avr: t03 now at least writes tty message once!

This commit is contained in:
Martin Preuss
2025-02-11 01:13:00 +01:00
parent 0790ac0dea
commit 351ab57d62
7 changed files with 202 additions and 563 deletions

View File

@@ -270,8 +270,8 @@ initModules:
.include "modules/uart_hw/lowlevel.asm" .include "modules/uart_hw/lowlevel.asm"
.include "modules/uart_hw/m_lowlevel_uart.asm" .include "modules/uart_hw/m_lowlevel_uart.asm"
.include "modules/uart_hw/lowlevel_uart1.asm" .include "modules/uart_hw/lowlevel_uart1.asm"
.include "modules/uart_hw/msglevel_recv.asm" ;.include "modules/uart_hw/msglevel_recv.asm"
.include "modules/uart_hw/msglevel_send.asm" ;.include "modules/uart_hw/msglevel_send.asm"
.include "modules/uart_hw/ttyonuart1.asm" .include "modules/uart_hw/ttyonuart1.asm"
@@ -293,8 +293,14 @@ maybeSendDeviceMsg:
push r16 push r16
adiw xh:xl, 1 adiw xh:xl, 1
rcall writeDeviceMsg rcall writeDeviceMsg
sbiw xh:xl, 1
pop r16 pop r16
rcall UART_HW_InterfaceAddOutgoingMsgNum push r16
rcall TtyOnUart1_SendBuffer
pop r16
brcs maybeSendDeviceMsg_resetCounter
rcall UART_HW_FixedBuffers_ReleaseByNum ; (R16, X)
rjmp maybeSendDeviceMsg_end
; reset counter ; reset counter
maybeSendDeviceMsg_resetCounter: maybeSendDeviceMsg_resetCounter:
ldi r24, LOW(SEND_DEVICE_EVERY) ldi r24, LOW(SEND_DEVICE_EVERY)
@@ -302,6 +308,7 @@ maybeSendDeviceMsg_resetCounter:
maybeSendDeviceMsg_storeCounter: maybeSendDeviceMsg_storeCounter:
sts deviceCounter, r24 sts deviceCounter, r24
sts deviceCounter+1, r25 sts deviceCounter+1, r25
maybeSendDeviceMsg_end:
ret ret

View File

