From ecb2d85ea2fdc4cfab50c4744ea5fdc5fb645026 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Sun, 19 Jan 2025 15:46:21 +0100 Subject: [PATCH] avr: more work on hardware-based UART module. --- avr/modules/uart_hw/buffers.asm | 72 ------ avr/modules/uart_hw/defs.asm | 56 ++--- avr/modules/uart_hw/lowlevel.asm | 77 ++++-- avr/modules/uart_hw/lowlevel_uart1.asm | 135 +++++++++++ avr/modules/uart_hw/raw_uart1.asm | 315 +++++++++++++++++++++++++ 5 files changed, 534 insertions(+), 121 deletions(-) create mode 100644 avr/modules/uart_hw/lowlevel_uart1.asm create mode 100644 avr/modules/uart_hw/raw_uart1.asm diff --git a/avr/modules/uart_hw/buffers.asm b/avr/modules/uart_hw/buffers.asm index 29385d2..ec5aee2 100644 --- a/avr/modules/uart_hw/buffers.asm +++ b/avr/modules/uart_hw/buffers.asm @@ -13,13 +13,6 @@ uartHwDataBegin: ; fixed buffers for incoming and outgoing messages uartHw_buffers: .byte UART_HW_FIXEDBUFFERS_NUM*UART_HW_FIXEDBUFFERS_SIZE - - ; ringbuffer for buffer numbers of incoming msgs - uartHw_ringBufferMsgNumIn: .byte RINGBUFFERY_OFFS_DATA+UART_HW_MSGNUMINBUF_SIZE - - ; ringbuffer for buffer numbers of outgoing msgs - uartHw_ringBufferMsgNumOut: .byte RINGBUFFERY_OFFS_DATA+UART_HW_MSGNUMOUTBUF_SIZE - uartHwDataEnd: @@ -106,68 +99,3 @@ UART_HW_FixedBuffers_Locate_end: -; --------------------------------------------------------------------------- -; @routine UART_HW_AddIncomingMsg @global -; -; @return CFLAG set if buffer available, cleared otherwise -; @return r16 buffer num -; @return X pointer to start of buffer -; @clobbers R17, R18, X, Y - -UART_HW_AddIncomingMsg: - ldi yl, LOW(uartHw_ringBufferMsgNumIn) - ldi yh, HIGH(uartHw_ringBufferMsgNumIn) - rjmp RingBufferY_WriteByte ; (R17, R18, X) -; @end - - - -; --------------------------------------------------------------------------- -; @routine UART_HW_GetNextIncomingMsg @global -; -; @return CFLAG set if buffer available, cleared otherwise -; @return r16 buffer num -; @return X pointer to start of buffer -; @clobbers R17, R18, X, Y - -UART_HW_GetNextIncomingMsg: - ldi yl, LOW(uartHw_ringBufferMsgNumIn) - ldi yh, HIGH(uartHw_ringBufferMsgNumIn) - rjmp RingBufferY_ReadByte ; (R17, R18, X) -; @end - - - -; --------------------------------------------------------------------------- -; @routine UART_HW_AddOutgoingMsg @global -; -; @return CFLAG set if buffer available, cleared otherwise -; @return r16 buffer num -; @return X pointer to start of buffer -; @clobbers R17, R18, X, Y - -UART_HW_AddOutgoingMsg: - ldi yl, LOW(uartHw_ringBufferMsgNumOut) - ldi yh, HIGH(uartHw_ringBufferMsgNumOut) - rjmp RingBufferY_WriteByte ; (R17, R18, X) -; @end - - - -; --------------------------------------------------------------------------- -; @routine UART_HW_GetNextOutgoingMsg @global -; -; @return CFLAG set if buffer available, cleared otherwise -; @return r16 buffer num -; @return X pointer to start of buffer -; @clobbers R17, R18, X, Y - -UART_HW_GetNextOutgoingMsg: - ldi yl, LOW(uartHw_ringBufferMsgNumOut) - ldi yh, HIGH(uartHw_ringBufferMsgNumOut) - rjmp RingBufferY_ReadByte ; (R17, R18, X) -; @end - - - - diff --git a/avr/modules/uart_hw/defs.asm b/avr/modules/uart_hw/defs.asm index c256ad3..336db9b 100644 --- a/avr/modules/uart_hw/defs.asm +++ b/avr/modules/uart_hw/defs.asm @@ -8,47 +8,41 @@ ; *************************************************************************** -.equ UART_HW_MSGNUMINBUF_SIZE = 8 -.equ UART_HW_MSGNUMOUTBUF_SIZE = 4 - -.equ UART_HW_FIXEDBUFFERS_NUM = 6 -.equ UART_HW_FIXEDBUFFERS_SIZE = 32 ; adapt UART_HW_FixedBuffers_Locate if you change this value! +.equ UART_HW_IFACE_READBUF_SIZE = 8 +.equ UART_HW_IFACE_WRITEBUF_SIZE = 8 +.equ UART_HW_MODE_OFF = 0 +.equ UART_HW_MODE_IDLE = 1 +.equ UART_HW_MODE_READING = 2 +.equ UART_HW_MODE_WRITING = 4 +.equ UART_HW_MODE_SKIPPING = 8 -.equ UART_HW_STATE_OFF = 0 -.equ UART_HW_STATE_IDLE = 1 -.equ UART_HW_STATE_READING = 2 -.equ UART_HW_STATE_WRITING = 3 -.equ UART_HW_STATE_SKIPPING = 4 - -.equ UART_HW_IFACE_MSGIDBUF_SIZE = 8 -.equ UART_HW_IFACE_READBUF_SIZE = 24 +.equ UART_HW_STATUS_UNDERRUN = 0x01 +.equ UART_HW_STATUS_OVERRUN = 0x02 +.equ UART_HW_STATUS_HWERR = 0x04 +.equ UART_HW_STATUS_ATTN = 0x80 .equ UART_HW_IFACE_OFFS_MODE = 0 .equ UART_HW_IFACE_OFFS_STATUS = 1 -.equ UART_HW_IFACE_OFFS_READBUFFERNUM = 2 ; num of buffer currently read -.equ UART_HW_IFACE_OFFS_READBUFFERPOS = 3 ; current pos in readbuffer -.equ UART_HW_IFACE_OFFS_READBUFFERLEFT = 4 ; bytes left to read for current message +.equ UART_HW_IFACE_OFFS_READTIMER = 2 -.equ UART_HW_IFACE_OFFS_WRITEBUFFERNUM = 5 ; num of buffer currently written from to network -.equ UART_HW_IFACE_OFFS_WRITEBUFFERPTR = 6 ; pointer to next pos in current write buffer to write from (2 bytes) -.equ UART_HW_IFACE_OFFS_WRITEBUFFERLEFT= 8 ; bytes left to write for current message +.equ UART_HW_IFACE_OFFS_READBUF = 3 ; ringbuffer for incoming chars +.equ UART_HW_IFACE_OFFS_READBUF_MAX = UART_HW_IFACE_OFFS_READBUF +.equ UART_HW_IFACE_OFFS_READBUF_USED = UART_HW_IFACE_OFFS_READBUF+1 +.equ UART_HW_IFACE_OFFS_READBUF_RDPOS = UART_HW_IFACE_OFFS_READBUF+2 +.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_RINGBUF_MAX = 9 -.equ UART_HW_IFACE_OFFS_RINGBUF_USED = 10 ; ringbuffer for incoming chars -.equ UART_HW_IFACE_OFFS_RINGBUF_RDPOS = 11 -.equ UART_HW_IFACE_OFFS_RINGBUF_WRPOS = 12 -.equ UART_HW_IFACE_OFFS_RINGBUF_DATA = 13 +.equ UART_HW_IFACE_OFFS_WRITEBUF = UART_HW_IFACE_OFFS_READBUF_DATA+UART_HW_IFACE_READBUF_SIZE +.equ UART_HW_IFACE_OFFS_WRITEBUF_MAX = UART_HW_IFACE_OFFS_WRITEBUF +.equ UART_HW_IFACE_OFFS_WRITEBUF_USED = UART_HW_IFACE_OFFS_WRITEBUF+1 +.equ UART_HW_IFACE_OFFS_WRITEBUF_RDPOS = UART_HW_IFACE_OFFS_WRITEBUF+2 +.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_OFFS_MSGIDBUF_MAX = UART_HW_IFACE_OFFS_RINGBUF_DATA+14 ; ringbuffer for ids of outbound messages -.equ UART_HW_IFACE_OFFS_MSGIDBUF_USED = UART_HW_IFACE_OFFS_RINGBUF_DATA+15 ; ringbuffer for ids of outbound messages -.equ UART_HW_IFACE_OFFS_MSGIDBUF_RDPOS = UART_HW_IFACE_OFFS_RINGBUF_DATA+16 -.equ UART_HW_IFACE_OFFS_MSGIDBUF_WRPOS = UART_HW_IFACE_OFFS_RINGBUF_DATA+17 -.equ UART_HW_IFACE_OFFS_MSGIDBUF_DATA = UART_HW_IFACE_OFFS_RINGBUF_DATA+18 - -.equ UART_HW_IFACE_SIZE = UART_HW_IFACE_OFFS_MSGIDBUF_DATA+UART_HW_IFACE_MSGIDBUF_SIZE +.equ UART_HW_IFACE_SIZE = UART_HW_IFACE_OFFS_WRITEBUF_DATA+UART_HW_IFACE_WRITEBUF_SIZE diff --git a/avr/modules/uart_hw/lowlevel.asm b/avr/modules/uart_hw/lowlevel.asm index e7d2a7f..403d121 100644 --- a/avr/modules/uart_hw/lowlevel.asm +++ b/avr/modules/uart_hw/lowlevel.asm @@ -57,35 +57,33 @@ UART_HW_InterfaceInit: clr r16 rcall Utils_FillSram ; (R17, X) m_ringbuffer_y_reset UART_HW_IFACE_READBUF_SIZE, \ - UART_HW_IFACE_OFFS_RINGBUF_USED, \ - UART_HW_IFACE_OFFS_RINGBUF_RDPOS, \ - UART_HW_IFACE_OFFS_RINGBUF_WRPOS, \ - UART_HW_IFACE_OFFS_RINGBUF_DATA - m_ringbuffer_y_reset UART_HW_IFACE_MSGIDBUF_SIZE, \ - UART_HW_IFACE_OFFS_MSGIDBUF_USED, \ - UART_HW_IFACE_OFFS_MSGIDBUF_RDPOS, \ - UART_HW_IFACE_OFFS_MSGIDBUF_WRPOS, \ - UART_HW_IFACE_OFFS_MSGIDBUF_DATA - ldi r16, 0xff - std Y+UART_HW_IFACE_OFFS_READBUFFERNUM, r16 - std Y+UART_HW_IFACE_OFFS_WRITEBUFFERNUM, r16 + UART_HW_IFACE_OFFS_READBUF_USED, \ + UART_HW_IFACE_OFFS_READBUF_RDPOS, \ + UART_HW_IFACE_OFFS_READBUF_WRPOS, \ + UART_HW_IFACE_OFFS_READBUF_DATA + + m_ringbuffer_y_reset UART_HW_IFACE_WRITEBUF_SIZE, \ + UART_HW_IFACE_OFFS_WRITEBUF_USED, \ + UART_HW_IFACE_OFFS_WRITEBUF_RDPOS, \ + UART_HW_IFACE_OFFS_WRITEBUF_WRPOS, \ + UART_HW_IFACE_OFFS_WRITEBUF_DATA ret ; @end ; --------------------------------------------------------------------------- -; @routine UART_HW_InterfaceAddReadByte +; @routine UART_HW_InterfaceWriteToReadBuffer @global ; ; @return CFLAG on success, cleared on error ; @param r16 byte to write ; @param Y pointer to start of interface data ; @clobbers R17, R18, X -UART_HW_InterfaceAddReadByte: +UART_HW_InterfaceWriteToReadBuffer: push yl push yh - adiw yh:yl, UART_HW_IFACE_OFFS_RINGBUF_MAX + adiw yh:yl, UART_HW_IFACE_OFFS_READBUF rcall RingBufferY_WriteByte ; R17, R18, X pop yh pop yl @@ -95,17 +93,17 @@ UART_HW_InterfaceAddReadByte: ; --------------------------------------------------------------------------- -; @routine UART_HW_InterfaceGetNextReadByte +; @routine UART_HW_InterfaceReadFromReadBuffer @global ; ; @return CFLAG on success, cleared on error ; @return R16 byte read ; @param Y pointer to start of interface data ; @clobbers R17, R18, X -UART_HW_InterfaceGetNextReadByte: +UART_HW_InterfaceReadFromReadBuffer: push yl push yh - adiw yh:yl, UART_HW_IFACE_OFFS_RINGBUF_MAX + adiw yh:yl, UART_HW_IFACE_OFFS_READBUF rcall RingBufferY_ReadByte ; R17, R18, X pop yh pop yl @@ -114,3 +112,46 @@ UART_HW_InterfaceGetNextReadByte: +; --------------------------------------------------------------------------- +; @routine UART_HW_InterfaceWriteToWriteBuffer @global +; +; @return CFLAG on success, cleared on error +; @param r16 byte to write +; @param Y pointer to start of interface data +; @clobbers R17, R18, X + +UART_HW_InterfaceWriteToWriteBuffer: + push yl + push yh + adiw yh:yl, UART_HW_IFACE_OFFS_WRITEBUF + rcall RingBufferY_WriteByte ; R17, R18, X + pop yh + pop yl + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine UART_HW_InterfaceReadFromWriteBuffer @global +; +; @return CFLAG on success, cleared on error +; @return R16 byte read +; @param Y pointer to start of interface data +; @clobbers R17, R18, X + +UART_HW_InterfaceReadFromWriteBuffer: + push yl + push yh + adiw yh:yl, UART_HW_IFACE_OFFS_WRITEBUF + rcall RingBufferY_ReadByte ; R17, R18, X + pop yh + pop yl + ret +; @end + + + + + + diff --git a/avr/modules/uart_hw/lowlevel_uart1.asm b/avr/modules/uart_hw/lowlevel_uart1.asm new file mode 100644 index 0000000..b4dc76b --- /dev/null +++ b/avr/modules/uart_hw/lowlevel_uart1.asm @@ -0,0 +1,135 @@ +; *************************************************************************** +; 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. * +; *************************************************************************** + + +.dseg +; uartHw_TtyOn1Interface: .byte UART_HW_IFACE_SIZE + + + +.cseg + + + +; --------------------------------------------------------------------------- +; @routine UART_HW_Uart1_StartRx @global +; +; @clobbers none + +UART_HW_Uart1_StartRx: + lds r16, UCSR1B + sbr r16, (1<