avr: more work on uart_hw module.
This commit is contained in:
@@ -10,75 +10,79 @@
|
||||
|
||||
.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
|
||||
; @param X pointer to start of buffer
|
||||
; @param r16 buffer number
|
||||
; @clobbers R16, R17, R18, R19, R20, R21, X
|
||||
|
||||
UART_HW_Interface_RunRead:
|
||||
rcall uartHwReadEnsureBuffer ; (r16, R17, X)
|
||||
brcc UART_HW_Interface_RunRead_end
|
||||
rcall uartHwReadEnsureHeader ; (r16, r17, r20, r21, X)
|
||||
brcc UART_HW_Interface_RunRead_end
|
||||
rcall uartHwReadEnsureBody ; (r16, r17, r20, r21, x)
|
||||
brcc UART_HW_Interface_RunRead_end
|
||||
UART_HW_Interface_RunRead_HaveMsg:
|
||||
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
|
||||
cpi r16, 3
|
||||
brcs UART_HW_Interface_RunRead_badMsg
|
||||
; check and store msg
|
||||
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)
|
||||
brcs UART_HW_Interface_RunRead_clearBuf
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
||||
rcall UART_HW_FixedBuffers_ReleaseByNum ; (R16, X)
|
||||
UART_HW_Interface_RunRead_clearBuf:
|
||||
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_badMsg:
|
||||
; reset READ buffer settings, enter skip mode
|
||||
rcall uartHwResetBufferStartSkipping ; (r16, X)
|
||||
UART_HW_Interface_RunRead_ovrError:
|
||||
rcall uartHwIncOvrCounter
|
||||
rcall uartHwReadResetBuffer
|
||||
rjmp UART_HW_Interface_RunRead_end
|
||||
UART_HW_Interface_RunRead_dataError:
|
||||
rcall uartHwIncContentCounter
|
||||
rcall uartHwResetBufferStartSkipping
|
||||
UART_HW_Interface_RunRead_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartHwEnsureReadBuffer
|
||||
;
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers r16 (R17, X)
|
||||
|
||||
uartHwReadEnsureBuffer:
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
||||
cpi r16, 0xff
|
||||
breq uartHwReadEnsureBuffer_alloc
|
||||
uartHwReadEnsureBuffer_SecRet:
|
||||
sec
|
||||
ret
|
||||
uartHwReadEnsureBuffer_alloc:
|
||||
rcall uartHwAllocateReadBuffer ; (r16, R17, X)
|
||||
brcc uartHwReadEnsureBuffer_error
|
||||
rcall uartHwReadSetBuffer ; (r16)
|
||||
rjmp uartHwReadEnsureBuffer_SecRet
|
||||
uartHwReadEnsureBuffer_error:
|
||||
; no buffer, set error status, skip msg
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
||||
rcall UART_HW_FixedBuffers_Locate ; (r16)
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
|
||||
rcall uartHwReadResetBuffer ; (r16)
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_MODE
|
||||
ori r16, UART_HW_MODE_SKIPPING
|
||||
std Y+UART_HW_IFACE_OFFS_MODE, r16
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_ERR_OVR
|
||||
inc r16
|
||||
breq UART_HW_Interface_RunRead_end
|
||||
std Y+UART_HW_IFACE_OFFS_ERR_OVR, r16
|
||||
clc
|
||||
uartHwReadEnsureBuffer_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartHwReadSetBuffer
|
||||
;
|
||||
@@ -108,8 +112,12 @@ uartHwReadSetBuffer:
|
||||
; @clobbers r16, X
|
||||
|
||||
uartHwReadResetBuffer:
|
||||
; reset READ buffer settings, enter skip mode
|
||||
; 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)
|
||||
@@ -134,64 +142,20 @@ uartHwResetBufferStartSkipping:
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartHwReadEnsureHeader
|
||||
;
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers r16 (r17, r20, r21, X)
|
||||
|
||||
uartHwReadEnsureHeader:
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_LEFT
|
||||
tst r16
|
||||
breq uartHwReadEnsureHeader_readHeader
|
||||
sec
|
||||
ret
|
||||
uartHwReadEnsureHeader_readHeader:
|
||||
; read and validate header (2 bytes)
|
||||
rcall uartHwReadAndValidateHeader ; (r16, r17, r20, r21, X)
|
||||
brcc UART_HW_Interface_RunRead_badMsg
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_USED
|
||||
cpi r16, 2 ; full header in buffer (2 bytes)?
|
||||
brcs UART_HW_Interface_RunRead_end ; nope, done for this round
|
||||
uartHwReadEnsureHeader_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartHwReadEnsureBody
|
||||
;
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers r20 (r16, r17, r21, x)
|
||||
|
||||
uartHwReadEnsureBody:
|
||||
ldd r20, Y+UART_HW_IFACE_OFFS_READMSG_LEFT
|
||||
tst r20
|
||||
sec
|
||||
breq uartHwReadEnsureBody_end ; no bytes left, message done
|
||||
rcall uartHwReadUptoNumBytes ; (r16, r17, r20, r21, X)
|
||||
ldd r20, Y+UART_HW_IFACE_OFFS_READMSG_LEFT
|
||||
tst r20
|
||||
sec
|
||||
breq uartHwReadEnsureBody_end ; no bytes left, message done
|
||||
clc
|
||||
uartHwReadEnsureBody_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartHwAllocateReadBuffer
|
||||
;
|
||||
; @return CFLAG set if buffer set, cleared otherwise
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers r16 (R17, X)
|
||||
; @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
|
||||
@@ -205,47 +169,10 @@ uartHwAllocateReadBuffer_end:
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uartHwReadAndValidateHeader
|
||||
;
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers r16, r20, X (r17, r21)
|
||||
|
||||
uartHwReadAndValidateHeader:
|
||||
; read until we have 2 bytes
|
||||
ldi r20, 2
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_USED
|
||||
sub r20, r16
|
||||
rcall uartHwReadUptoNumBytes ; (r16, r17, r20, r21, X)
|
||||
; check whether we have 2 bytes
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_USED
|
||||
cpi r16, 2
|
||||
brcs uartHwReadAndValidateHeader_ok ; < 2 bytes in buffer, nothing to do
|
||||
; read and check msg len
|
||||
ldd xl, Y+UART_HW_IFACE_OFFS_READMSG_PTR
|
||||
ldd xh, Y+UART_HW_IFACE_OFFS_READMSG_PTR+1
|
||||
sbiw xh:xl, 1 ; go back one byte, pointing to MSG_LEN
|
||||
ld r16, X
|
||||
cpi r16, UART_HW_FIXEDBUFFERS_SIZE-4 ; minus buffer status byte, dest addr, msglen, crc
|
||||
brcc uartHwReadAndValidateHeader_error ; bad msg length
|
||||
; set number of bytes left to read
|
||||
inc r16 ; account for crc byte
|
||||
std Y+UART_HW_IFACE_OFFS_READMSG_LEFT, r16
|
||||
uartHwReadAndValidateHeader_ok:
|
||||
sec
|
||||
ret
|
||||
uartHwReadAndValidateHeader_error:
|
||||
clc
|
||||
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)
|
||||
@@ -278,3 +205,39 @@ uartHwReadUptoNumBytes_done:
|
||||
; @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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user