; *************************************************************************** ; copyright : (C) 2025 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** ; * This file is part of the project "AqHome". * ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** #ifndef AVR_MODULES_COM2W_COM2WN_SEND_H #define AVR_MODULES_COM2W_COM2WN_SEND_H ; WORK IN PROGRESS .cseg ; --------------------------------------------------------------------------- ; @routine com2wnSendMsg ; ; @param X pointer to bytes to send ; @param Y pointer to interface data in SRAM ; @return CFLAG set if message sent, cleared otherwise ; @clobbers R16, R18 (R20, R22, R24, R25, X) com2wnSendMsg: ldi r20, 6 ; wait for about 60us for clock low rcall com2wWaitForClockLowMulti10Us ; (R16, R20, R22) brcs com2wnSendMsg_busy ; CLK got low while waiting, so line is busy push r15 in r15, SREG cli ; atomic disable irq and set CLK low rcall com2wnDisableClkIrq ; (none) rcall com2wnClkSetLow ; reserve bus (none) out SREG, r15 pop r15 adiw xh:xl, NETMSG_OFFS_MSGLEN ld r18, X sbiw xh:xl, NETMSG_OFFS_MSGLEN inc r18 ; adjust for DESTADDR inc r18 ; adjust for MSGLEN inc r18 ; adjust for CRCBYTE rcall com2wnWaitTime1 ; longer wait period (R22) rcall com2wnSendBytes ; (r16, r17, r18, r22, X) rcall com2wClkSetHigh ; make sure bus is released rcall com2wnDataSetHigh rcall com2wnEnableClkIrq ; (none) ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW rcall NET_Interface_IncCounter16 ; (R24, R25) sec ret com2wnSendMsg_busy: ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW rcall NET_Interface_IncCounter16 ; (R24, R25) clc ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wnSendBytes ; ; @param R18 number of bytes to send ; @param X pointer to bytes to send ; @param Y pointer to interface data in SRAM ; @clobbers: r16, r18, X (r17, r22) com2wnSendBytes: com2wnSendBytes_loop: rcall com2wnClkSetLow ; (none) rcall com2wnWaitTime1 ; longer wait period (R22) ld r16, X+ rcall com2wnSendByte ; (R16, R17, R22) dec r18 brne com2wnSendBytes_loop ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wnSendByte ; ; @param R16 byte to send ; @param Y pointer to interface data in SRAM ; @clobbers r16, r17 (r22) com2wnSendByte: ldi r17, 8 com2wnSendByte_loop: rcall com2wnClkSetLow rcall com2wnWaitTime1 ; longer wait period (R22) lsr r16 brcs com2wnSendByte_send1 rcall com2wnDataSetLow rjmp com2wnSendByte_sent com2wnSendByte_send1: rcall com2wnDataSetHigh com2wnSendByte_sent: rcall com2wnWaitTime2 ; shorter wait period (R22) push r15 in r15, SREG cli ; ensure time period by disabling irqs rcall com2wClkSetHigh rcall com2wnWaitTime1 ; longer wait period (R22) out SREG, r15 pop r15 dec r17 brne com2wnSendByte_loop ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wnWaitTime1 ; ; waits for longer period (e.g. 30ns) ; ; @clobbers R22 com2wnWaitTime1: Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET) ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wnWaitTime2 ; ; waits for shorter period (e.g. 10ns) ; ; @clobbers R22 com2wnWaitTime2: Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET) ret ; @end #endif ; AVR_MODULES_COM2W_COM2WN_SEND_H