242 lines
7.2 KiB
NASM
242 lines
7.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. *
|
|
; ***************************************************************************
|
|
|
|
|
|
.cseg
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine UART_HW_Interface_RunRead
|
|
;
|
|
; This routine reads bytes from the ringbuffer of the given
|
|
; interface and parses them into messages.
|
|
; If a valid message is received it will be added to the system's
|
|
; incoming message ringbuffer.
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers R16, R20 (R17, R18, R18, R19, R20, R21, X)
|
|
|
|
UART_HW_Interface_RunRead:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
|
cpi r16, 0xff
|
|
brne UART_HW_Interface_RunRead_HaveBuffer
|
|
rcall uartHwAllocateReadBuffer ; (r16, R17, X)
|
|
brcc UART_HW_Interface_RunRead_ovrError
|
|
rcall uartHwReadSetBuffer ; (r16)
|
|
UART_HW_Interface_RunRead_HaveBuffer:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_LEFT
|
|
tst r16
|
|
brne UART_HW_Interface_RunRead_HaveHeader
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_USED
|
|
ldi r20, 2
|
|
sub r20, r16
|
|
rcall uartHwReadUptoNumBytes ; (r16, r17, r20, r21, X)
|
|
tst r20
|
|
brne UART_HW_Interface_RunRead_end
|
|
ldd xl, Y+UART_HW_IFACE_OFFS_READMSG_PTR
|
|
ldd xh, Y+UART_HW_IFACE_OFFS_READMSG_PTR+1
|
|
sbiw xh:xl, 1
|
|
ld r16, X ; msg len
|
|
cpi r16, UART_HW_FIXEDBUFFERS_SIZE-4 ; minus buffer status byte, dest addr, msglen, crc
|
|
brcc UART_HW_Interface_RunRead_dataError ; invalid msg
|
|
inc r16
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_LEFT, r16
|
|
UART_HW_Interface_RunRead_HaveHeader:
|
|
ldd r20, Y+UART_HW_IFACE_OFFS_READMSG_LEFT
|
|
tst r20
|
|
breq UART_HW_Interface_RunRead_HaveMsg
|
|
rcall uartHwReadUptoNumBytes ; (r16, r17, r20, r21, X)
|
|
tst r20
|
|
brne UART_HW_Interface_RunRead_end ; not all bytes received, done for now
|
|
UART_HW_Interface_RunRead_HaveMsg:
|
|
ldd xl, Y+UART_HW_IFACE_OFFS_READMSG_PTR
|
|
ldd xh, Y+UART_HW_IFACE_OFFS_READMSG_PTR+1
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_USED
|
|
sub xl, r16 ; X-=r16
|
|
sbc xh, r16
|
|
add xh, r16
|
|
rcall com2CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
|
brcc UART_HW_Interface_RunRead_dataError
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
|
rcall UART_HW_AddIncomingMsgNum ; (R17, R18, X)
|
|
brcc UART_HW_Interface_RunRead_ovrError
|
|
ldi r16, 0xff
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM, r16
|
|
rjmp UART_HW_Interface_RunRead_end
|
|
UART_HW_Interface_RunRead_ovrError:
|
|
rcall uartHwIncOvrCounter ; (R16)
|
|
rcall uartHwReadResetBuffer ; (R16, X)
|
|
rjmp UART_HW_Interface_RunRead_end
|
|
UART_HW_Interface_RunRead_dataError:
|
|
rcall uartHwIncContentCounter ; (R16)
|
|
rcall uartHwResetBufferStartSkipping ; (R16, X)
|
|
UART_HW_Interface_RunRead_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwReadSetBuffer
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @param X pointer to start of buffer
|
|
; @param r16 buffer number
|
|
; @clobbers r16
|
|
|
|
uartHwReadSetBuffer:
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM, r16 ; set buffer data
|
|
adiw xh:xl, 1
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_PTR, xl
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_PTR+1, xh
|
|
sbiw xh:xl, 1
|
|
clr r16
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_USED, r16
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_LEFT, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwReadResetBuffer
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers r16, X
|
|
|
|
uartHwReadResetBuffer:
|
|
; reset READ buffer settings
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
|
cpi r16, 0xff
|
|
brne uartHwReadResetBuffer_haveBuffer
|
|
ret
|
|
uartHwReadResetBuffer_haveBuffer:
|
|
rcall UART_HW_FixedBuffers_Locate ; (X)
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
|
rjmp uartHwReadSetBuffer ; (r16)
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwResetBufferStartSkipping
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers r16 (X)
|
|
|
|
uartHwResetBufferStartSkipping:
|
|
; reset READ buffer settings, enter skip mode
|
|
rcall uartHwReadResetBuffer ; (R16, X)
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_MODE
|
|
ori r16, UART_HW_MODE_SKIPPING
|
|
std Y+UART_HW_IFACE_OFFS_MODE, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwAllocateReadBuffer
|
|
;
|
|
; @return CFLAG set if buffer set, cleared otherwise
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers r16, R17 (X)
|
|
|
|
uartHwAllocateReadBuffer:
|
|
rcall UART_HW_FixedBuffers_Alloc ; (R16, R17, X)
|
|
brcc uartHwAllocateReadBuffer_end
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM, r16
|
|
ldd r17, Y+UART_HW_IFACE_OFFS_IFACENUM
|
|
ori r17, (1<<UART_HW_BUFFER_INUSE_BIT)
|
|
st X, r17
|
|
adiw xh:xl, 1
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_PTR, xl
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_PTR+1, xh
|
|
clr r16
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_USED, r16
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_LEFT, r16
|
|
sec
|
|
uartHwAllocateReadBuffer_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwReadUptoNumBytes
|
|
;
|
|
; @return r20 remaining bytes (bytes not yet read)
|
|
; @param Y pointer to start of interface data
|
|
; @param R20 number of bytes to read
|
|
; @clobbers r16, r20, r21, X (R17)
|
|
|
|
uartHwReadUptoNumBytes:
|
|
clr r21
|
|
ldd xl, Y+UART_HW_IFACE_OFFS_READMSG_PTR
|
|
ldd xh, Y+UART_HW_IFACE_OFFS_READMSG_PTR+1
|
|
uartHwReadUptoNumBytes_loop:
|
|
push xl
|
|
push xh
|
|
rcall UART_HW_InterfaceReadFromWriteBuffer ; (R17, R18, X)
|
|
pop xh
|
|
pop xl
|
|
brcc uartHwReadUptoNumBytes_done
|
|
st X+, r16
|
|
inc r21
|
|
dec r20
|
|
brne uartHwReadUptoNumBytes_loop
|
|
uartHwReadUptoNumBytes_done:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_USED
|
|
add r16, r21
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_USED, r16
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_LEFT
|
|
sub r16, r21
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_LEFT, r16 ; might become negative when reading header
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_PTR, xl
|
|
std Y+UART_HW_IFACE_OFFS_READMSG_PTR+1, xh
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwIncOvrCounter
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers r16
|
|
|
|
uartHwIncOvrCounter:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_ERR_OVR
|
|
inc r16
|
|
breq uartHwIncOvrCounter_end
|
|
std Y+UART_HW_IFACE_OFFS_ERR_OVR, r16
|
|
uartHwIncOvrCounter_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine uartHwIncContentCounter
|
|
;
|
|
; @param Y pointer to start of interface data
|
|
; @clobbers r16
|
|
|
|
uartHwIncContentCounter:
|
|
ldd r16, Y+UART_HW_IFACE_OFFS_ERR_CONTENT
|
|
inc r16
|
|
breq uartHwIncContentCounter_end
|
|
std Y+UART_HW_IFACE_OFFS_ERR_OVR, r16
|
|
uartHwIncContentCounter_end:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|