241 lines
7.4 KiB
NASM
241 lines
7.4 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_ReceiveAndCheckMsg
|
|
;
|
|
; Receive a packet into buffer pointed to by X.
|
|
; Expects interrupts to be disabled.
|
|
;
|
|
; @param R18 COM address to listen to
|
|
; @param R19 max buffer size
|
|
; @param X buffer to receive to
|
|
; @return CFLAG set if msg received, cleared on error
|
|
; @clobbers R16, R19 (R17, R20, R21, R22, R24, R25)
|
|
|
|
uartBitbang_ReceiveAndCheckMsg:
|
|
push xl
|
|
push xh
|
|
rcall uartBitbang_RawReceiveMsg ; (R16, R17, R19, R20, R21, R22, R24, R25, X)
|
|
pop xh
|
|
pop xl
|
|
brcs uartBitbang_ReceiveAndCheckMsg_recvd
|
|
; fall-through, return with CF cleared (from uartBitbang_RawReceiveMsg)
|
|
ret
|
|
uartBitbang_ReceiveAndCheckMsg_recvd:
|
|
push xl
|
|
push xh
|
|
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
|
pop xh
|
|
pop xl
|
|
brcs uartBitbang_ReceiveAndCheckMsg_msgOk
|
|
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
clc
|
|
ret
|
|
uartBitbang_ReceiveAndCheckMsg_msgOk:
|
|
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_RawReceiveMsg
|
|
;
|
|
; Receive a packet into buffer pointed to by X.
|
|
; Expects interrupts to be disabled.
|
|
;
|
|
; @param R18 COM address to listen to
|
|
; @param R19 max buffer size
|
|
; @param X buffer to receive to
|
|
; @return CFLAG set if msg received, cleared on error (see R16)
|
|
; @return R16 if CFLAG cleared: 0=message not for this node, otherwise error
|
|
; @clobbers R16, R19 (R17, R20, R21, R22, R24, R25, X)
|
|
|
|
uartBitbang_RawReceiveMsg:
|
|
cpi r19, 3
|
|
brcs uartBitbang_RawReceiveMsg_eBadSize
|
|
; read destination address
|
|
rcall uartBitbang_ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
brcc uartBitbang_RawReceiveMsg_eIo
|
|
cp r16, r18
|
|
breq uartBitbang_RawReceiveMsg_forMe
|
|
cpi r16, 0xff
|
|
breq uartBitbang_RawReceiveMsg_forMe
|
|
clr r16 ; not for me
|
|
rjmp uartBitbang_RawReceiveMsg_clcRet
|
|
uartBitbang_RawReceiveMsg_forMe:
|
|
subi r19, 1
|
|
brcs uartBitbang_RawReceiveMsg_eBadSize
|
|
st X+, r16
|
|
; read size of msg payload (e.g. number of msg bytes following minus CRC byte)
|
|
rcall uartBitbang_ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
brcc uartBitbang_RawReceiveMsg_eIo
|
|
subi r19, 1
|
|
brcs uartBitbang_RawReceiveMsg_eBadSize
|
|
st X+, r16 ; store msg payload size
|
|
inc r16 ; account for crc byte
|
|
sub r19, r16 ; check msg size against remaining buffer size
|
|
brcs uartBitbang_RawReceiveMsg_eBadSize
|
|
mov r19, r16
|
|
uartBitbang_RawReceiveMsg_loop:
|
|
rcall uartBitbang_ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
brcc uartBitbang_RawReceiveMsg_eIo
|
|
st X+, r16 ; store msg
|
|
dec r19
|
|
brne uartBitbang_RawReceiveMsg_loop
|
|
sec
|
|
rjmp uartBitbang_RawReceiveMsg_end
|
|
uartBitbang_RawReceiveMsg_eBadSize:
|
|
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
|
|
rjmp uartBitbang_RawReceiveMsg_incCounterRet
|
|
uartBitbang_RawReceiveMsg_eIo:
|
|
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
|
|
uartBitbang_RawReceiveMsg_incCounterRet:
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
uartBitbang_RawReceiveMsg_clcRet:
|
|
clc
|
|
uartBitbang_RawReceiveMsg_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_SendMsg
|
|
;
|
|
; Send packet over wire, handle ATTN line.
|
|
;
|
|
; @param X ptr to buffer to send
|
|
; @return CFLAGS set if okay, cleared otherwise (index of error variable in R16)
|
|
; @return R16 index of error variable (if CFLAGS cleared)
|
|
; @clobbers R16 (R17, R21, R22, R24, R25, X)
|
|
|
|
uartBitbang_SendMsg:
|
|
rcall uartBitbang_AcquireBus
|
|
brcc uartBitbang_SendMsg_lineBusyError
|
|
|
|
rcall uartBitbang_WaitForOneBitLength ; wait for one bit duration (R22)
|
|
rcall uartBitbang_WaitForOneBitLength ; wait for one bit duration (R22)
|
|
|
|
rcall uartBitbang_RawSendMsg ; (R16, R17, R21, R22, R24, R25, X)
|
|
cbi COM_ATTN_DDR, COM_ATTN_PIN ; release ATTN line (by setting direction to IN)
|
|
ret
|
|
uartBitbang_SendMsg_lineBusyError:
|
|
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_RawSendMsg
|
|
;
|
|
; Send packet over wire.
|
|
;
|
|
; @param X ptr to buffer to send
|
|
; @return CFLAGS set if okay, cleared otherwise (index of error variable in R16)
|
|
; @return R16 index of error variable (if CFLAGS cleared)
|
|
; @clobbers R16, R17 (R21, R22, R24, R25, X)
|
|
|
|
uartBitbang_RawSendMsg:
|
|
adiw xh:xl, NETMSG_OFFS_MSGLEN
|
|
ld r17, X
|
|
sbiw xh:xl, NETMSG_OFFS_MSGLEN
|
|
inc r17 ; account for dest addr
|
|
inc r17 ; account for msglen byte
|
|
inc r17 ; account for crc byte
|
|
|
|
uartBitbang_RawSendMsg_loop:
|
|
rcall uartBitbang_WaitForOneBitLength ; wait for one bit duration (R22)
|
|
|
|
ld r16, X+
|
|
rcall uartBitbang_SendByte ; send byte (R16, R21, R22)
|
|
brcc uartBitbang_RawSendMsg_ioError
|
|
dec r17
|
|
brne uartBitbang_RawSendMsg_loop
|
|
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
sec
|
|
ret
|
|
uartBitbang_RawSendMsg_ioError:
|
|
ldi r16, NET_IFACE_OFFS_ERR_COLLISIONS_LOW
|
|
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_WaitForAttnHigh
|
|
;
|
|
; Wait up to 1ms for data pin to become high
|
|
; @return CFLAG set if okay, clear otherwise
|
|
; @clobbers R17, R22
|
|
|
|
uartBitbang_WaitForAttnHigh:
|
|
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
|
|
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
|
|
UART_BB_M_WAIT_FOR_PIN_HIGH COM_ATTN_INPUT, COM_ATTN_PIN
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_AcquireBus
|
|
;
|
|
; Reserve bus if free (otherwise return error)
|
|
; Expects interrupts to be disabled.
|
|
;
|
|
; @return CFLAG set if okay (bus acquired), cleared on error
|
|
; @clobbers: none
|
|
|
|
uartBitbang_AcquireBus:
|
|
; check for ATTN line: busy?
|
|
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN as input
|
|
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable pullup on ATTN
|
|
nop ; needed to sample current input
|
|
sbis COM_ATTN_INPUT, COM_ATTN_PIN ; ATTN low?
|
|
rjmp uartBitbang_AcquireBus_busy ; jump if it is
|
|
sbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN as output
|
|
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; set ATTN low
|
|
sec
|
|
ret
|
|
uartBitbang_AcquireBus_busy:
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|