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

@@ -95,7 +95,7 @@ onSystemTimerTick:
#endif
#ifdef MODULES_UART_HW
rcall NET_Uart_Periodically
rcall NET_Uart_Every100ms
#endif
#ifdef MODULES_TTYONUART1

View File

@@ -52,7 +52,8 @@
#define MODULES_NETWORK
;#define MODULES_COMONUART0
#define MODULES_UART_HW
#define MODULES_SPI_HW
#define MODULES_ILI9341
;#define MODULES_UART_BITBANG
;#define MODULES_TWI_MASTER
;#define MODULES_LCD
@@ -109,8 +110,7 @@
; ---------------------------------------------------------------------------
; Reset and interrupt vectors
rjmp BOOTLOADER_ADDR ; 1: Reset vector RESET
; rjmp ComOnUart0_AttnChangeIsr ; 2: INT0 External Interrupt Request 0
reti
rjmp NetUart_AttnChangeIsr ; 2: INT0 External Interrupt Request 0
reti ; 3: INT1 External Interrupt Request 1
reti ; 4: TIMER1_CAPT Timer/Counter1 Capture Event
reti ; 5: TIMER1_COMPA Timer/Counter1 Compare Match A
@@ -118,9 +118,9 @@
reti ; 7: TIMER1_OVF Timer/Counter1 Overflow
reti ; 8: TIMER0_OVF Timer/Counter0 Overflow
reti ; 9: SPI_STC Serial Transfer Complete
rjmp Uart_RxCharIsr ; 10: USART_RXC USART Rx Complete
rjmp Uart_UdreIsr ; 11: USART_UDRE USART Data Register Empty
rjmp Uart_TxCharIsr ; 12: USART_TXC USART Tx Complete
reti ; 10: USART_RXC USART Rx Complete
reti ; 11: USART_UDRE USART Data Register Empty
reti ; 12: USART_TXC USART Tx Complete
reti ; 13: ANA_COMP Analog Comparator
reti ; 14: INT2 External Interrupt Request 2
rjmp baseTimerIrqOC0A ; 15: TIMER0_COMP Timer/Counter0 Compare Match
@@ -202,7 +202,7 @@ onEveryLoop:
.include "devices/all/hw_m8515.asm"
.include "devices/all/includes.asm"
.include "common/debug.asm"
;.include "common/debug.asm"

View File

