avr: started working on hw interface for uart0.

This commit is contained in:
Martin Preuss
2025-02-26 21:00:09 +01:00
parent 8968f14122
commit bebc4c1b0d
5 changed files with 509 additions and 21 deletions

View File

@@ -16,7 +16,7 @@
; PB0 2 13 PA0 ATTN0 ; PB0 2 13 PA0 ATTN0
; PB1 3 12 PA1 TXD0 (UART0) ; PB1 3 12 PA1 TXD0 (UART0)
; /RESET PB3 4 11 PA2 RXD0 (UART0) ; /RESET PB3 4 11 PA2 RXD0 (UART0)
; LED PB2 5 10 PA3 ATTN1 ; LED PB2 5 10 PA3
; 1-wire PA7 6 9 PA4 RXD1 (UART1) [SCK, PRG] ; 1-wire PA7 6 9 PA4 RXD1 (UART1) [SCK, PRG]
; [MOSI,PRG] SDA (I2C) PA6 7 8 PA5 TXD1 (UART1) [MISO, PRG] ; [MOSI,PRG] SDA (I2C) PA6 7 8 PA5 TXD1 (UART1) [MISO, PRG]
; ------- ; -------
@@ -51,33 +51,18 @@
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; COM module ; COM module
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
.equ COM_DATA_DDR = DDRA
.equ COM_DATA_INPUT = PINA
.equ COM_DATA_OUTPUT = PORTA
.equ COM_DATA_PIN = PORTA2
.equ COM_ATTN_DDR = DDRA .equ COM_ATTN_DDR = DDRA
.equ COM_ATTN_INPUT = PINA .equ COM_ATTN_INPUT = PINA
.equ COM_ATTN_OUTPUT = PORTA .equ COM_ATTN_OUTPUT = PORTA
.equ COM_ATTN_PIN = PORTA0 .equ COM_ATTN_PIN = PORTA0
.equ COM_IRQ_ADDR_ATTN = PCMSK0 .equ COM_IRQ_ADDR_ATTN = PCMSK0
.equ COM_IRQ_BIT_ATTN = PCINT0 ; bit 7 in PCMSK0 .equ COM_IRQ_BIT_ATTN = PCINT0 ; bit 0 in PCMSK0
.equ COM_IRQ_GIFR_ATTN = PCIF0 .equ COM_IRQ_GIFR_ATTN = PCIF0
.equ COM_IRQ_GIMSK_ATTN = PCIE0 .equ COM_IRQ_GIMSK_ATTN = PCIE0
; ---------------------------------------------------------------------------
; LCD module
.equ LCD_TWI_ADDRESS = 0x3c
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; 1-Wire Master ; 1-Wire Master
; ;

View File

@@ -3,12 +3,13 @@
<gwbuild> <gwbuild>
<extradist> <extradist>
comonuart0.asm
defs.asm defs.asm
init_uart1.asm
lowlevel.asm lowlevel.asm
lowlevel_uart0.asm
lowlevel_uart1.asm lowlevel_uart1.asm
msglevel_recv.asm m_lowlevel_uart.asm
msglevel_send.asm ttyonuart1.asm
</extradist> </extradist>
</gwbuild> </gwbuild>

View File

