Files
aqhomecontrol/avr/com_recv.asm
2023-04-08 18:18:19 +02:00

162 lines
4.8 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. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
COM_RECV_BEGIN:
; ---------------------------------------------------------------------------
; comReceivePacketHandleBuffer
;
; Allocate a buffer and receive a packet into it.
; On success the buffer flags will have COM_BUFFER_FLAGS_RECEIVED set.
; On error the buffer will be deallocated.
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, cleared otherwise
; MODIFIED REGISTERS: R16, R17, X, Y (R1, R18, R19, R20, R21, R22)
comReceivePacketHandleBuffer:
rcall COM_BufferAlloc
brcs comReceivePacketHandleBuffer_haveBuffer
ldi xl, LOW(comStatsRecvNoBuffer)
ldi xh, HIGH(comStatsRecvNoBuffer)
rjmp comReceivePacketHandleBuffer_errorWithCounter
comReceivePacketHandleBuffer_haveBuffer:
; get pos of data portion for the allocated buffer
mov xl, yl
mov xh, yh
adiw xh:xl, COM_BUFFER_OFFS_DATA
rcall comReceivePacketToXandCheck ; (r16, r17, r18, r20, r21, r22, X)
brcs comReceivePacketHandleBuffer_haveMessage
push r16
rcall COM_BufferDeallocBack ; (r16, r17, r21)
pop r16
cpi r16, COM_ERR_NOTFORME ; packet just not for me?
breq comReceivePacketHandleBuffer_notforme ; correct, don't count as error
ldi xl, LOW(comStatsRecvCrcErrs)
ldi xh, HIGH(comStatsRecvCrcErrs)
cpi r16, COM_ERR_CHECKSUM
breq comReceivePacketHandleBuffer_errorWithCounter
ldi xl, LOW(comStatsRecvErrs) ; generic error
ldi xh, HIGH(comStatsRecvErrs)
rjmp comReceivePacketHandleBuffer_errorWithCounter
comReceivePacketHandleBuffer_haveMessage:
; handle buffer flags
ldi r16, COM_BUFFER_FLAGS_RECEIVED
std y+COM_BUFFER_OFFS_FLAGS, r16
ldi xl, LOW(comStatsPacketsIn)
ldi xh, HIGH(comStatsPacketsIn)
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
sec
ret
comReceivePacketHandleBuffer_errorWithCounter:
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
comReceivePacketHandleBuffer_notforme:
clc
ret
; ---------------------------------------------------------------------------
; comReceivePacketToXandCheck
;
; Receive a packet to the given SRAM position.
; IN:
; - X: pointer to start of buffer to receive bytes
; OUT:
; - CFLAG: set if okay, clear otherwise
; - R16: error code if CFLAG cleared
; MODIFIED REGISTERS: r16, r17, r18, X (r19, r20, r21, r22)
comReceivePacketToXandCheck:
push xh
push xl
rcall comReceivePacketToSram ; (r16, r17, R20, R21, R22, X)
pop xl
pop xh
brcc comReceivePacketToXandCheck_error
rcall cproCheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
ldi r16, COM_ERR_CHECKSUM
brcc comReceivePacketToXandCheck_error
sec
ret
comReceivePacketToXandCheck_error:
clc
ret
; ---------------------------------------------------------------------------
; comReceivePacketToSram
;
; Receive a packet to the given SRAM position.
; IN:
; - X: pointer to start of buffer to receive bytes
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGISTERS: r16, r17, X (R20, R21, R22)
comReceivePacketToSram:
; read destination address
rcall comReceiveByte ; read byte (R16, R17, R20, R21, R22)
brcc comReceivePacketToSram_error
; compare destination address (accept "00", "FF" and own address)
tst r16
breq comReceivePacketToSram_acceptAddr
cpi r16, 0xff
breq comReceivePacketToSram_acceptAddr
lds r17, comAddress
cp r16, r17
breq comReceivePacketToSram_acceptAddr
ldi r16, COM_ERR_NOTFORME
clc ; not for me
ret
comReceivePacketToSram_acceptAddr:
st X+, r16 ; store dest address
; read msg length
rcall comReceiveByte ; read packet length (R16, R17, R20, R21, R22)
brcc comReceivePacketToSram_error
st X+, r16
cpi r16, (COM_BUFFER_SIZE-3-COM_BUFFER_OFFS_DATA)+1
brcc comReceivePacketToSram_error ; packet too long (TODO: count overruns)
inc r16 ; account for checksum byte
mov r17, r16
comReceivePacketToSram_loop:
push r17
rcall comReceiveByte ; read byte (R16, R17, R20, R21, R22)
pop r17
brcc comReceivePacketToSram_error
st X+, r16
dec r17
brne comReceivePacketToSram_loop
sec
ret
comReceivePacketToSram_error:
ldi r16, COM_ERR_IO
clc
ret
COM_RECV_END:
.equ MODULE_SIZE_COM_RECV = COM_RECV_END-COM_RECV_BEGIN