avr: more work on hardware based uart module.

This commit is contained in:
Martin Preuss
2025-01-27 00:20:45 +01:00
parent a96bd7fc07
commit 52bbfcfb15
11 changed files with 650 additions and 71 deletions

View File

@@ -4,7 +4,7 @@
<extradist> <extradist>
crc8.asm crc8.asm
fixedbuffers.asm m_fixedbuffers.asm
m_ringbuffer.asm m_ringbuffer.asm
m_ringbuffer_y.asm m_ringbuffer_y.asm
ringbuffer.asm ringbuffer.asm

View File

@@ -92,7 +92,7 @@ l_end:
; @param %1 constant maxBuffers ; @param %1 constant maxBuffers
; @clobbers r16, X ; @clobbers r16, X
.macro m_fixedbuf_locate: .macro m_fixedbuf_locate
cpi r16, @1 cpi r16, @1
brcc l_end ; idx out of range, use cleared CFLAG brcc l_end ; idx out of range, use cleared CFLAG
tst r16 ; doesn't change CFLAG which is set from CPI above tst r16 ; doesn't change CFLAG which is set from CPI above

View File

@@ -70,6 +70,12 @@
;#define MODULES_MOTION ;#define MODULES_MOTION
.equ UART_HW_FIXEDBUFFERS_NUM = 32
.equ UART_HW_FIXEDBUFFERS_SIZE = 6
.equ UART_HW_MSGNUMINBUF_SIZE = 6
.equ UART_HW_MSGNUMOUTBUF_SIZE = 6
; *************************************************************************** ; ***************************************************************************
; code segment ; code segment
@@ -134,36 +140,13 @@ firmwareStart:
ldi r16, Low(RAMEND) ldi r16, Low(RAMEND)
out SPL, r16 ; init LSB stack pointer out SPL, r16 ; init LSB stack pointer
#if 0
; start by setting all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
sts PUEA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
sts PUEB, r16 ; enable pull-up on all
.endif
.ifdef PORTC
out DDRC, r17 ; all input
sts PUEC, r16 ; enable pull-up on all
.endif
#endif
rcall systemSetSpeed rcall systemSetSpeed
rcall initHardware
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot) ; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
rcall Utils_Init rcall initModules
rcall BaseTimer_Init
rcall LedSimple_Init
rcall Utils_SetupUid rcall Utils_SetupUid
sbi LED_SIMPLE_DDR, LED_SIMPLE_PINNUM ; out sbi LED_SIMPLE_DDR, LED_SIMPLE_PINNUM ; out
sbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; off sbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; off
@@ -217,6 +200,40 @@ onSystemTimerTick:
initHardware:
; set all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
sts PUEA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
sts PUEB, r16 ; enable pull-up on all
.endif
.ifdef PORTC
out DDRC, r17 ; all input
sts PUEC, r16 ; enable pull-up on all
.endif
ret
; @end
initModules:
rcall Utils_Init
rcall BaseTimer_Init
rcall LedSimple_Init
rcall UART_HW_Init
ret
; @end
; *************************************************************************** ; ***************************************************************************
@@ -226,10 +243,19 @@ onSystemTimerTick:
.include "common/utils_wait_fixed.asm" .include "common/utils_wait_fixed.asm"
.include "common/utils_copy_from_flash.asm" .include "common/utils_copy_from_flash.asm"
.include "common/utils_copy_sdram.asm" .include "common/utils_copy_sdram.asm"
.include "common/m_ringbuffer_y.asm"
.include "common/ringbuffer_y.asm"
.include "common/m_fixedbuffers.asm"
.include "common/crc8.asm" .include "common/crc8.asm"
.include "modules/flash/wait.asm" .include "modules/flash/wait.asm"
.include "modules/basetimer/main.asm" .include "modules/basetimer/main.asm"
.include "modules/led_simple/main.asm" .include "modules/led_simple/main.asm"
.include "modules/uart_hw/defs.asm"
.include "modules/uart_hw/buffers.asm"
.include "modules/uart_hw/lowlevel.asm"
.include "modules/uart_hw/lowlevel_uart1.asm"
.include "modules/uart_hw/msglevel_recv.asm"
.include "modules/uart_hw/msglevel_send.asm"

