- increased waiting time after lowering ATTN line - lengthten stop bit for cleaner frames (now recognized by PulseView) - count "NOTFORME" conditions - introduce definition COM_HALFBIT_LENGTH (I dont' trust value calculations in avrasm)
164 lines
5.0 KiB
NASM
164 lines
5.0 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2023 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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; receive packet into buffer pointed to by X.
|
|
;
|
|
; IN:
|
|
; - R16: COM address to listen to
|
|
; - R17: maximum value for accepted msg data (i.e. buffersize minus 3)
|
|
; - X : buffer to receive to
|
|
; OUT:
|
|
; - CFLAG: set if okay (packet received), cleared on error
|
|
; - R16: error code if CFLAG is cleared
|
|
; REGS: r16, r17, r18, X (r19, r20, r21, r22)
|
|
com2ReceivePacketRaw:
|
|
mov r18, r17
|
|
push r16
|
|
; read destination address
|
|
rcall com2ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
pop r17 ; pop from R16 to R17
|
|
brcc com2ReceivePacketRaw_ioError
|
|
; compare destination address (accept "FF" and own address)
|
|
cp r16, r17
|
|
breq com2ReceivePacketRaw_acceptAddr
|
|
cpi r16, 0xff
|
|
breq com2ReceivePacketRaw_acceptAddr
|
|
ldi r16, COM2_ERROR_NOTFORME
|
|
rjmp com2ReceivePacketRaw_error ; clc/ret
|
|
com2ReceivePacketRaw_acceptAddr:
|
|
st X+, r16 ; store dest address, lock buffer
|
|
; read msg length
|
|
rcall com2ReceiveByte ; read packet length (R16, R17, R20, R21, R22)
|
|
brcc com2ReceivePacketRaw_ioError
|
|
st X+, r16
|
|
cp r16, r18 ; (COM2_BUFFER_SIZE-3)
|
|
brcc com2ReceivePacketRaw_contentError ; packet too long
|
|
inc r16 ; account for checksum byte
|
|
mov r17, r16
|
|
com2ReceivePacketRaw_loop:
|
|
push r17
|
|
rcall com2ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
|
pop r17
|
|
brcc com2ReceivePacketRaw_ioError
|
|
st X+, r16
|
|
dec r17
|
|
brne com2ReceivePacketRaw_loop
|
|
rjmp com2PacketsSecRet
|
|
com2ReceivePacketRaw_ioError:
|
|
ldi r16, COM2_ERROR_IOERROR
|
|
rjmp com2PacketsClcRet
|
|
com2ReceivePacketRaw_contentError:
|
|
ldi r16, COM2_ERROR_DATAERROR
|
|
com2ReceivePacketRaw_error:
|
|
rjmp com2PacketsClcRet
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; send packet over wire, handle ATTN line.
|
|
;
|
|
; IN:
|
|
; - x : ptr to buffer to send
|
|
; OUT:
|
|
; - CFLAGS: set if okay, cleared otherwise (errorcode in R16)
|
|
; REGS: R16, R22 (R17, R21, X)
|
|
|
|
COM2_SendPacketWithAttn:
|
|
push r15
|
|
in r15, SREG
|
|
cli
|
|
; check for ATTN line: busy?
|
|
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable pullup on ATTN
|
|
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as input
|
|
nop ; needed to sample current input
|
|
sbis COM_PIN_ATTN, COM_PINNUM_ATTN ; ATTN low?
|
|
rjmp COM2_SendPacketWithAttn_lineBusyError ; jump if it is
|
|
|
|
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; set ATTN low
|
|
sbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as output
|
|
rcall com2WaitForOneBitLength ; wait for one bit duration (R22)
|
|
rcall com2WaitForOneBitLength ; wait for another bit duration (R22)
|
|
|
|
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
|
ld r16, X
|
|
sbiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
|
inc r16 ; account for dest addr
|
|
inc r16 ; account for msglen byte
|
|
inc r16 ; account for crc byte
|
|
rcall com2SendPacketRaw ; (r16, r17, r21, r22, X)
|
|
|
|
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; release ATTN line (by setting direction to IN)
|
|
brcc COM2_SendPacketWithAttn_ioError
|
|
; packet successfully sent
|
|
out SREG, r15
|
|
pop r15
|
|
rjmp com2PacketsSecRet
|
|
|
|
COM2_SendPacketWithAttn_ioError:
|
|
ldi r16,COM2_ERROR_COLLISION
|
|
rjmp COM2_SendPacketWithAttn_retNc
|
|
|
|
COM2_SendPacketWithAttn_lineBusyError:
|
|
ldi r16,COM2_ERROR_BUSY
|
|
COM2_SendPacketWithAttn_retNc:
|
|
pop r15
|
|
out SREG, r15
|
|
rjmp com2PacketsClcRet
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; wait for one bit length (minus cycles for call and ret).
|
|
;
|
|
; IN:
|
|
; - nothing
|
|
; OUT:
|
|
; - nothing
|
|
; REGS: r22
|
|
|
|
com2WaitForOneBitLength:
|
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 7, r22 ; wait for one bit duration (minus RCALL/RET)
|
|
ret
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; send packet over wire, expects ATTN to be low.
|
|
;
|
|
; IN:
|
|
; - r16: number of bytes to send
|
|
; - x : ptr to buffer to send
|
|
; OUT:
|
|
; - nothing
|
|
; REGS: r16, r17, x (r21, r22)
|
|
|
|
com2SendPacketRaw:
|
|
mov r17, r16
|
|
com2SendPacket_loop:
|
|
ld r16, X+
|
|
rcall com2SendByte ; send byte (R16, R21, R22)
|
|
brcc com2PacketsClcRet
|
|
dec r17
|
|
brne com2SendPacket_loop
|
|
sec
|
|
ret
|
|
|
|
|
|
com2PacketsClcRet:
|
|
clc
|
|
ret
|
|
|
|
com2PacketsSecRet:
|
|
sec
|
|
ret
|
|
|