@@ -17,18 +17,16 @@
.equ UART_HW_BUFFER_IFACENUM0_BIT = 0 .equ UART_HW_BUFFER_IFACENUM0_BIT = 0
.equ UART_HW_MODE_READMASK = 0x0f .equ UART_HW_READMODE_OFF = 0
.equ UART_HW_MODE_WRITEMASK = 0xf0 .equ UART_HW_READMODE_IDLE = 1
.equ UART_HW_READMODE_READING = 2
.equ UART_HW_READMODE_SKIPPING = 3
.equ UART_HW_MODE_OFF = 0 .equ UART_HW_WRITEMODE_OFF = 0
.equ UART_HW_MODE_IDLE = 1 .equ UART_HW_WRITEMODE_IDLE = 1
.equ UART_HW_MODE_READING = 2 .equ UART_HW_WRITEMODE_WRITING = 2
.equ UART_HW_MODE_SKIPPING = 3 .equ UART_HW_WRITEMODE_WAITBUFFEREMPTY = 3
.equ UART_HW_WRITEMODE_WRITEBUFFEREMPTY = 4
.equ UART_HW_MODE_W_IDLE = 0
.equ UART_HW_MODE_WRITING = 16
.equ UART_HW_MODE_WAITBUFFEREMPTY = 17
.equ UART_HW_MODE_WRITEBUFFEREMPTY = 18
.equ UART_HW_STATUS_UNDERRUN_BIT = 0 .equ UART_HW_STATUS_UNDERRUN_BIT = 0
@@ -39,51 +37,28 @@
.equ UART_HW_IFACE_OFFS_IFACENUM = 0 ; interface number (put into received messages) .equ UART_HW_IFACE_OFFS_IFACENUM = 0 ; interface number (put into received messages)
.equ UART_HW_IFACE_OFFS_MODE = 1 .equ UART_HW_IFACE_OFFS_STATUS = 1
.equ UART_HW_IFACE_OFFS_STATUS = 2 .equ UART_HW_IFACE_OFFS_READTIMER = 2
.equ UART_HW_IFACE_OFFS_READTIMER = 3 .equ UART_HW_IFACE_OFFS_WRITETIMER = 3
.equ UART_HW_IFACE_OFFS_WRITETIMER = 4 .equ UART_HW_IFACE_OFFS_ERR_OVRLOW = 4
.equ UART_HW_IFACE_OFFS_ERR_OVR = 5 .equ UART_HW_IFACE_OFFS_ERR_OVRHIGH = 5
.equ UART_HW_IFACE_OFFS_ERR_CONTENT = 6 .equ UART_HW_IFACE_OFFS_ERR_CONTENTLOW = 6
.equ UART_HW_IFACE_OFFS_ERR_CONTENTHIGH = 7
; ringbuffer for incoming chars .equ UART_HW_IFACE_OFFS_READMODE = 8
.equ UART_HW_IFACE_OFFS_READBUF = 7 .equ UART_HW_IFACE_OFFS_READBUFNUM = 9
.equ UART_HW_IFACE_OFFS_READBUF_MAX = UART_HW_IFACE_OFFS_READBUF .equ UART_HW_IFACE_OFFS_READBUFPOSLOW = 10
.equ UART_HW_IFACE_OFFS_READBUF_USED = UART_HW_IFACE_OFFS_READBUF+1 .equ UART_HW_IFACE_OFFS_READBUFPOSHIGH = 11
.equ UART_HW_IFACE_OFFS_READBUF_RDPOS = UART_HW_IFACE_OFFS_READBUF+2 .equ UART_HW_IFACE_OFFS_READBUFUSED = 12
.equ UART_HW_IFACE_OFFS_READBUF_WRPOS = UART_HW_IFACE_OFFS_READBUF+3 .equ UART_HW_IFACE_OFFS_READBUFLEFT = 13
.equ UART_HW_IFACE_OFFS_READBUF_DATA = UART_HW_IFACE_OFFS_READBUF+4 ; UART_HW_IFACE_READBUF_SIZE bytes
; ringbuffer for outgoing chars .equ UART_HW_IFACE_OFFS_WRITEMODE = 14
.equ UART_HW_IFACE_OFFS_WRITEBUF = UART_HW_IFACE_OFFS_READBUF_DATA+UART_HW_IFACE_READBUF_SIZE .equ UART_HW_IFACE_OFFS_WRITEBUFNUM = 15
.equ UART_HW_IFACE_OFFS_WRITEBUF_MAX = UART_HW_IFACE_OFFS_WRITEBUF .equ UART_HW_IFACE_OFFS_WRITEBUFPOSLOW = 16
.equ UART_HW_IFACE_OFFS_WRITEBUF_USED = UART_HW_IFACE_OFFS_WRITEBUF+1 .equ UART_HW_IFACE_OFFS_WRITEBUFPOSHIGH = 17
.equ UART_HW_IFACE_OFFS_WRITEBUF_RDPOS = UART_HW_IFACE_OFFS_WRITEBUF+2 .equ UART_HW_IFACE_OFFS_WRITEBUFUSED = 18
.equ UART_HW_IFACE_OFFS_WRITEBUF_WRPOS = UART_HW_IFACE_OFFS_WRITEBUF+3 .equ UART_HW_IFACE_OFFS_WRITEBUFLEFT = 19
.equ UART_HW_IFACE_OFFS_WRITEBUF_DATA = UART_HW_IFACE_OFFS_WRITEBUF+4
; ringbuffer for outgoing messages .equ UART_HW_IFACE_SIZE = UART_HW_IFACE_OFFS_WRITEBUFLEFT+1
.equ UART_HW_IFACE_OFFS_OUTMSGBUF = UART_HW_IFACE_OFFS_WRITEBUF_DATA+UART_HW_IFACE_WRITEBUF_SIZE
.equ UART_HW_IFACE_OFFS_OUTMSGBUF_MAX = UART_HW_IFACE_OFFS_OUTMSGBUF
.equ UART_HW_IFACE_OFFS_OUTMSGBUF_USED = UART_HW_IFACE_OFFS_OUTMSGBUF+1
.equ UART_HW_IFACE_OFFS_OUTMSGBUF_RDPOS = UART_HW_IFACE_OFFS_OUTMSGBUF+2
.equ UART_HW_IFACE_OFFS_OUTMSGBUF_WRPOS = UART_HW_IFACE_OFFS_OUTMSGBUF+3
.equ UART_HW_IFACE_OFFS_OUTMSGBUF_DATA = UART_HW_IFACE_OFFS_OUTMSGBUF+4
; ref to recv buffer
.equ UART_HW_IFACE_OFFS_READMSG = UART_HW_IFACE_OFFS_OUTMSGBUF_DATA+UART_HW_IFACE_OUTMSGBUF_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
; ref to transmit buffer
.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