View File

@@ -3,7 +3,13 @@
<gwbuild> <gwbuild>
<extradist> <extradist>
buffers.asm
defs.asm defs.asm
init_uart1.asm
lowlevel.asm
lowlevel_uart1.asm
msglevel_recv.asm
msglevel_send.asm
</extradist> </extradist>
</gwbuild> </gwbuild>

View File

@@ -13,6 +13,8 @@
uartHwDataBegin: uartHwDataBegin:
; fixed buffers for incoming and outgoing messages ; fixed buffers for incoming and outgoing messages
uartHw_buffers: .byte UART_HW_FIXEDBUFFERS_NUM*UART_HW_FIXEDBUFFERS_SIZE uartHw_buffers: .byte UART_HW_FIXEDBUFFERS_NUM*UART_HW_FIXEDBUFFERS_SIZE
uartHw_ringBufferMsgNumIn: .byte UART_HW_MSGNUMINBUF_SIZE
uartHw_ringBufferMsgNumOut: .byte UART_HW_MSGNUMOUTBUF_SIZE
uartHwDataEnd: uartHwDataEnd:
@@ -53,18 +55,34 @@ UART_HW_FixedBuffers_Alloc:
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine UART_HW_FixedBuffers_Release @global ; @routine UART_HW_FixedBuffers_ReleaseByAddr @global
; ;
; @param X pointer to start of buffers ; @param X pointer to start of buffers
; @clobbers R16 ; @clobbers R16
UART_HW_FixedBuffers_Release: UART_HW_FixedBuffers_ReleaseByAddr:
m_fixedbuf_release m_fixedbuf_release
ret ret
; @end ; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_FixedBuffers_ReleaseByNum @global
;
; @param r16 buffer number
; @clobbers X (R16)
UART_HW_FixedBuffers_ReleaseByNum:
rcall UART_HW_FixedBuffers_Locate ; (R16)
brcc UART_HW_FixedBuffers_ReleaseByNum_end
rcall UART_HW_FixedBuffers_ReleaseByAddr ; (R16)
UART_HW_FixedBuffers_ReleaseByNum_end:
ret
; @end
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine UART_HW_FixedBuffers_Locate ; @routine UART_HW_FixedBuffers_Locate
; ;
@@ -99,3 +117,88 @@ UART_HW_FixedBuffers_Locate_end:
; ---------------------------------------------------------------------------
; @routine UART_HW_AddIncomingMsg @global
;
; @return CFLAG on success, cleared on error
; @param R16 buffer number of the next incoming message
; @clobbers R17, R18, X
UART_HW_AddIncomingMsgNum:
push yl
push yh
ldi yl, LOW(uartHw_ringBufferMsgNumIn)
ldi yh, HIGH(uartHw_ringBufferMsgNumIn)
rcall RingBufferY_WriteByte ; R17, R18, X
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_GetNextIncomingMsgNum @global
;
; @return CFLAG on success, cleared on error
; @return R16 buffer number of the next incoming message
; @param Y pointer to start of interface data
; @clobbers R17, R18, X
UART_HW_GetNextIncomingMsgNum:
push yl
push yh
ldi yl, LOW(uartHw_ringBufferMsgNumIn)
ldi yh, HIGH(uartHw_ringBufferMsgNumIn)
rcall RingBufferY_ReadByte ; R17, R18, X
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_AddOutgoingMsg @global
;
; @return CFLAG on success, cleared on error
; @param R16 buffer number of the next incoming message
; @clobbers R17, R18, X
UART_HW_AddOutgoingMsgNum:
push yl
push yh
ldi yl, LOW(uartHw_ringBufferMsgNumOut)
ldi yh, HIGH(uartHw_ringBufferMsgNumOut)
rcall RingBufferY_WriteByte ; R17, R18, X
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_GetNextOutgoingMsgNum @global
;
; @return CFLAG on success, cleared on error
; @return R16 buffer number of the next incoming message
; @param Y pointer to start of interface data
; @clobbers R17, R18, X
UART_HW_GetNextOutgoingMsgNum:
push yl
push yh
ldi yl, LOW(uartHw_ringBufferMsgNumOut)
ldi yh, HIGH(uartHw_ringBufferMsgNumOut)
rcall RingBufferY_ReadByte ; R17, R18, X
pop yh
pop yl
ret
; @end

