From 3633bb03fcc9c281aeca45c459a5999af34cb396 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Wed, 15 Jan 2025 00:12:06 +0100 Subject: [PATCH] avr: started working on hardware-based UART module. --- avr/modules/uart_hw/0BUILD | 11 +++++ avr/modules/uart_hw/defs.asm | 49 ++++++++++++++++++++++ avr/modules/uart_hw/lowlevel.asm | 72 ++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 avr/modules/uart_hw/0BUILD create mode 100644 avr/modules/uart_hw/defs.asm create mode 100644 avr/modules/uart_hw/lowlevel.asm diff --git a/avr/modules/uart_hw/0BUILD b/avr/modules/uart_hw/0BUILD new file mode 100644 index 0000000..443b708 --- /dev/null +++ b/avr/modules/uart_hw/0BUILD @@ -0,0 +1,11 @@ + + + + + + defs.asm + + + + + diff --git a/avr/modules/uart_hw/defs.asm b/avr/modules/uart_hw/defs.asm new file mode 100644 index 0000000..96ab2d0 --- /dev/null +++ b/avr/modules/uart_hw/defs.asm @@ -0,0 +1,49 @@ +; *************************************************************************** +; 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. * +; *************************************************************************** + + +.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_IFACE_OFFS_STATE = 0 + +.equ UART_HW_IFACE_OFFS_READBUFFERNUM = 1 ; num of buffer currently read +.equ UART_HW_IFACE_OFFS_READBUFFERPOS = 2 ; current pos in readbuffer +.equ UART_HW_IFACE_OFFS_READBUFFERLEFT = 3 ; bytes left to read for current message + +.equ UART_HW_IFACE_OFFS_WRITEBUFFERID = 4 ; num of buffer currently written from to network +.equ UART_HW_IFACE_OFFS_WRITEBUFFERPOS = 5 ; current pos in writebuffer +.equ UART_HW_IFACE_OFFS_WRITEBUFFERLEFT= 6 ; bytes left to write for current message + + +.equ UART_HW_IFACE_OFFS_RINGBUF_USED = 7 ; ringbuffer for incoming chars +.equ UART_HW_IFACE_OFFS_RINGBUF_RDPOS = 8 +.equ UART_HW_IFACE_OFFS_RINGBUF_WRPOS = 9 + +.equ UART_HW_IFACE_OFFS_MSGIDBUF_USED = 10 ; ringbuffer for ids of outbound messages +.equ UART_HW_IFACE_OFFS_MSGIDBUF_RDPOS = 11 +.equ UART_HW_IFACE_OFFS_MSGIDBUF_WRPOS = 12 +.equ UART_HW_IFACE_OFFS_RINGBUF_DATA = 13 +.equ UART_HW_IFACE_OFFS_MSGIDBUF_DATA = UART_HW_IFACE_OFFS_RINGBUF_DATA+UART_HW_IFACE_READBUF_SIZE + +.equ UART_HW_IFACE_SIZE = UART_HW_IFACE_OFFS_MSGIDBUF_DATA+UART_HW_IFACE_MSGIDBUF_SIZE + + +.equ UART_HW_IFACE_FN_ISR_CHECKATTN = 0 +.equ UART_HW_IFACE_FN_ISR_READCHAR = 1 +.equ UART_HW_IFACE_FN_ISR_WRITECHAR = 2 +.equ UART_HW_IFACE_FN_COUNT = 3 + diff --git a/avr/modules/uart_hw/lowlevel.asm b/avr/modules/uart_hw/lowlevel.asm new file mode 100644 index 0000000..ff2f527 --- /dev/null +++ b/avr/modules/uart_hw/lowlevel.asm @@ -0,0 +1,72 @@ +; *************************************************************************** +; 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_InitInterface @global +; +; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE) +; @param Z pointer to IFACE jump table for the given interface +; @clobbers R16, R17, X + +UART_HW_InitInterface: + mov xl, yl + mov xh, yh + ldi r17, UART_HW_IFACE_SIZE + 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 + ret +; @end + + + +; --------------------------------------------------------------------------- +; @routine UART_HW_JumpToFunction @global +; +; @param R16 function number (see @ref UART_HW_IFACE_FN_ISR_CHECKATTN) +; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE) +; @param Z pointer to IFACE jump table for the given interface +; @clobbers R16, R17, X + +UART_HW_JumpToFunction: + cpi r16, UART_HW_IFACE_FN_COUNT + brcc UART_HW_JumpToFunction_ret ; return with cleared CFLAG + mov xl, zl + mov xh, zh + add xl, r16 + adc xh, xl + sub xh, xl + push xl + push xh +UART_HW_JumpToFunction_ret: + ret ; indirect jump to address we just pushed onto the stack or return on error +; @end + + + + + +