@@ -37,8 +37,6 @@ 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
@@ -57,156 +55,65 @@ UART_HW_InterfaceInit:
ldi r17, UART_HW_IFACE_SIZE ldi r17, UART_HW_IFACE_SIZE
clr r16 clr r16
rcall Utils_FillSram ; (R17, X) rcall Utils_FillSram ; (R17, X)
; reset ringbuffer for recvd chars
m_ringbuffer_y_reset UART_HW_IFACE_OFFS_READBUF_MAX, \
UART_HW_IFACE_OFFS_READBUF_USED, \
UART_HW_IFACE_OFFS_READBUF_RDPOS, \
UART_HW_IFACE_OFFS_READBUF_WRPOS, \
UART_HW_IFACE_OFFS_READBUF_DATA
ldi r16, UART_HW_IFACE_READBUF_SIZE
std Y+UART_HW_IFACE_OFFS_READBUF_MAX, r16
; reset ringbuffer for chars to transmit
m_ringbuffer_y_reset UART_HW_IFACE_OFFS_WRITEBUF_MAX, \
UART_HW_IFACE_OFFS_WRITEBUF_USED, \
UART_HW_IFACE_OFFS_WRITEBUF_RDPOS, \
UART_HW_IFACE_OFFS_WRITEBUF_WRPOS, \
UART_HW_IFACE_OFFS_WRITEBUF_DATA
ldi r16, UART_HW_IFACE_WRITEBUF_SIZE
std Y+UART_HW_IFACE_OFFS_WRITEBUF_MAX, r16
; reset ringbuffer for messages to be sent
m_ringbuffer_y_reset UART_HW_IFACE_OFFS_OUTMSGBUF_MAX, \
UART_HW_IFACE_OFFS_OUTMSGBUF_USED, \
UART_HW_IFACE_OFFS_OUTMSGBUF_RDPOS, \
UART_HW_IFACE_OFFS_OUTMSGBUF_WRPOS, \
UART_HW_IFACE_OFFS_OUTMSGBUF_DATA
ldi r16, UART_HW_IFACE_OUTMSGBUF_SIZE
std Y+UART_HW_IFACE_OFFS_OUTMSGBUF_MAX, r16
ldi r16, 0xff ldi r16, 0xff
std Y+UART_HW_IFACE_OFFS_READMSG_BUFNUM, r16 std Y+UART_HW_IFACE_OFFS_READBUFNUM, r16
std Y+UART_HW_IFACE_OFFS_WRITEMSG_BUFNUM, r16 std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, UART_HW_READMODE_OFF
std Y+UART_HW_IFACE_OFFS_READMODE, r16
ldi r16, UART_HW_WRITEMODE_IDLE
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
ret ret
; @end ; @end
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine UART_HW_InterfaceWriteToReadBuffer @global ; @routine UART_HW_Interface_SetReadBuffer @global
; ;
; @return CFLAG on success, cleared on error ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
; @param r16 byte to write ; @param r16 read buffer number
; @param Y pointer to start of interface data ; @param X read buffer pos
; @clobbers R17, R18, X ; @clobbers R17
UART_HW_InterfaceWriteToReadBuffer: UART_HW_Interface_SetReadBuffer:
push yl std Y+UART_HW_IFACE_OFFS_READBUFNUM, r16
push yh adiw xh:xl, 1
adiw yh:yl, UART_HW_IFACE_OFFS_READBUF std Y+UART_HW_IFACE_OFFS_READBUFPOSLOW, xl
rcall uartHwRingBufferWriteGuarded ; R17, R18, X std Y+UART_HW_IFACE_OFFS_READBUFPOSHIGH, xh
pop yh sbiw xh:xl, 1
pop yl clr r17
std Y+UART_HW_IFACE_OFFS_READBUFUSED, r17
std Y+UART_HW_IFACE_OFFS_READBUFLEFT, r17
ret ret
; @end ; @end
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine UART_HW_InterfaceReadFromReadBuffer @global ; @routine UART_HW_Interface_SetWriteBuffer @global
; ;
; @return CFLAG on success, cleared on error ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_STATE)
; @return R16 byte read ; @param r16 write buffer number
; @param Y pointer to start of interface data ; @param X write buffer pos
; @clobbers R17, R18, X ; @clobbers r17
UART_HW_InterfaceReadFromReadBuffer: UART_HW_Interface_SetWriteBuffer:
push yl std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r16
push yh adiw xh:xl, 1
adiw yh:yl, UART_HW_IFACE_OFFS_READBUF std Y+UART_HW_IFACE_OFFS_WRITEBUFPOSLOW, xl ; begin of msg (dest addr byte)
rcall uartHwRingBufferReadGuarded ; R17, R18, X std Y+UART_HW_IFACE_OFFS_WRITEBUFPOSHIGH, xh
pop yh adiw xh:xl, 1
pop yl ld r17, X ; payload length byte
ret sbiw xh:xl, 2 ; back to start of buffer
; @end inc r17
inc r17
inc r17
std Y+UART_HW_IFACE_OFFS_WRITEBUFUSED, r17
; --------------------------------------------------------------------------- std Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT, r17
; @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 uartHwRingBufferWriteGuarded ; 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 uartHwRingBufferReadGuarded ; R17, R18, X
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_InterfaceAddOutgoingMsgNum @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_InterfaceAddOutgoingMsgNum:
push yl
push yh
adiw yh:yl, UART_HW_IFACE_OFFS_OUTMSGBUF
rcall uartHwRingBufferWriteGuarded ; R17, R18, X
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine UART_HW_InterfaceGetNextOutgoingMsgNum @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_InterfaceGetNextOutgoingMsgNum:
push yl
push yh
adiw yh:yl, UART_HW_IFACE_OFFS_OUTMSGBUF
rcall uartHwRingBufferReadGuarded ; R17, R18, X
pop yh
pop yl
ret ret
; @end ; @end
@@ -214,64 +121,3 @@ UART_HW_InterfaceGetNextOutgoingMsgNum:
; ---------------------------------------------------------------------------
; @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