View File

@@ -22,27 +22,44 @@
.equ UART_HW_STATUS_UNDERRUN = 0x01 .equ UART_HW_STATUS_UNDERRUN = 0x01
.equ UART_HW_STATUS_OVERRUN = 0x02 .equ UART_HW_STATUS_OVERRUN = 0x02
.equ UART_HW_STATUS_HWERR = 0x04 .equ UART_HW_STATUS_HWERR = 0x04
.equ UART_HW_STATUS_SOFTERR = 0x08
.equ UART_HW_STATUS_ATTN = 0x80 .equ UART_HW_STATUS_ATTN = 0x80
.equ UART_HW_IFACE_OFFS_MODE = 0 .equ UART_HW_IFACE_OFFS_MODE = 0
.equ UART_HW_IFACE_OFFS_STATUS = 1 .equ UART_HW_IFACE_OFFS_STATUS = 1
.equ UART_HW_IFACE_OFFS_READTIMER = 2 .equ UART_HW_IFACE_OFFS_READTIMER = 2
.equ UART_HW_IFACE_OFFS_WRITETIMER = 3
.equ UART_HW_IFACE_OFFS_ERR_OVR = 4
.equ UART_HW_IFACE_OFFS_READBUF = 3 ; ringbuffer for incoming chars ; ringbuffer for incoming chars
.equ UART_HW_IFACE_OFFS_READBUF_MAX = UART_HW_IFACE_OFFS_READBUF .equ UART_HW_IFACE_OFFS_READBUF = 5
.equ UART_HW_IFACE_OFFS_READBUF_USED = UART_HW_IFACE_OFFS_READBUF+1 .equ UART_HW_IFACE_OFFS_READBUF_MAX = UART_HW_IFACE_OFFS_READBUF
.equ UART_HW_IFACE_OFFS_READBUF_RDPOS = UART_HW_IFACE_OFFS_READBUF+2 .equ UART_HW_IFACE_OFFS_READBUF_USED = UART_HW_IFACE_OFFS_READBUF+1
.equ UART_HW_IFACE_OFFS_READBUF_WRPOS = UART_HW_IFACE_OFFS_READBUF+3 .equ UART_HW_IFACE_OFFS_READBUF_RDPOS = UART_HW_IFACE_OFFS_READBUF+2
.equ UART_HW_IFACE_OFFS_READBUF_DATA = UART_HW_IFACE_OFFS_READBUF+4 ; UART_HW_IFACE_READBUF_SIZE bytes .equ UART_HW_IFACE_OFFS_READBUF_WRPOS = UART_HW_IFACE_OFFS_READBUF+3
.equ UART_HW_IFACE_OFFS_READBUF_DATA = UART_HW_IFACE_OFFS_READBUF+4 ; UART_HW_IFACE_READBUF_SIZE bytes
.equ UART_HW_IFACE_OFFS_WRITEBUF = UART_HW_IFACE_OFFS_READBUF_DATA+UART_HW_IFACE_READBUF_SIZE ; ringbuffer for outgoing chars
.equ UART_HW_IFACE_OFFS_WRITEBUF_MAX = UART_HW_IFACE_OFFS_WRITEBUF .equ UART_HW_IFACE_OFFS_WRITEBUF = UART_HW_IFACE_OFFS_READBUF_DATA+UART_HW_IFACE_READBUF_SIZE
.equ UART_HW_IFACE_OFFS_WRITEBUF_USED = UART_HW_IFACE_OFFS_WRITEBUF+1 .equ UART_HW_IFACE_OFFS_WRITEBUF_MAX = UART_HW_IFACE_OFFS_WRITEBUF
.equ UART_HW_IFACE_OFFS_WRITEBUF_RDPOS = UART_HW_IFACE_OFFS_WRITEBUF+2 .equ UART_HW_IFACE_OFFS_WRITEBUF_USED = UART_HW_IFACE_OFFS_WRITEBUF+1
.equ UART_HW_IFACE_OFFS_WRITEBUF_WRPOS = UART_HW_IFACE_OFFS_WRITEBUF+3 .equ UART_HW_IFACE_OFFS_WRITEBUF_RDPOS = UART_HW_IFACE_OFFS_WRITEBUF+2
.equ UART_HW_IFACE_OFFS_WRITEBUF_DATA = UART_HW_IFACE_OFFS_WRITEBUF+4 .equ UART_HW_IFACE_OFFS_WRITEBUF_WRPOS = UART_HW_IFACE_OFFS_WRITEBUF+3
.equ UART_HW_IFACE_OFFS_WRITEBUF_DATA = UART_HW_IFACE_OFFS_WRITEBUF+4
.equ UART_HW_IFACE_SIZE = UART_HW_IFACE_OFFS_WRITEBUF_DATA+UART_HW_IFACE_WRITEBUF_SIZE .equ UART_HW_IFACE_OFFS_READMSG = UART_HW_IFACE_OFFS_WRITEBUF_DATA+UART_HW_IFACE_WRITEBUF_SIZE
.equ UART_HW_IFACE_OFFS_READMSG_BUFNUM = UART_HW_IFACE_OFFS_READMSG ; 1 byte
.equ UART_HW_IFACE_OFFS_READMSG_PTR = UART_HW_IFACE_OFFS_READMSG+1 ; 2 bytes
.equ UART_HW_IFACE_OFFS_READMSG_USED = UART_HW_IFACE_OFFS_READMSG+3 ; 1 byte
.equ UART_HW_IFACE_OFFS_READMSG_LEFT = UART_HW_IFACE_OFFS_READMSG+4 ; 1 byte
.equ UART_HW_IFACE_OFFS_WRITEMSG = UART_HW_IFACE_OFFS_READMSG_LEFT+1
.equ UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM = UART_HW_IFACE_OFFS_WRITEMSG ; 1 byte
.equ UART_HW_IFACE_OFFS_WRITEMSG_PTR = UART_HW_IFACE_OFFS_WRITEMSG+1 ; 2 bytes
.equ UART_HW_IFACE_OFFS_WRITEMSG_USED = UART_HW_IFACE_OFFS_WRITEMSG+3 ; 1 byte
.equ UART_HW_IFACE_OFFS_WRITEMSG_LEFT = UART_HW_IFACE_OFFS_WRITEMSG+4 ; 1 byte
.equ UART_HW_IFACE_SIZE = UART_HW_IFACE_OFFS_WRITEMSG_LEFT+1

