158 lines
5.4 KiB
NASM
158 lines
5.4 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2024 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_ReceivePacketIntoBuffer
|
|
;
|
|
; Receive a packet into buffer pointed to by X.
|
|
; Expects interrupts to be disabled.
|
|
;
|
|
; @param R16 COM address to listen to
|
|
; @param R17 maximum value for accepted msg data (i.e. buffersize minus 3)
|
|
; @param X buffer to receive to
|
|
; @return CFLAG set if okay (packet received), cleared on error
|
|
; @return R16 error code if CFLAG is cleared (COM2_ERROR_NOTFORME, COM2_ERROR_IOERROR, COM2_ERROR_DATAERROR)
|
|
; @clobbers: r16, r17, r18, X (r19, r20, r21, r22)
|
|
|
|
uartBitbang_ReceivePacketIntoBuffer:
|
|
mov r18, r17
|
|
push r16
|
|
; read destination address
|
|
rcall uartBitbang_ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
pop r17 ; pop from R16 to R17
|
|
brcc uartBitbang_ReceivePacketIntoBuffer_ioError
|
|
#ifndef COM_ACCEPT_ALL_DEST ; accept every destination address
|
|
; compare destination address (accept "FF" and own address)
|
|
cp r16, r17
|
|
breq uartBitbang_ReceivePacketIntoBuffer_acceptAddr
|
|
cpi r16, 0xff
|
|
breq uartBitbang_ReceivePacketIntoBuffer_acceptAddr
|
|
ldi r16, COM2_ERROR_NOTFORME
|
|
rjmp uartBitbang_ReceivePacketIntoBuffer_error ; clc/ret
|
|
#endif
|
|
uartBitbang_ReceivePacketIntoBuffer_acceptAddr:
|
|
st X+, r16 ; store dest address, lock buffer
|
|
; read msg length
|
|
rcall uartBitbang_ReceiveByte ; read packet length (R16, R17, R20, R21, R22)
|
|
brcc uartBitbang_ReceivePacketIntoBuffer_ioError
|
|
st X+, r16
|
|
cp r16, r18 ; (COM2_BUFFER_SIZE-3)
|
|
brcc uartBitbang_ReceivePacketIntoBuffer_contentError ; packet too long
|
|
inc r16 ; account for checksum byte
|
|
mov r17, r16
|
|
uartBitbang_ReceivePacketIntoBuffer_loop:
|
|
push r17
|
|
rcall uartBitbang_ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
pop r17
|
|
brcc uartBitbang_ReceivePacketIntoBuffer_ioError
|
|
st X+, r16
|
|
dec r17
|
|
brne uartBitbang_ReceivePacketIntoBuffer_loop
|
|
sec
|
|
ret
|
|
uartBitbang_ReceivePacketIntoBuffer_ioError:
|
|
ldi r16, COM2_ERROR_IOERROR
|
|
rjmp uartBitbang_ReceivePacketIntoBuffer_error
|
|
uartBitbang_ReceivePacketIntoBuffer_contentError:
|
|
ldi r16, COM2_ERROR_DATAERROR
|
|
uartBitbang_ReceivePacketIntoBuffer_error:
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_SendPacket
|
|
;
|
|
; Send packet over wire, handle ATTN line.
|
|
;
|
|
; @param X ptr to buffer to send
|
|
; @return CFLAGS set if okay, cleared otherwise (errorcode in R16)
|
|
; @clobbers R16, R22 (R17, R21, X)
|
|
|
|
uartBitbang_SendPacket:
|
|
rcall uartBitbang_AcquireBus
|
|
brcc uartBitbang_SendPacket_lineBusyError
|
|
|
|
rcall uartBitbang_WaitForOneBitLength ; wait for one bit duration (R22)
|
|
rcall uartBitbang_WaitForOneBitLength ; wait for one bit duration (R22)
|
|
|
|
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
|
ld r17, X
|
|
sbiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
|
inc r17 ; account for dest addr
|
|
inc r17 ; account for msglen byte
|
|
inc r17 ; account for crc byte
|
|
|
|
uartBitbang_SendPacket_loop:
|
|
ld r16, X+
|
|
rcall uartBitbang_SendByte ; send byte (R16, R21, R22)
|
|
brcc uartBitbang_SendPacket_releaseBusRet
|
|
dec r17
|
|
brne uartBitbang_SendPacket_loop
|
|
sec
|
|
uartBitbang_SendPacket_releaseBusRet:
|
|
cbi COM_ATTN_DDR, COM_ATTN_PIN ; release ATTN line (by setting direction to IN)
|
|
brcc uartBitbang_SendPacket_ioError
|
|
; packet successfully sent
|
|
ret
|
|
uartBitbang_SendPacket_ioError:
|
|
ldi r16,COM2_ERROR_COLLISION
|
|
ret
|
|
uartBitbang_SendPacket_lineBusyError:
|
|
ldi r16,COM2_ERROR_BUSY
|
|
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_OUTPUT, COM_ATTN_PIN ; disable pullup on ATTN
|
|
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN as input
|
|
nop ; needed to sample current input
|
|
sbis COM_ATTN_INPUT, COM_ATTN_PIN ; ATTN low?
|
|
rjmp uartBitbang_AcquireBus_busy ; jump if it is
|
|
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; set ATTN low
|
|
sbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN as output
|
|
sec
|
|
ret
|
|
uartBitbang_AcquireBus_busy:
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartBitbang_WaitForOneBitLength
|
|
;
|
|
; wait for one bit length (minus cycles for call and ret).
|
|
;
|
|
; @clobbers r22
|
|
|
|
uartBitbang_WaitForOneBitLength:
|
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 7, r22 ; wait for one bit duration (minus RCALL/RET)
|
|
ret
|
|
; @end
|
|
|
|
|