@@ -0,0 +1,366 @@
; ***************************************************************************
; 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 COMONUART0_IFACENUM = 1
.dseg
comOnUart0_iface: .byte UART_HW_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Init @global
;
; @clobbers Y (R16, R17, X)
ComOnUart0_Init:
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall UART_HW_Interface_Init ; (R16, R17, X)
rcall UART_HW_Uart0_Init ; (R16, R17, X)
ldi r16, COMONUART0_IFACENUM
std Y+NET_IFACE_OFFS_IFACENUM, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Periodically @global
;
; @clobbers R16, Y
ComOnUart0_Periodically:
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
inc r16
breq ComOnUart0_Periodically_l1
std Y+NET_IFACE_OFFS_READTIMER, r16
ComOnUart0_Periodically_l1:
ldd r16, Y+NET_IFACE_OFFS_WRITETIMER
inc r16
breq ComOnUart0_Periodically_l2
std Y+NET_IFACE_OFFS_WRITETIMER, r16
ComOnUart0_Periodically_l2:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_RxCharIsr @global @isr
;
; @clobbers none
ComOnUart0_RxCharIsr:
push r15
in r15, SREG
push r16
push r17
push r18
push r24
push r25
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall UART_HW_Uart0_RxCharIsr ; (R16, R17, R18, R24, R25, X)
pop yh
pop yl
pop xh
pop xl
pop r25
pop r24
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_TxUdreIsr @global @isr
;
; @clobbers none
ComOnUart0_TxUdreIsr:
push r15
in r15, SREG
push r16
push r17
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall UART_HW_Uart0_TxUdreIsr ; (R16, R17, X)
pop yh
pop yl
pop xh
pop xl
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_TxCharIsr @global @isr
;
; @clobbers none
ComOnUart0_TxCharIsr:
push r15
in r15, SREG
push r16
push r17
push r18
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall UART_HW_Uart0_TxCharIsr ; (R16, R17, R18, X)
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Run @global
;
; @clobbers all
ComOnUart0_Run:
push r15
in r15, SREG
cli
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0RunWriteModes
rcall comOnUart0RunReadModes
pop r15
out SREG, r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWriteModes
;
; @clobbers all, !Y
comOnUart0RunWriteModes:
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE ; handle write functions
cpi r16, UART_HW_WRITEMODE_IDLE
breq comOnUart0RunWriteIdle
cpi r16, UART_HW_WRITEMODE_WRITING
breq comOnUart0RunWriting
cpi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
breq comOnUart0RunWaitBufferEmpty
cpi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
breq comOnUart0RunWriteBufferEmpty
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunIdle
;
; @clobbers
comOnUart0RunWriteIdle:
ldd r16, Y+NET_IFACE_OFFS_WRITETIMER
cpi r16, TTYONUART1_MSG_INTERVAL ; wait a bit between messages
brcs comOnUart0RunWriteIdle_end
rcall NET_Interface_GetNextOutgoingMsgNum ; (R17, R18, X)
brcc comOnUart0RunWriteIdle_end
rcall NET_Buffer_Locate ; (R17)
brcc comOnUart0RunWriteIdle_end
rcall ComOnUart0_SendBuffer ; (R16, R17)
comOnUart0RunWriteIdle_end:
ret
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWriting
;
; @clobbers
comOnUart0RunWriting:
; TODO: check for timeout etc.
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWaitBufferEmpty
;
; @clobbers none
comOnUart0RunWaitBufferEmpty:
; TODO: check for timeout etc.
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWriteBufferEmpty
;
; @clobbers R16, R17, X
comOnUart0RunWriteBufferEmpty:
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
ldi r17, 0xff
cp r16, r17
breq comOnUart0RunWriteBufferEmpty_setIdle
std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r17
rcall NET_Buffer_ReleaseByNum ; (R16, X)
comOnUart0RunWriteBufferEmpty_setIdle:
rcall UART_HW_Uart0_StopTx ; disable transceiver and interrupts (R16)
ldi r16, UART_HW_WRITEMODE_IDLE
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW ; increment packets counter
rcall NET_Interface_IncCounter16 ; (R24, R25)
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunReadModes
;
; @clobbers all, !Y
comOnUart0RunReadModes:
ldd r16, Y+UART_HW_IFACE_OFFS_READMODE ; handle read functions
cpi r16, UART_HW_READMODE_IDLE
breq comOnUart0RunReadIdle ; (R16, R17, R24, R25, X)
cpi r16, UART_HW_READMODE_READING
breq comOnUart0RunReading ; (none)
cpi r16, UART_HW_READMODE_SKIPPING
breq comOnUart0RunSkipping ; (R16)
cpi r16, UART_HW_READMODE_MSGRECEIVED
breq comOnUart0RunMsgReceived ; (R16, R17, R18, R24, R25)
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunReadIdle
;
; @clobbers R16 (R17, R24, R25, X)
comOnUart0RunReadIdle:
ldd r16, Y+UART_HW_IFACE_OFFS_READBUFNUM
cpi r16, 0xff
brne comOnUart0RunReadIdle_enterReading
rcall NET_Buffer_Alloc ; (R16, R17, X)
brcc comOnUart0RunReadIdle_noBuf
rcall UART_HW_Interface_SetReadBuffer ; (R17)
comOnUart0RunReadIdle_enterReading:
ldi r16, UART_HW_READMODE_READING
std Y+UART_HW_IFACE_OFFS_READMODE, r16
rcall UART_HW_Uart0_StartRx ; R16
ret
comOnUart0RunReadIdle_noBuf:
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunReading
;
; @clobbers none
comOnUart0RunReading:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunSkipping
;
; @clobbers R16
comOnUart0RunSkipping:
sbis COM_ATTN_INPUT, COM_ATTN_PIN ; ATTN low?
rjmp comOnUart0RunSkipping_end ; yes, jmp
; ATTN ishigh, skipped message finished
ldi r16, UART_HW_READMODE_IDLE
std Y+UART_HW_IFACE_OFFS_READMODE, r16
comOnUart0RunSkipping_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunMsgReceived
;
; @clobbers R16 (R17, R18, R24, R25)
comOnUart0RunMsgReceived:
ldd r16, Y+UART_HW_IFACE_OFFS_READBUFNUM
cpi r16, 0xff
breq comOnUart0RunMsgReceived_end
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
brcs comOnUart0RunMsgReceived_enterIdle
comOnUart0RunMsgReceived_overrun: ; reset/reuse current buffer
rcall NET_Buffer_Locate
rcall UART_HW_Interface_SetReadBuffer ; (R17)
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
comOnUart0RunMsgReceived_enterIdle:
ldi r16, 0xff
std Y+UART_HW_IFACE_OFFS_READBUFNUM, r16
ldi r16, UART_HW_READMODE_IDLE
std Y+UART_HW_IFACE_OFFS_READMODE, r16
comOnUart0RunMsgReceived_end:
ret
; @end