@@ -1,168 +0,0 @@
; ***************************************************************************
; 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

View File

@@ -109,7 +109,7 @@ UART_HW_Uart1_RxCharIsr:
; Handler for UDRE1 interrupt called when TX data register is empty. ; 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) ; @param Y pointer to interface data in SRAM (see @ref UART_HW_IFACE_OFFS_MODE)
; @clobbers R16, (R17, R18, X) ; @clobbers R16, R17, X
UART_HW_Uart1_TxUdreIsr: UART_HW_Uart1_TxUdreIsr:
M_UART_HW_Uart_TxUdreIsr 1 M_UART_HW_Uart_TxUdreIsr 1
@@ -125,7 +125,7 @@ UART_HW_Uart1_TxUdreIsr:
; 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, (R17, R18, X) ; @clobbers R16
UART_HW_Uart1_TxCharIsr: UART_HW_Uart1_TxCharIsr:
M_UART_HW_Uart_TxCharIsr 1 M_UART_HW_Uart_TxCharIsr 1

View File

@@ -138,6 +138,7 @@ l_end_%:
; @clobbers R16 (R17, R18, X) ; @clobbers R16 (R17, R18, X)
.macro M_UART_HW_Uart_RxCharIsr .macro M_UART_HW_Uart_RxCharIsr
#if 0
lds r16, UCSR@0A ; check for errors lds r16, UCSR@0A ; check for errors
andi r16, (1<<FE@0) | (1<<DOR@0) | (1<<UPE@0) andi r16, (1<<FE@0) | (1<<DOR@0) | (1<<UPE@0)
breq l_recv_% ; no error, receive next char breq l_recv_% ; no error, receive next char
@@ -160,6 +161,7 @@ l_overrun_%:
l_setStatusAndEnd_%: l_setStatusAndEnd_%:
std Y+UART_HW_IFACE_OFFS_STATUS, r16 std Y+UART_HW_IFACE_OFFS_STATUS, r16
l_end_%: l_end_%:
#endif
.endmacro .endmacro
; @end ; @end
@@ -172,24 +174,53 @@ l_end_%:
; ;
; @param %0 UART number ("0" for UART0) ; @param %0 UART number ("0" for UART0)
; @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, (R17, R18, X) ; @clobbers R16, R17, X
.macro M_UART_HW_Uart_TxUdreIsr .macro M_UART_HW_Uart_TxUdreIsr
lds r16, UCSR@0A lds r16, UCSR@0A
sbrs r16,UDRE@0 sbrs r16,UDRE@0
rjmp l_end_% ; not ready rjmp l_disable_irq_% ; not ready
rcall UART_HW_InterfaceReadFromWriteBuffer ; (R17, R18, X)
brcs l_send_% ; got a byte, go send
; check write mode
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE
cpi r16, UART_HW_WRITEMODE_WRITING
brne l_disable_irq_% ; not in writing mode
; check whether we have an active write buffer
ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
cpi r16, 0xff
breq l_disable_irq_% ; no buffer
; check whether there is data in the buffer to send
ldd r17, Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT ; r17=bytes left
tst r17
breq l_disable_irq_% ; nothing left to write
; get read ptr, read byte, inc read ptr, store ptr and bytesLeft
ldd xl, Y+UART_HW_IFACE_OFFS_WRITEBUFPOSLOW
ldd xh, Y+UART_HW_IFACE_OFFS_WRITEBUFPOSHIGH
ld r16, X+ ; r16=byte to write
std Y+UART_HW_IFACE_OFFS_WRITEBUFPOSLOW, xl
std Y+UART_HW_IFACE_OFFS_WRITEBUFPOSHIGH, xh
dec r17
std Y+UART_HW_IFACE_OFFS_WRITEBUFLEFT, r17
; send byte, reset write timer
sts UDR@0, r16
clr r16
std Y+UART_HW_IFACE_OFFS_WRITETIMER, r16 ; reset write timer
; still bytes left to write?
tst r17
brne l_end_%
ldi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16 ; change mode to WAITBUFFEREMPTY
l_disable_irq_%:
; disable further DRE1 interrupts ; disable further DRE1 interrupts
lds r16, UCSR@0B lds r16, UCSR@0B
cbr r16, (1<<UDRIE@0) ; disable TX data register empty interrupt cbr r16, (1<<UDRIE@0) ; disable TX data register empty interrupt
sts UCSR@0B, r16 sts UCSR@0B, r16
rjmp l_end_%
l_send_%:
sts UDR@0, r16
clr r16
std Y+UART_HW_IFACE_OFFS_WRITETIMER, r16 ; reset write timer
l_end_%: l_end_%:
.endmacro .endmacro
; @end ; @end
@@ -200,21 +231,27 @@ l_end_%:
; @macro M_UART_HW_Uart_TxCharIsr ; @macro M_UART_HW_Uart_TxCharIsr
; ;
; Handler for TXCn interrupt called when a last byte has been completely sent and ; Handler for TXCn interrupt called when a last byte has been completely sent and
; the data register is empty.. ; the data register is empty.
; ;
; @param %0 UART number ("0" for UART0) ; @param %0 UART number ("0" for UART0)
; @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, (R17, R18, X) ; @clobbers R16
.macro M_UART_HW_Uart_TxCharIsr .macro M_UART_HW_Uart_TxCharIsr
; disable further TXC1 interrupts ; disable further TXC1 interrupts
lds r16, UCSR@0B lds r16, UCSR@0B
cbr r16, (1<<TXC@0) ; disable TXC1 interrupt cbr r16, (1<<TXC@0) ; disable TXC1 interrupt
sts UCSR@0B, r16 sts UCSR@0B, r16
; set underrun status (TODO: maybe change this later)
ldd r16, Y+UART_HW_IFACE_OFFS_STATUS ; set underrun error ; check write mode
ori r16, (1<<UART_HW_STATUS_UNDERRUN_BIT) ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE
std Y+UART_HW_IFACE_OFFS_STATUS, r16 cpi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
brne l_end_%
; change write mode to WRITEBUFFEREMPTY
ldi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
l_end_%:
.endmacro .endmacro
; @end ; @end