@@ -11,7 +11,6 @@
; ***************************************************************************
; defines
.equ NET_UART_MSG_INTERVAL = 1
@@ -46,195 +45,229 @@ NET_Uart_Init:
; ---------------------------------------------------------------------------
; @routine NET_Uart_Run @global
;
; @clobbers all
NET_Uart_Run:
push r15
in r15, SREG
cli
ldi yl, LOW(netUartIface)
ldi yh, HIGH(netUartIface)
rcall netUartRunReadModes
ldd r16, Y+UART_HW_IFACE_OFFS_READMODE ; test for active read mode
cpi r16, UART_HW_READMODE_IDLE
brne NET_Uart_Run_end
rcall netUartRunWriteModes ; only call write routine if read idle
NET_Uart_Run_end:
pop r15
out SREG, r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine NET_Uart_Periodically
;
; @clobbers all, !Y
NET_Uart_Periodically:
NET_Uart_Every100ms:
ldi yl, LOW(netUartIface)
ldi yh, HIGH(netUartIface)
push r15
in r15, SREG
cli
rcall NET_Interface_Periodically ; (R16)
rcall netUartSendNextPkg
out SREG, r15
pop r15
ret
rjmp NET_Interface_Periodically
; @end
; ---------------------------------------------------------------------------
; @routine netUartSendNextPkg
;
; Check whether there is an outgoing message in interface data
; and send it if possible.
;
; @return CFLAG set if okay, clear on error
; @param Y pointer to start of interface data
; @clobbers R16, R17, R18, R21, R21, R24, R25, X
netUartSendNextPkg:
rcall NET_Interface_PeekNextOutgoingMsgNum ; (R17, R18, X)
brcc netUartSendNextPkg_end
rcall NET_Buffer_Locate ; get pointer to buffer (R17)
brcc netUartSendNextPkg_end
adiw xh:xl, 1 ; skip buffer header
rcall netUartSendPacketWithAttn ; (R16, R17, R21, R22, X)
brcc netUartSendNextPkg_error
rcall NET_Interface_GetNextOutgoingMsgNum ; remove from stack (R17, R18, X)
rcall NET_Buffer_ReleaseByNum ; release buffer (R16, X)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
rjmp netUartSendNextPkg_end
netUartSendNextPkg_error:
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
netUartSendNextPkg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine netUartRunWriteModes
; @routine netUartSendPacket
;
; @clobbers all, !Y
; @param X buffer to send
; @return CFLAG set if okay, cleared on error
; @return R16 error code (if CFLAG cleared)
; @clobbers R16, R17, R22, X
netUartRunWriteModes:
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE ; handle write functions
cpi r16, UART_HW_WRITEMODE_IDLE
breq netUartRunWriteIdle
cpi r16, UART_HW_WRITEMODE_WRITING
breq netUartRunWriting
cpi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
breq netUartRunWaitBufferEmpty
cpi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
breq netUartRunWriteBufferEmpty
ret
; @end
netUartRunWaitBufferEmpty:
rcall UART_GetFlags ; (none)
ldi r17, (1<<UART_FLAGS_LASTBYTESENT_BIT) | (1<<UART_FLAGS_SWUNDERRUN_BIT)
eor r16, r17
andi r16, (1<<UART_FLAGS_LASTBYTESENT_BIT) | (1<<UART_FLAGS_SWUNDERRUN_BIT)
brne netUartRunWaitBufferEmpty_end
rcall UART_StopTx
ldi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
rjmp netUartRunWriteBufferEmpty ; we just entered new write mode
netUartRunWaitBufferEmpty_end:
ret
; @end
netUartRunWriteBufferEmpty:
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
rcall NET_Buffer_ReleaseByNum ; (R16, X)
ldi r16, 0xff
std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r16
rcall ATTN_SetHighEnableIrq ; release bus
ldi r16, UART_HW_WRITEMODE_IDLE
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
ret
; @end
netUartRunWriteIdle:
ldd r16, Y+NET_IFACE_OFFS_WRITETIMER
cpi r16, NET_UART_MSG_INTERVAL ; wait a bit between messages
brcs netUartRunWriteIdle_end
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcc netUartRunWriteIdle_end ; no outmsg in queue
netUartSendPacketWithAttn:
rcall ATTN_IsHigh
brcc netUartRunWriteIdle_end ; ATTN low, jmp
mov r17, r16
rcall ATTN_SetLowDisableIrq ; reserve bus as soon as possible (R16)
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
brcc netUartSendPacketWithAttn_end ; ATTN low, jmp
rcall ATTN_SetLowDisableIrq ; reserve bus (R16)
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
mov r16, r17
rcall NET_Buffer_Locate ; (R17)
rcall UART_HW_Interface_SetWriteBuffer
ldi r17, UART_HW_WRITEMODE_WRITING
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r17
rcall NET_Interface_GetNextOutgoingMsgNum ; take msg from queue (R17, R18, X)
rjmp netUartRunWriting ; just entered writing mode
netUartRunWriteIdle_end:
rcall netUartSendPacket
rcall ATTN_SetHighEnableIrq ; release bus
sec
netUartSendPacketWithAttn_end:
ret
; @end
netUartRunWriting:
ldd r19, Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT
tst r19
breq netUartRunWriting_checkTxEn
rcall UART_GetFlags ; r16=flags (none)
andi r16, (1<<UART_FLAGS_SWUNDERRUN_BIT) | (1<<UART_FLAGS_LASTBYTESENT_BIT)
brne netUartRunWriting_error ; got an error while still bytes to send
; ---------------------------------------------------------------------------
; @routine netUartSendPacket
;
; @param X buffer to send
; @clobbers R17 (R16, X)
netUartSendPacket:
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r17, X
inc r17
inc r17
inc r17
sbiw xh:xl, NETMSG_OFFS_MSGLEN
rjmp UART_SendBytes ; (R16, R17, X)
; @end
; ---------------------------------------------------------------------------
; @routine netUartRecvPacket
;
; alloc a buffer, receive message, add message to global list
; @param Y pointer to start of interface data
; @return CFLAG set if okay, cleared on error
; @clobbers R16, R17, R18, R19, R20, R24, R25, X
netUartRecvPacket:
rcall UART_StartRx ; (R16)
rcall NET_Buffer_Alloc ; (R16, R17, X)
brcs netUartRecvPacket_haveBuf
rcall UART_StopRx ; (R16)
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rjmp netUartRecvPacket_incCounterRet
netUartRecvPacket_haveBuf:
push r16
adiw xh:xl, 1
ldd r18, Y+NET_IFACE_OFFS_ADDRESS
ldi r17, NET_BUFFERS_SIZE-1
rcall netUartRecvPacketIntoX ; (R16, R17, R18, R19, R20, R24, R25)
pop r16
brcc netUartRecvPacket_releaseBufRet
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
brcc netUartRecvPacket_releaseBufRet
rcall UART_StopRx ; (R16)
sec
ret
netUartRecvPacket_releaseBufRet:
rcall NET_Buffer_ReleaseByNum ; (R16, X)
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
netUartRecvPacket_incCounterRet:
rcall NET_Interface_IncCounter16 ; (R24, R25)
rcall UART_StopRx ; (R16)
netUartRecvPacket_retNc:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine netUartRecvPacketIntoX
;
; @param Y pointer to start of interface data
; @param X pointer buffer (in RAM)
; @param r17 maximum number of bytes to receive
; @param r18 network address to listen to
; @return CFLAG set if okay, cleared on error
; @clobbers R16, R17, R18, R19, R20, R24, R25
netUartRecvPacketIntoX:
push xh
push xl
rcall UART_RecvPacket ; (r16, r17, X)
pop xl
pop xh
brcc netUartRecvPacketIntoX_handleError
push xl
push xh
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
pop xh
pop xl
brcc netUartRecvPacketIntoX_contentError
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
ret
netUartRecvPacketIntoX_handleError:
mov r17, r16
cpi r17, UART_ERROR_IO
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
breq netUartRecvPacketIntoX_incCounterRetNc
cpi r17, UART_ERROR_CONTENT
breq netUartRecvPacketIntoX_contentError
rjmp netUartRecvPacketIntoX_retNc
netUartRecvPacketIntoX_contentError:
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
netUartRecvPacketIntoX_incCounterRetNc:
rcall NET_Interface_IncCounter16 ; (R24, R25)
netUartRecvPacketIntoX_retNc:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine NetUart_AttnChangeIsr @global @isr
;
; @clobbers none
NetUart_AttnChangeIsr:
push r15
in r15, SREG
push r16
push r17
push r18
push r19
push r20
push r24
push r25
push xl
push xh
push yl
push yh
push zl
push zh
ldd zl, Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_LOW
ldd zh, Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_HIGH
clr r16
std Y+NET_IFACE_OFFS_WRITETIMER, r16
netUartRunWriting_loop:
ld r16, Z
rcall UART_WriteByte ; (R17, R18, X, Y)
brcc netUartRunWriting_loopEnd
adiw zh:zl, 1
dec r19
brne netUartRunWriting_loop
netUartRunWriting_loopEnd:
pop zl
pop zh
ldi yl, LOW(netUartIface)
ldi yh, HIGH(netUartIface)
rcall netUartRecvPacket ; (R16, R17, R18, R19, R20, R24, R25, X)
pop yh
pop yl
std Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_LOW, zl
std Y+UART_HW_IFACE_OFFS_WRITEBUFPOS_HIGH, zh
std Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT, r19
netUartRunWriting_checkTxEn:
rcall UART_GetFlags ; (none)
sbrs r16, UART_FLAGS_TXEN_BIT
rcall UART_StartTx ; (R16)
tst r19
brne netUartRunWriting_end
ldi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
rjmp netUartRunWaitBufferEmpty ; we just entered new write mode
netUartRunWriting_error:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall netUartAbortTx
netUartRunWriting_end:
ret
pop xh
pop xl
pop r25
pop r24
pop r20
pop r19
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine netUartAbortTx
;
; @clobbers all, !Y
netUartAbortTx:
rcall NET_Interface_IncCounter16
rcall UART_StopTx
rcall UART_ResetWriteBuffer
rcall ATTN_SetHighEnableIrq
ldi r16, UART_HW_WRITEMODE_IDLE
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
ldi r17, 0xff
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r17
rjmp NET_Buffer_ReleaseByNum
; @end
netUartRunReadModes:
ret
; @end

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