View File

@@ -0,0 +1,136 @@
; ***************************************************************************
; 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_Uart0_Init @global
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
; @clobbers R16, R17, X
UART_HW_Uart0_Init:
M_UART_HW_Uart_Init 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_StartRx @global
;
; @clobbers R16
UART_HW_Uart0_StartRx:
M_UART_HW_Uart_StartRx 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_StopRx @global
;
; @clobbers R16
UART_HW_Uart0_StopRx:
M_UART_HW_Uart_StopRx 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_StartTx @global
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
; @clobbers R16
UART_HW_Uart0_StartTx:
M_UART_HW_Uart_StartTx 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_StopTx @global
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
; @clobbers R16
UART_HW_Uart0_StopTx:
M_UART_HW_Uart_StopTx 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_Flush
;
; Flush receiption buffer.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16
UART_HW_Uart0_Flush:
M_UART_HW_Uart_Flush 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_RxCharIsr @global
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16 (R17, R18, R24, R25, X)
UART_HW_Uart0_RxCharIsr:
M_UART_HW_Uart_RxCharIsr 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_TxUdreIsr @global
;
; Handler for UDRE1 interrupt called when TX data register is empty.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16, R17, X
UART_HW_Uart0_TxUdreIsr:
M_UART_HW_Uart_TxUdreIsr 0
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_Uart0_TxCharIsr @global
;
; Handler for TXC1 interrupt called when a last byte has been completely sent and
; the data register is empty.
;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16
UART_HW_Uart0_TxCharIsr:
M_UART_HW_Uart_TxCharIsr 0
ret
; @end

View File

@@ -122,7 +122,7 @@ UART_HW_Uart1_TxUdreIsr:
; @routine UART_HW_Uart1_TxCharIsr @global ; @routine UART_HW_Uart1_TxCharIsr @global
; ;
; Handler for TXC1 interrupt called when a last byte has been completely sent and ; Handler for TXC1 interrupt called when a last byte has been completely sent and
; the data register is empty.. ; the data register is empty.
; ;
; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE) ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16 ; @clobbers R16