View File

@@ -27,7 +27,7 @@ UART_HW_Init:
rcall Utils_FillSram rcall Utils_FillSram
rcall UART_HW_FixedBuffers_Init rcall UART_HW_FixedBuffers_Init
ldi r16, UART_HW_MSGNUMINBUF_SIZE ldi r16, UART_HW_MSGNUMINBUF_SIZE
ldi yl, LOW(uartHw_ringBufferMsgNumIn) ldi yl, LOW(uartHw_ringBufferMsgNumIn)
ldi yh, HIGH(uartHw_ringBufferMsgNumIn) ldi yh, HIGH(uartHw_ringBufferMsgNumIn)
@@ -37,7 +37,8 @@ UART_HW_Init:
ldi yl, LOW(uartHw_ringBufferMsgNumOut) ldi yl, LOW(uartHw_ringBufferMsgNumOut)
ldi yh, HIGH(uartHw_ringBufferMsgNumOut) ldi yh, HIGH(uartHw_ringBufferMsgNumOut)
rcall RingBufferY_Init rcall RingBufferY_Init
sec sec
ret ret
; @end ; @end
@@ -67,6 +68,9 @@ UART_HW_InterfaceInit:
UART_HW_IFACE_OFFS_WRITEBUF_RDPOS, \ UART_HW_IFACE_OFFS_WRITEBUF_RDPOS, \
UART_HW_IFACE_OFFS_WRITEBUF_WRPOS, \ UART_HW_IFACE_OFFS_WRITEBUF_WRPOS, \
UART_HW_IFACE_OFFS_WRITEBUF_DATA UART_HW_IFACE_OFFS_WRITEBUF_DATA
ldi r16, 0xff
std Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM, r16
std Y+UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM, r16
ret ret
; @end ; @end
@@ -84,7 +88,7 @@ UART_HW_InterfaceWriteToReadBuffer:
push yl push yl
push yh push yh
adiw yh:yl, UART_HW_IFACE_OFFS_READBUF adiw yh:yl, UART_HW_IFACE_OFFS_READBUF
rcall RingBufferY_WriteByte ; R17, R18, X rcall uartHwRingBufferWriteGuarded ; R17, R18, X
pop yh pop yh
pop yl pop yl
ret ret
@@ -104,7 +108,7 @@ UART_HW_InterfaceReadFromReadBuffer:
push yl push yl
push yh push yh
adiw yh:yl, UART_HW_IFACE_OFFS_READBUF adiw yh:yl, UART_HW_IFACE_OFFS_READBUF
rcall RingBufferY_ReadByte ; R17, R18, X rcall uartHwRingBufferReadGuarded ; R17, R18, X
pop yh pop yh
pop yl pop yl
ret ret
@@ -124,7 +128,7 @@ UART_HW_InterfaceWriteToWriteBuffer:
push yl push yl
push yh push yh
adiw yh:yl, UART_HW_IFACE_OFFS_WRITEBUF adiw yh:yl, UART_HW_IFACE_OFFS_WRITEBUF
rcall RingBufferY_WriteByte ; R17, R18, X rcall uartHwRingBufferWriteGuarded ; R17, R18, X
pop yh pop yh
pop yl pop yl
ret ret
@@ -144,7 +148,7 @@ UART_HW_InterfaceReadFromWriteBuffer:
push yl push yl
push yh push yh
adiw yh:yl, UART_HW_IFACE_OFFS_WRITEBUF adiw yh:yl, UART_HW_IFACE_OFFS_WRITEBUF
rcall RingBufferY_ReadByte ; R17, R18, X rcall uartHwRingBufferReadGuarded ; R17, R18, X
pop yh pop yh
pop yl pop yl
ret ret
@@ -152,6 +156,67 @@ UART_HW_InterfaceReadFromWriteBuffer:
UART_HW_Interface_Run:
; ---------------------------------------------------------------------------
; @routine uartHwRingBufferReadGuarded
;
; @return CFLAG on success, cleared on error
; @param r16 byte to write
; @param Y pointer to start of interface data
; @clobbers R17, R18, X
uartHwRingBufferReadGuarded:
push r15
in r15, SREG
cli
rcall RingBufferY_ReadByte ; R17, R18, X
brcc uartHwRingBufferReadGuarded_error
out SREG, r15
pop r15
sec
ret
uartHwRingBufferReadGuarded_error:
out SREG, r15
pop r15
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartHwRingBufferWriteGuarded
;
; @return CFLAG on success, cleared on error
; @param r16 byte to write
; @param Y pointer to start of interface data
; @clobbers R17, R18, X
uartHwRingBufferWriteGuarded:
push r15
in r15, SREG
cli
rcall RingBufferY_WriteByte ; R17, R18, X
brcc uartHwRingBufferWriteGuarded_error
out SREG, r15
pop r15
sec
ret
uartHwRingBufferWriteGuarded_error:
out SREG, r15
pop r15
clc
ret
; @end

