uart_hw: removed unneeded code.

This commit is contained in:
Martin Preuss
2025-05-20 00:30:39 +02:00
parent 8ece026f2d
commit aceffdfad2
4 changed files with 377 additions and 441 deletions

View File

@@ -12,29 +12,12 @@
; defines
.equ UART_RINGBUFFER_IN_SIZE = 24
.equ UART_RINGBUFFER_OUT_SIZE = 32
.equ UART_ERROR_NOTFORME = 1
.equ UART_ERROR_INVALID = 2
.equ UART_ERROR_IO = 3
.equ UART_ERROR_CONTENT = 4
.equ UART_FLAGS_TXEN_BIT = 7
.equ UART_FLAGS_RXEN_BIT = 6
.equ UART_FLAGS_HWOVERRUN_BIT = 5
.equ UART_FLAGS_FRAMEERROR_BIT = 4
.equ UART_FLAGS_SWOVERRUN_BIT = 3
.equ UART_FLAGS_SWUNDERRUN_BIT = 2
.equ UART_FLAGS_LASTBYTESENT_BIT = 1
; ***************************************************************************
; data
.dseg
uartFlags: .byte 1
uartRingbufferIn: .byte RINGBUFFERY_SIZE+UART_RINGBUFFER_IN_SIZE
uartRingbufferOut: .byte RINGBUFFERY_SIZE+UART_RINGBUFFER_OUT_SIZE
; ***************************************************************************
; code
@@ -44,19 +27,6 @@ uartRingbufferOut: .byte RINGBUFFERY_SIZE+UART_RINGBUFFER_OUT_SIZE
UART_Init:
clr r16
sts uartFlags, r16
ldi r16, UART_RINGBUFFER_IN_SIZE
ldi yl, LOW(uartRingbufferIn)
ldi yh, HIGH(uartRingbufferIn)
rcall RingBufferY_Init
ldi r16, UART_RINGBUFFER_OUT_SIZE
ldi yl, LOW(uartRingbufferOut)
ldi yh, HIGH(uartRingbufferOut)
rcall RingBufferY_Init
; set baudrate
.if clock == 8000000
ldi r16, 25 ; (19.2Kb/s at 8MHz)
@@ -84,24 +54,194 @@ UART_Init:
; ---------------------------------------------------------------------------
; @routine UART_SendBytes @global
;
; @param X pointer data to send (in RAM)
; @param r17 number of bytes to send
; @clobbers R16, R17, X
UART_SendBytes:
tst r17
breq UART_SendBytes_secRet
rcall UART_StartTx ; (R16)
; send bytes
UART_SendBytes_loop1:
M_IO_READ r16, UCSRA
sbrs r16, UDRE
rjmp UART_SendBytes_loop1
ld r16, X+
M_IO_WRITE UDR, r16
dec r17
brne UART_SendBytes_loop1
; wait until all data sent
UART_SendBytes_loop2:
M_IO_READ r16, UCSRA
sbrs r16, TXC
rjmp UART_SendBytes_loop2
rcall UART_StopTx
UART_SendBytes_secRet:
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_RecvPacket @global
;
; @param X pointer buffer (in RAM)
; @param r17 maximum number of bytes to receive
; @param r18 network address to listen to
; @clobbers r16, r17, X
UART_RecvPacket:
cpi r17, 3
brcs UART_RecvPacket_invalid
rcall uartRecvByteWithin10ms ; recv destination address
brcc UART_RecvPacket_ioError
cp r16, r18
breq UART_RecvPacket_forMe
cpi r16, 0xff
breq UART_RecvPacket_forMe
ldi r16, UART_ERROR_NOTFORME
rjmp UART_RecvPacket_clcRet
UART_RecvPacket_forMe:
st X+, r16 ; dest addr
dec r17
rcall uartRecvByteWithin10ms ; msg len (R16)
brcc UART_RecvPacket_ioError
st X+, r16
dec r17
inc r16 ; account for CRC
cp r17, r16
brcs UART_RecvPacket_badMsg
mov r17, r16
UART_RecvPacket_loop:
rcall uartRecvByteWithin10ms ; (R16)
brcc UART_RecvPacket_ioError
st X+, r16
dec r17
brne UART_RecvPacket_loop
sec
ret
UART_RecvPacket_invalid:
ldi r16, UART_ERROR_INVALID
rjmp UART_RecvPacket_clcRet
UART_RecvPacket_badMsg:
ldi r16, UART_ERROR_CONTENT
rjmp UART_RecvPacket_clcRet
UART_RecvPacket_ioError:
ldi r16, UART_ERROR_IO
UART_RecvPacket_clcRet:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartRecvByteWithin10ms
;
; Wait up to 10ms for incoming byte and read it.
;
; @return CFLAG set if okay (data available), cleared on error
; @return r16 byte received (if CFLAG set)
; @clobbers: none
uartRecvByteWithin10ms:
push r20
push r22
rcall uartWaitForData10ms ; (R20, R22)
pop r22
pop r20
brcc uartRecvByteWithin10ms_end
M_IO_READ r16, UCSRA ; check for errors
andi r16, (1<<FE) | (1<<DOR)
brne uartRecvByteWithin10ms_error
M_IO_READ r16, UDR ; read data byte
sec
ret
uartRecvByteWithin10ms_error:
clc
uartRecvByteWithin10ms_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartWaitForData10ms
;
; Wait for incoming data for max 10 milliseconds.
;
; @return CFLAG set if okay (data available), cleared on error
; @clobbers: r20, r22
uartWaitForData10ms:
.if clock == 8000000
ldi r20, 80
.endif
.if clock == 1000000
ldi r20, 10
.endif
uartWaitForData10ms_loop:
push r20
rcall uartWaitForData1000Cycles ; (r20, r22)
pop r20
brcs uartWaitForData10ms_gotit
dec r20
brne uartWaitForData10ms_loop
clc
uartWaitForData10ms_gotit:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartWaitForData1000Cycles
;
; Wait for incoming data for max 1000 clock cycles
; (about 1ms at 1MHz, 0.125 at 8MHz)
;
; @return CFLAG set if okay (packet received), cleared on error
; @clobbers: r20, r22
uartWaitForData1000Cycles:
ldi r20, 140 ; 1
uartWaitForData_loop:
M_IO_READ r22, UCSRA ; 2
sbrc r22, RXC ; 2/3
rjmp uartWaitForData_gotit ; 2
dec r20 ; 1
brne uartWaitForData_loop ; 1/2 -> 7 per loop, max about 1000
clc ; 1
ret ; 4
uartWaitForData_gotit:
sec ; 1
ret ; 4
; @end
; ---------------------------------------------------------------------------
; @routine UART_StartRx @global
;
; @clobbers R16
UART_StartRx:
; clear read error flags
lds r16, uartFlags
cbr r16, (1<<UART_FLAGS_HWOVERRUN_BIT) | (1<<UART_FLAGS_FRAMEERROR_BIT) | (1<<UART_FLAGS_SWOVERRUN_BIT)
sbr r16, (1<<UART_FLAGS_RXEN_BIT)
sts uartFlags, r16
M_IO_READ r16, UCSRA ; clear errors
cbr r16,(1<<RXC) | (1<<FE) | (1<<DOR) | (1<<UPE)
cbr r16, (1<<FE) | (1<<DOR) | (1<<UPE)
sbr r16, (1<<RXC)
M_IO_WRITE UCSRA, r16
M_IO_READ r16, UCSRB
sbr r16, (1<<RXCIE) | (1<<RXEN) ; enable RX complete interrupt, enable receive
sbr r16, (1<<RXEN) ; enable receive
M_IO_WRITE UCSRB, r16
ret
@@ -115,10 +255,6 @@ UART_StartRx:
; @clobbers R16
UART_StopRx:
lds r16, uartFlags
cbr r16, (1<<UART_FLAGS_RXEN_BIT)
sts uartFlags, r16
M_IO_READ r16, UCSRB
cbr r16, (1<<RXCIE | (1<<RXEN)) ; disable RX complete interrupt, disable receive
M_IO_WRITE UCSRB, r16
@@ -134,18 +270,12 @@ UART_StopRx:
; @clobbers R16
UART_StartTx:
; clear write error flags
lds r16, uartFlags
cbr r16, (1<<UART_FLAGS_SWUNDERRUN_BIT) | (1<<UART_FLAGS_LASTBYTESENT_BIT)
sbr r16, (1<<UART_FLAGS_TXEN_BIT)
sts uartFlags, r16
M_IO_READ r16, UCSRA
cbr r16, (1<<TXC) ; clear TXC interrupt
sbr r16, (1<<TXC) ; clear TXC interrupt
M_IO_WRITE UCSRA, r16
M_IO_READ r16, UCSRB
sbr r16, (1<<UDRIE) | (1<<TXC) | (1<<TXEN) ; enable TX UDRE and TXC1 interrupt, enable transceive
sbr r16, (1<<TXEN) ; enable TX UDRE and TXC1 interrupt, enable transceive
M_IO_WRITE UCSRB, r16
ret
@@ -160,10 +290,6 @@ UART_StartTx:
; @clobbers R16
UART_StopTx:
lds r16, uartFlags
cbr r16, (1<<UART_FLAGS_TXEN_BIT)
sts uartFlags, r16
M_IO_READ r16, UCSRB
cbr r16, (1<<UDRIE) | (1<<TXC) | (1<<TXEN) ; disable TX UDRE and TXC1 interrupt, enable transceive
M_IO_WRITE UCSRB, r16
@@ -173,226 +299,3 @@ UART_StopTx:
; ---------------------------------------------------------------------------
; @routine UART_ReadByte @global
;
; @return CFLAG on success, cleared on error
; @return r16 byte read
; @clobbers (R17, R18, X, Y)
UART_ReadByte:
ldi yl, LOW(uartRingbufferIn)
ldi yh, HIGH(uartRingbufferIn)
rjmp RingBufferY_ReadByteGuarded ; (R17, R18, X)
; @end
; ---------------------------------------------------------------------------
; @routine UART_WriteByte @global
;
; @clobbers (R17, R18, X, Y)
UART_WriteByte:
ldi yl, LOW(uartRingbufferOut)
ldi yh, HIGH(uartRingbufferOut)
rjmp RingBufferY_WriteByteGuarded ; (R17, R18, X)
; @end
; ---------------------------------------------------------------------------
; @routine UART_ResetWriteBuffer @global
;
; @clobbers (R17)
UART_ResetWriteBuffer:
ldi yl, LOW(uartRingbufferOut)
ldi yh, HIGH(uartRingbufferOut)
rjmp RingBufferY_Reset ; (R17)
; @end
; ---------------------------------------------------------------------------
; @routine UART_GetFlags @global
;
; @return r16 flags
; @clobbers none
UART_GetFlags:
lds r16, uartFlags
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_RxCharIsr @isr
;
UART_RxCharIsr:
push r15
in r15, SREG
push r16
push r17
push r18
push xl
push xh
push yl
push yh
rcall uartHandleRxChar
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine UART_TxCharIsr @isr
;
UART_TxCharIsr:
push r15
in r15, SREG
push r16
rcall uartHandleTxChar ; (R16)
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine UART_UdreIsr @isr
;
UART_UdreIsr:
push r15
in r15, SREG
push r16
push r17
push r18
push xl
push xh
push yl
push yh
rcall uartHandleUdre
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine uartHandleRxChar
;
; @clobbers R16, R17, Y (R18, X)
uartHandleRxChar:
; check for errors
M_IO_READ r16, UCSRA
sbrc r16, FE
rjmp uartHandleRxChar_hwErrFe
sbrc r16, DOR
rjmp uartHandleRxChar_hwErrDor
; have char?
sbrs r16, RXC
rjmp uartHandleRxChar_end ; no data
; read char
M_IO_READ r16, UDR ; r16=received char
ldi yl, LOW(uartRingbufferIn)
ldi yh, HIGH(uartRingbufferIn)
rcall RingBufferY_WriteByte ; (R17, R18, X)
brcs uartHandleRxChar_end
lds r16, UART_FLAGS_SWOVERRUN_BIT
rjmp uartHandleRxChar_storeErrorFlags
uartHandleRxChar_hwErrFe:
lds r16, UART_FLAGS_FRAMEERROR_BIT
rjmp uartHandleRxChar_storeErrorFlags
uartHandleRxChar_hwErrDor:
lds r16, UART_FLAGS_HWOVERRUN_BIT
rjmp uartHandleRxChar_storeErrorFlags
uartHandleRxChar_storeErrorFlags:
lds r17, uartFlags
or r17, r16
sts uartFlags, r17
uartHandleRxChar_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartHandleUdre
;
; @clobbers R16, Y (R17, R18, X)
uartHandleUdre:
M_IO_READ r16, UCSRA
sbrs r16, UDRE
; rjmp uartHandleUdre_disableUdre ; not ready, SNH!
rjmp uartHandleUdre_end ; not ready, SNH!
ldi yl, LOW(uartRingbufferOut)
ldi yh, HIGH(uartRingbufferOut)
rcall RingBufferY_ReadByte ; (R17, R18, X)
brcc uartHandleUdre_underrun
M_IO_WRITE UDR, r16
rjmp uartHandleUdre_end
uartHandleUdre_underrun:
lds r16, uartFlags
sbr r16, (1<<UART_FLAGS_SWUNDERRUN_BIT)
sts uartFlags, r16
uartHandleUdre_disableUdre:
M_IO_READ r16, UCSRB
cbr r16, (1<<UDRIE) ; disable TX UDRE interrupt
M_IO_WRITE UCSRB, r16
uartHandleUdre_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartHandleTxChar
;
; @clobbers R16
uartHandleTxChar:
lds r16, uartFlags
sbr r16, (1<<UART_FLAGS_LASTBYTESENT_BIT)
sts uartFlags, r16
M_IO_READ r16, UCSRB
cbr r16, (1<<TXC) ; disable TXC interrupt
M_IO_WRITE UCSRB, r16
ret
; @end