; *************************************************************************** ; 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 com2wSendMsg ; ; @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) com2wSendMsg: ldi r20, 6 ; wait for about 60us for clock low rcall com2wWaitForClockLowMulti10Us ; (R17, R20, R22) brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy push r15 in r15, SREG cli ; atomic disable irq and set CLK low rcall com2wDisableClkIrq ; (none) rcall com2wClkSetLow ; 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 com2wWaitTime1 ; longer wait period (R22) rcall com2wSendBytes ; (r16, r17, r18, r22, X) rcall com2wClkSetHigh ; make sure bus is released rcall com2wDataSetHigh rcall com2wEnableClkIrq ; (none) ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW rcall NET_Interface_IncCounter16 ; (R24, R25) sec ret com2wSendMsg_busy: ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW rcall NET_Interface_IncCounter16 ; (R24, R25) clc ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wSendBytes ; ; @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) com2wSendBytes: com2wSendBytes_loop: rcall com2wClkSetLow ; (none) rcall com2wWaitTime1 ; longer wait period (R22) ld r16, X+ rcall com2wSendByte ; (R16, R17, R22) dec r18 brne com2wSendBytes_loop ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wSendByte ; ; @param R16 byte to send ; @param Y pointer to interface data in SRAM ; @clobbers r16, r17 (r22) com2wSendByte: ldi r17, 8 com2wSendByte_loop: rcall com2wClkSetLow rcall com2wWaitTime1 ; longer wait period (R22) lsr r16 brcs com2wSendByte_send1 rcall com2wDataSetLow rjmp com2wSendByte_sent com2wSendByte_send1: rcall com2wDataSetHigh com2wSendByte_sent: rcall com2wWaitTime2 ; shorter wait period (R22) push r15 in r15, SREG cli ; ensure time period by disabling irqs rcall com2wClkSetHigh rcall com2wWaitTime1 ; longer wait period (R22) out SREG, r15 pop r15 dec r17 brne com2wSendByte_loop ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wWaitTime1 ; ; waits for longer period (e.g. 30ns) ; ; @clobbers R22 com2wWaitTime1: Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET) ret ; @end ; --------------------------------------------------------------------------- ; @routine com2wWaitTime2 ; ; waits for shorter period (e.g. 10ns) ; ; @clobbers R22 com2wWaitTime2: Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET) ret ; @end #endif ; AVR_MODULES_COM2W_COM2WN_SEND_H