View File

@@ -119,7 +119,7 @@ UART_HW_TtyOn1_StopTx:
UART_HW_TtyOn1_RxCharIsr: UART_HW_TtyOn1_RxCharIsr:
sbis UCSR1A, RXC1 sbis UCSR1A, RXC1
rjmp UART_HW_TtyOn1_RxCharIsr_end ; no data rjmp UART_HW_TtyOn1_RxCharIsr_end ; no data
in r16, UDR1 in r16, UDR1
rcall UART_HW_InterfaceAddReadByte ; (R17, R18, X) rcall UART_HW_InterfaceAddReadByte ; (R17, R18, X)
UART_HW_TtyOn1_RxCharIsr_end: UART_HW_TtyOn1_RxCharIsr_end:

View File

@@ -20,8 +20,7 @@
UART_HW_Uart1_StartRx: UART_HW_Uart1_StartRx:
lds r16, UCSR1B lds r16, UCSR1B
sbr r16, (1<<RXCIE1) ; enable RX complete interrupt sbr r16, (1<<RXCIE1) | (1<<RXEN1) ; enable RX complete interrupt, enable receive
sbr r16, (1<<RXEN1) ; enable receive
sts UCSR1B, r16 sts UCSR1B, r16
ret ret
; @end ; @end
@@ -35,8 +34,7 @@ UART_HW_Uart1_StartRx:
UART_HW_Uart1_StopRx: UART_HW_Uart1_StopRx:
lds r16, UCSR1B lds r16, UCSR1B
cbr r16, (1<<RXCIE1) ; disable RX complete interrupt cbr r16, (1<<RXCIE1 | (1<<RXEN1)) ; disable RX complete interrupt, disable receive
cbr r16, (1<<RXEN1) ; disable receive
sts UCSR1B, r16 sts UCSR1B, r16
ret ret
; @end ; @end
@@ -51,8 +49,7 @@ UART_HW_Uart1_StopRx:
UART_HW_Uart1_StartTx: UART_HW_Uart1_StartTx:
lds r16, UCSR1B lds r16, UCSR1B
sbr r16, (1<<UDRIE1) ; enable TX data register empty interrupt sbr r16, (1<<UDRIE1) | (1<<TXEN1) ; enable TX data register empty interrupt, enable transceive
sbr r16, (1<<TXEN1) ; enable transceive
sts UCSR1B, r16 sts UCSR1B, r16
ret ret
; @end ; @end
@@ -67,8 +64,7 @@ UART_HW_Uart1_StartTx:
UART_HW_Uart1_StopTx: UART_HW_Uart1_StopTx:
lds r16, UCSR1B lds r16, UCSR1B
cbr r16, (1<<UDRIE1) ; disable TX data register empty interrupt cbr r16, (1<<UDRIE1) | (1<<TXEN1) ; disable TX data register empty interrupt, disable transceive
cbr r16, (1<<TXEN1) ; disable transceive
sts UCSR1B, r16 sts UCSR1B, r16
ret ret
; @end ; @end
@@ -82,22 +78,22 @@ UART_HW_Uart1_StopTx:
; @clobbers R16 (R17, R18, X) ; @clobbers R16 (R17, R18, X)
UART_HW_Uart1_RxCharIsr: UART_HW_Uart1_RxCharIsr:
in r16, UCSR1A ; check for errors lds r16, UCSR1A ; check for errors
andi r16, (1<<FE1) | (1<<DOR1) | (1<<UPE1) andi r16, (1<<FE1) | (1<<DOR1) | (1<<UPE1)
breq UART_HW_Uart1_RxCharIsr_recv breq UART_HW_Uart1_RxCharIsr_recv ; no error, receive next char
ldd r16, Y+UART_HW_IFACE_OFFS_STATUS ldd r16, Y+UART_HW_IFACE_OFFS_STATUS ; set error status
ori r16, UART_HW_STATUS_HWERR ori r16, UART_HW_STATUS_HWERR ; -> HWERR
std Y+UART_HW_IFACE_OFFS_STATUS, r16 rjmp UART_HW_Uart1_RxCharIsr_setStatusAndEnd
rjmp UART_HW_Uart1_RxCharIsr_end
UART_HW_Uart1_RxCharIsr_recv: UART_HW_Uart1_RxCharIsr_recv:
lds r16, UCSR1A lds r16, UCSR1A
sbrs r16, RXC1 sbrs r16, RXC1
rjmp UART_HW_Uart1_RxCharIsr_end ; no data rjmp UART_HW_Uart1_RxCharIsr_end ; no data
lds r16, UDR1 lds r16, UDR1
rcall UART_HW_InterfaceWriteToReadBuffer ; (R17, R18, X) rcall UART_HW_InterfaceWriteToReadBuffer ; (R17, R18, X)
brcs UART_HW_Uart1_RxCharIsr_end brcs UART_HW_Uart1_RxCharIsr_end
ldd r16, Y+UART_HW_IFACE_OFFS_STATUS ; set overrun error ldd r16, Y+UART_HW_IFACE_OFFS_STATUS ; set overrun error
ori r16, UART_HW_STATUS_OVERRUN ori r16, UART_HW_STATUS_OVERRUN ; -> OVERRUN
UART_HW_Uart1_RxCharIsr_setStatusAndEnd:
std Y+UART_HW_IFACE_OFFS_STATUS, r16 std Y+UART_HW_IFACE_OFFS_STATUS, r16
UART_HW_Uart1_RxCharIsr_end: UART_HW_Uart1_RxCharIsr_end:
ret ret

