Files
aqhomecontrol/avr/modules/com2w/com2wn_send.asm
2025-08-19 23:03:15 +02:00

155 lines
4.2 KiB
NASM

; ***************************************************************************
; 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