View File

@@ -33,8 +33,6 @@ TtyOnUart1_Init:
rcall UART_HW_Uart1_Init ; (R16, R17, X) rcall UART_HW_Uart1_Init ; (R16, R17, X)
ldi r16, TTYONUART1_IFACENUM ldi r16, TTYONUART1_IFACENUM
std Y+UART_HW_IFACE_OFFS_IFACENUM, r16 std Y+UART_HW_IFACE_OFFS_IFACENUM, r16
ldi r16, UART_HW_MODE_IDLE | UART_HW_MODE_W_IDLE ; start in full idle mode
std Y+UART_HW_IFACE_OFFS_MODE, r16
ret ret
; @end ; @end
@@ -106,19 +104,17 @@ TtyOnUart1_TxUdreIsr:
in r15, SREG in r15, SREG
push r16 push r16
push r17 push r17
push r18 push xl
push xl push xh
push xh push yl
push yl push yh
push yh ldi yl, LOW(ttyOnUart1_iface)
ldi yl, LOW(ttyOnUart1_iface) ldi yh, HIGH(ttyOnUart1_iface)
ldi yh, HIGH(ttyOnUart1_iface) rcall UART_HW_Uart1_TxUdreIsr ; (R16, R17, X)
rcall UART_HW_Uart1_TxUdreIsr ; (R16, R17, R18, X) pop yh
pop yh pop yl
pop yl pop xh
pop xh pop xl
pop xl
pop r18
pop r17 pop r17
pop r16 pop r16
out SREG, r15 out SREG, r15
@@ -160,17 +156,46 @@ TtyOnUart1_TxCharIsr:
TtyOnUart1_SendBuffer:
push r15
in r15, SREG
cli
ldd r17, Y+UART_HW_IFACE_OFFS_WRITEMODE
cpi r17, UART_HW_WRITEMODE_IDLE
breq TtyOnUart1_SendBuffer_setBuffer
pop r15
out SREG, r15
clc
ret
TtyOnUart1_SendBuffer_setBuffer:
rcall UART_HW_Interface_SetWriteBuffer
ldi r17, UART_HW_WRITEMODE_WRITING
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r17
rcall UART_HW_Uart1_StartTx ; (R16)
pop r15
out SREG, r15
sec
ret
; @end
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine TtyOnUart1_Run @global ; @routine TtyOnUart1_Run @global
; ;
; @clobbers all ; @clobbers all
TtyOnUart1_Run: TtyOnUart1_Run:
ldi yl, LOW(ttyOnUart1_iface) push r15
ldi yh, HIGH(ttyOnUart1_iface) in r15, SREG
cli
ldi yl, LOW(ttyOnUart1_iface)
ldi yh, HIGH(ttyOnUart1_iface)
rcall ttyOnUart1RunWriteModes rcall ttyOnUart1RunWriteModes
rcall ttyOnUart1RunReadModes ; rcall ttyOnUart1RunReadModes
pop r15
out SREG, r15
ret ret
; @end ; @end
@@ -182,49 +207,26 @@ TtyOnUart1_Run:
; @clobbers all, !Y ; @clobbers all, !Y
ttyOnUart1RunWriteModes: ttyOnUart1RunWriteModes:
ldd r16, Y+UART_HW_IFACE_OFFS_MODE ; handle write functions ldd r16, Y+UART_HW_IFACE_OFFS_WRITEMODE ; handle write functions
andi r16, UART_HW_MODE_WRITEMASK cpi r16, UART_HW_WRITEMODE_WRITING
cpi r16, UART_HW_MODE_W_IDLE
breq ttyOnUart1RunWIdle
cpi r16, UART_HW_MODE_WRITING
breq ttyOnUart1RunWriting breq ttyOnUart1RunWriting
cpi r16, UART_HW_MODE_WAITBUFFEREMPTY cpi r16, UART_HW_WRITEMODE_WAITBUFFEREMPTY
breq ttyOnUart1RunWaitBufferEmpty breq ttyOnUart1RunWaitBufferEmpty
cpi r16, UART_HW_MODE_WRITEBUFFEREMPTY cpi r16, UART_HW_WRITEMODE_WRITEBUFFEREMPTY
breq ttyOnUart1RunWriteBufferEmpty breq ttyOnUart1RunWriteBufferEmpty
ret ret
; @end ; @end
; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunWIdle
;
; @clobbers all, !Y
ttyOnUart1RunWIdle:
rcall UART_HW_InterfaceGetNextOutgoingMsgNum ; (R17, R18, X)
brcc ttyOnUart1RunWIdle_end
rcall UART_HW_Interface_WriteSetBuffer ; (r16, r19, X)
ldd r16, Y+UART_HW_IFACE_OFFS_MODE
cbr r16, UART_HW_MODE_WRITEMASK
ori r16, UART_HW_MODE_WRITING
std Y+UART_HW_IFACE_OFFS_MODE, r16
rcall ttyOnUart1RunWriting ; fill ringbuffer
rcall UART_HW_Uart1_StartTx ; enable transceiver and interrupts
ttyOnUart1RunWIdle_end:
ret
; @end
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunWriting ; @routine ttyOnUart1RunWriting
; ;
; @clobbers all, !Y ; @clobbers
ttyOnUart1RunWriting: ttyOnUart1RunWriting:
rjmp UART_HW_Interface_RunWriting ; (R16, R17, R18, R19, R20, R21, X) ; TODO: check for timeout etc.
ret
; @end ; @end
@@ -232,19 +234,11 @@ ttyOnUart1RunWriting:
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunWaitBufferEmpty ; @routine ttyOnUart1RunWaitBufferEmpty
; ;
; @clobbers all, !Y ; @clobbers none
ttyOnUart1RunWaitBufferEmpty: ttyOnUart1RunWaitBufferEmpty:
ldd r16, Y+UART_HW_IFACE_OFFS_STATUS ; TODO: check for timeout etc.
sbrs r16, UART_HW_STATUS_UNDERRUN_BIT ; underrun bit set? ret
ret ; return if bit still clear
cbr r16, (1<<UART_HW_STATUS_UNDERRUN_BIT)
std Y+UART_HW_IFACE_OFFS_STATUS, r16
ldd r16, Y+UART_HW_IFACE_OFFS_MODE ; change mode to WRITEBUFFEREMPTY and go handle that
cbr r16, UART_HW_MODE_WRITEMASK
ori r16, UART_HW_MODE_WRITEBUFFEREMPTY
std Y+UART_HW_IFACE_OFFS_MODE, r16
rjmp ttyOnUart1RunWriteBufferEmpty
; @end ; @end
@@ -252,15 +246,20 @@ ttyOnUart1RunWaitBufferEmpty:
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunWriteBufferEmpty ; @routine ttyOnUart1RunWriteBufferEmpty
; ;
; @clobbers all, !Y ; @clobbers R16, R17, X
ttyOnUart1RunWriteBufferEmpty: ttyOnUart1RunWriteBufferEmpty:
ldd r16, Y+UART_HW_IFACE_OFFS_MODE ldd r16, Y+UART_HW_IFACE_OFFS_WRITEBUFNUM
cbr r16, UART_HW_MODE_WRITEMASK ldi r17, 0xff
ori r16, UART_HW_MODE_W_IDLE cp r16, r17
std Y+UART_HW_IFACE_OFFS_MODE, r16 breq ttyOnUart1RunWriteBufferEmpty_setIdle
rcall UART_HW_Uart1_StopTx ; disable transceiver and interrupts std Y+UART_HW_IFACE_OFFS_WRITEBUFNUM, r17
rjmp ttyOnUart1RunWIdle rcall UART_HW_FixedBuffers_ReleaseByNum ; (R16, X)
ttyOnUart1RunWriteBufferEmpty_setIdle:
rcall UART_HW_Uart1_StopTx ; disable transceiver and interrupts (R16)
ldi r16, UART_HW_WRITEMODE_IDLE
std Y+UART_HW_IFACE_OFFS_WRITEMODE, r16
ret
; @end ; @end
@@ -271,65 +270,8 @@ ttyOnUart1RunWriteBufferEmpty:
; @clobbers all, !Y ; @clobbers all, !Y
ttyOnUart1RunReadModes: ttyOnUart1RunReadModes:
ldd r16, Y+UART_HW_IFACE_OFFS_MODE ; handle read functions
andi r16, UART_HW_MODE_READMASK
cpi r16, UART_HW_MODE_IDLE
breq ttyOnUart1RunIdle
cpi r16, UART_HW_MODE_READING
breq ttyOnUart1RunReading
cpi r16, UART_HW_MODE_SKIPPING
breq ttyOnUart1RunSkipping
ret ret
; @end ; @end
; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunIdle
;
; @clobbers all, !Y
ttyOnUart1RunIdle:
rcall UART_HW_Uart1_StartRx
ldd r16, Y+UART_HW_IFACE_OFFS_MODE
cbr r16, UART_HW_MODE_READMASK
ori r16, UART_HW_MODE_READING
std Y+UART_HW_IFACE_OFFS_MODE, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunReading
;
; @clobbers all, !Y
ttyOnUart1RunReading:
rjmp UART_HW_Interface_RunRead ; (R16, R17, R18, R18, R19, R20, R21, X)
; @end
; ---------------------------------------------------------------------------
; @routine ttyOnUart1RunSkipping
;
; @clobbers all, !Y
ttyOnUart1RunSkipping:
rcall UART_HW_Uart1_Flush ; (R16)
ldd r16, Y+UART_HW_IFACE_OFFS_READTIMER
cpi r16, TTYONUART1_SKIPTIME
brcs ttyOnUart1RunSkipping_end
ldd r16, Y+UART_HW_IFACE_OFFS_MODE
cbr r16, UART_HW_MODE_READMASK
ori r16, UART_HW_MODE_READING
std Y+UART_HW_IFACE_OFFS_MODE, r16
ttyOnUart1RunSkipping_end:
ret
; @end