View File

@@ -0,0 +1,280 @@
; ***************************************************************************
; 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
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_USED
cpi r16, 3
brcs UART_HW_Interface_RunRead_badMsg
; check and store msg
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:
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_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
;
; @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, enter skip mode
ldd r16, Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM
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
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 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
;
; @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
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 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
;
; @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

View File

@@ -0,0 +1,86 @@
; ***************************************************************************
; 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_RunWrite @global
;
; @param Y pointer to start of interface data
; @clobbers r16, r19, X (R17, R18, R20, R21)
UART_HW_Interface_RunWrite:
ldd r19, Y+UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM
cpi r19, 0xff
brne UART_HW_Interface_RunWrite_haveMsg
rcall UART_HW_GetNextOutgoingMsgNum ; (R17, R18, X)
rcall UART_HW_FixedBuffers_Locate ; (R16)
brcc UART_HW_Interface_RunWrite_end
std Y+UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM, r19
adiw xh:xl, 1
std Y+UART_HW_IFACE_OFFS_WRITEMSG_PTR, xl
std Y+UART_HW_IFACE_OFFS_WRITEMSG_PTR+1, xh
adiw xh:xl, 1 ; get msg len
ld r16, X
inc r16
inc r16
inc r16
std Y+UART_HW_IFACE_OFFS_WRITEMSG_LEFT, r16
std Y+UART_HW_IFACE_OFFS_WRITEMSG_USED, r16
UART_HW_Interface_RunWrite_haveMsg:
ldd r20, Y+UART_HW_IFACE_OFFS_WRITEMSG_LEFT
rcall uartHwWriteUptoNumBytes ; (r16, r17, r18, r20, r21, X)
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMSG_LEFT
tst r16
brne UART_HW_Interface_RunWrite_end ; still bytes left to write
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM
rcall UART_HW_FixedBuffers_ReleaseByNum
ldi r16, 0xff ; reset buffer number
std Y+UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM, r16
UART_HW_Interface_RunWrite_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartHwWriteUptoNumBytes
;
; @param Y pointer to start of interface data
; @param R20 number of bytes to read
; @clobbers r16, r20, r21, X (R17, R18)
uartHwWriteUptoNumBytes:
clr r21
ldd xl, Y+UART_HW_IFACE_OFFS_WRITEMSG_PTR
ldd xh, Y+UART_HW_IFACE_OFFS_WRITEMSG_PTR+1
uartHwWriteUptoNumBytes_loop:
ld r16, X+
push xl
push xh
rcall UART_HW_InterfaceWriteToWriteBuffer ; (R17, R18, X)
pop xh
pop xl
brcc uartHwWriteUptoNumBytes_done
inc r21
dec r20
brne uartHwWriteUptoNumBytes_loop
uartHwWriteUptoNumBytes_done:
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMSG_LEFT
sub r16, r21
std Y+UART_HW_IFACE_OFFS_WRITEMSG_LEFT, r16
std Y+UART_HW_IFACE_OFFS_WRITEMSG_PTR, xl
std Y+UART_HW_IFACE_OFFS_WRITEMSG_PTR+1, xh
ret
; @end