avr: more work on uart_hw.
This commit is contained in:
173
avr/modules/uart_hw/buffers.asm
Normal file
173
avr/modules/uart_hw/buffers.asm
Normal file
@@ -0,0 +1,173 @@
|
||||
; ***************************************************************************
|
||||
; 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
|
||||
|
||||
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:
|
||||
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_FixedBuffers_Init @global
|
||||
;
|
||||
; @clobbers R16, R17, X
|
||||
|
||||
UART_HW_FixedBuffers_Init:
|
||||
ldi xl, LOW(uartHw_buffers)
|
||||
ldi xh, HIGH(uartHw_buffers)
|
||||
m_fixedbuf_init UART_HW_FIXEDBUFFERS_SIZE, UART_HW_FIXEDBUFFERS_NUM
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_FixedBuffers_Alloc @global
|
||||
;
|
||||
; @return CFLAG set if buffer available, cleared otherwise
|
||||
; @return r16 buffer num
|
||||
; @return X pointer to start of buffer
|
||||
; @clobbers R16, R17, X
|
||||
|
||||
UART_HW_FixedBuffers_Alloc:
|
||||
ldi xl, LOW(uartHw_buffers)
|
||||
ldi xh, HIGH(uartHw_buffers)
|
||||
m_fixedbuf_reserve UART_HW_FIXEDBUFFERS_SIZE, UART_HW_FIXEDBUFFERS_NUM
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_FixedBuffers_Release @global
|
||||
;
|
||||
; @param X pointer to start of buffers
|
||||
; @clobbers R16
|
||||
|
||||
UART_HW_FixedBuffers_Release:
|
||||
m_fixedbuf_release
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_FixedBuffers_Locate
|
||||
;
|
||||
; Get position of a given buffer.
|
||||
;
|
||||
; CAVE: need to change this routine if UART_HW_FIXEDBUFFERS_SIZE is changed!
|
||||
;
|
||||
; @return CFLAG set if okay, cleared on error
|
||||
; @return X points to start of buffer with the given num
|
||||
; @param r16 buffer num (0-max)
|
||||
; @clobbers r16
|
||||
|
||||
UART_HW_FixedBuffers_Locate:
|
||||
cpi r16, UART_HW_FIXEDBUFFERS_NUM
|
||||
brcc UART_HW_FixedBuffers_Locate_end ; out of range
|
||||
mov xh, r16 ; * 256
|
||||
clr xl
|
||||
lsr xh ; *128
|
||||
ror xl
|
||||
lsr xh ; *64
|
||||
ror xl
|
||||
lsr xh ; *32
|
||||
ror xl
|
||||
ldi r16, LOW(uartHw_buffers)
|
||||
add xl, r16
|
||||
ldi r16, HIGH(uartHw_buffers)
|
||||
adc xh, r16
|
||||
sec
|
||||
UART_HW_FixedBuffers_Locate_end:
|
||||
ret
|
||||
; @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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
.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_STATE_OFF = 0
|
||||
.equ UART_HW_STATE_IDLE = 1
|
||||
.equ UART_HW_STATE_READING = 2
|
||||
@@ -18,26 +26,28 @@
|
||||
.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_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_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_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_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_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_MSGIDBUF_DATA = UART_HW_IFACE_OFFS_RINGBUF_DATA+UART_HW_IFACE_READBUF_SIZE
|
||||
|
||||
.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
|
||||
|
||||
|
||||
@@ -8,19 +8,49 @@
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_InitInterface @global
|
||||
; @routine UART_HW_Init @global
|
||||
;
|
||||
; Initializes buffers.
|
||||
;
|
||||
; @clobbers R16, R17, X, Y
|
||||
|
||||
UART_HW_Init:
|
||||
ldi xh, HIGH(uartHwDataBegin)
|
||||
ldi xl, LOW(uartHwDataBegin)
|
||||
clr r16
|
||||
ldi r17, (uartHwDataEnd-uartHwDataBegin)
|
||||
rcall Utils_FillSram
|
||||
|
||||
rcall UART_HW_FixedBuffers_Init
|
||||
|
||||
ldi r16, UART_HW_MSGNUMINBUF_SIZE
|
||||
ldi yl, LOW(uartHw_ringBufferMsgNumIn)
|
||||
ldi yh, HIGH(uartHw_ringBufferMsgNumIn)
|
||||
rcall RingBufferY_Init
|
||||
|
||||
ldi r16, UART_HW_MSGNUMOUTBUF_SIZE
|
||||
ldi yl, LOW(uartHw_ringBufferMsgNumOut)
|
||||
ldi yh, HIGH(uartHw_ringBufferMsgNumOut)
|
||||
rcall RingBufferY_Init
|
||||
|
||||
sec
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_InterfaceInit @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:
|
||||
UART_HW_InterfaceInit:
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
ldi r17, UART_HW_IFACE_SIZE
|
||||
@@ -38,14 +68,49 @@ UART_HW_InitInterface:
|
||||
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
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_InterfaceAddReadByte
|
||||
;
|
||||
; @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:
|
||||
push yl
|
||||
push yh
|
||||
adiw yh:yl, UART_HW_IFACE_OFFS_RINGBUF_MAX
|
||||
rcall RingBufferY_WriteByte ; R17, R18, X
|
||||
pop yh
|
||||
pop yl
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_InterfaceGetNextReadByte
|
||||
;
|
||||
; @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:
|
||||
push yl
|
||||
push yh
|
||||
adiw yh:yl, UART_HW_IFACE_OFFS_RINGBUF_MAX
|
||||
rcall RingBufferY_ReadByte ; R17, R18, X
|
||||
pop yh
|
||||
pop yl
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
168
avr/modules/uart_hw/lowlevel_tty.asm
Normal file
168
avr/modules/uart_hw/lowlevel_tty.asm
Normal file
@@ -0,0 +1,168 @@
|
||||
; ***************************************************************************
|
||||
; 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_TtyOn1_Init @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
|
||||
; @clobbers R16, R17, X
|
||||
|
||||
UART_HW_TtyOn1_Init:
|
||||
rcall UART_HW_InitInterface
|
||||
|
||||
; set baudrate
|
||||
.if clock == 8000000
|
||||
ldi r16, 25 ; (19.2Kb/s at 8MHz)
|
||||
ldi r17, 0
|
||||
.endif
|
||||
|
||||
.if clock == 1000000
|
||||
ldi r16, 3 ; (19.2Kb/s at 1MHz)
|
||||
ldi r17, 0
|
||||
.endif
|
||||
|
||||
out UBRR1H, r17
|
||||
out UBRR1L, r16
|
||||
|
||||
; set character format
|
||||
ldi r16, (1<<USBS1)|(3<<UCSZ10)
|
||||
out UCSR1C, r16
|
||||
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_TtyOn1_StartRx @global
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
UART_HW_TtyOn1_StartRx:
|
||||
; enable RX complete interrupt
|
||||
sbi UCSR1B, RXCIE1
|
||||
; enable receive
|
||||
sbi UCSR1B, RXEN1
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_TtyOn1_StopRx @global
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
UART_HW_TtyOn1_StopRx:
|
||||
; disable RX complete interrupt
|
||||
cbi UCSR1B, RXCIE1
|
||||
; disable receive
|
||||
cbi UCSR1B, RXEN1
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_TtyOn1_StartTx @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
|
||||
; @clobbers none
|
||||
|
||||
UART_HW_TtyOn1_StartTx:
|
||||
; enable TX data register empty interrupt
|
||||
sbi UCSR1B, UDRIE1
|
||||
; enable transmit
|
||||
sbi UCSR1B, TXEN1
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_TtyOn1_StopTx @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
|
||||
; @clobbers none
|
||||
|
||||
UART_HW_TtyOn1_StopTx:
|
||||
; enable TX data register empty interrupt
|
||||
cbi UCSR1B, UDRIE1
|
||||
; enable transmit
|
||||
cbi UCSR1B, TXEN1
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_TtyOn1_RxCharIsr @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
|
||||
; @clobbers R16 (R17, R18, X)
|
||||
|
||||
UART_HW_TtyOn1_RxCharIsr:
|
||||
sbis UCSR1A, RXC1
|
||||
rjmp UART_HW_TtyOn1_RxCharIsr_end ; no data
|
||||
in r16, UDR1
|
||||
rcall UART_HW_InterfaceAddReadByte ; (R17, R18, X)
|
||||
UART_HW_TtyOn1_RxCharIsr_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_HW_TtyOn1_TxCharIsr @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
|
||||
; @clobbers R16, X
|
||||
|
||||
UART_HW_TtyOn1_TxCharIsr:
|
||||
sbis UCSR1A,UDRE1
|
||||
rjmp UART_HW_TtyOn1_TxCharIsr_end ; not ready
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFFERNUM
|
||||
cpi r16, 0xff
|
||||
breq UART_HW_TtyOn1_TxCharIsr_end ; no current write buffer
|
||||
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFFERLEFT
|
||||
tst r16
|
||||
breq UART_HW_TtyOn1_TxCharIsr_end ; nothing to send
|
||||
dec r16
|
||||
std Y+UART_HW_IFACE_OFFS_WRITEBUFFERLEFT, r16
|
||||
ldd xl, Y+UART_HW_IFACE_OFFS_WRITEBUFFERPTR
|
||||
ldd xh, Y+UART_HW_IFACE_OFFS_WRITEBUFFERPTR+1
|
||||
ld r16, X+
|
||||
std Y+UART_HW_IFACE_OFFS_WRITEBUFFERPTR, xl
|
||||
std Y+UART_HW_IFACE_OFFS_WRITEBUFFERPTR+1, xh
|
||||
out UDR1, r16
|
||||
UART_HW_TtyOn1_TxCharIsr_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user