Files
aqhomecontrol/avr/modules/uart_hw2/comonuart0.asm
2025-07-06 12:21:41 +02:00

848 lines
22 KiB
NASM

; ***************************************************************************
; 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. *
; ***************************************************************************
#ifndef AVR_MODULES_UART_HW2_COMONUART0_H
#define AVR_MODULES_UART_HW2_COMONUART0_H
.dseg
comOnUart0_iface: .byte UART_HW2_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Init @global
;
; @clobbers R16, R17, Y (X)
ComOnUart0_Init:
rcall comOnUart0StopRx
rcall comOnUart0StopTx
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, 0xff
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, UART_HW2_MODE_IDLE
std Y+UART_HW2_IFACE_OFFS_MODE, r16
clr r16
std Y+NET_IFACE_OFFS_IFACENUM, r16
rcall comOnUart0SetAttnInput
sbi COM_IRQ_ADDR_ATTN0, COM_IRQ_BIT_ATTN0 ; enable pin change irq for ATTN line
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_ATTN0)
outr GIMSK, r16
ldi r16, (1<<COM_IRQ_GIFR_ATTN0) ; clear pending irq by writing 1 to ATTN bit
outr GIFR, r16
; set baudrate
.if clock == 8000000
ldi r16, 25 ; (19.2Kb/s at 8MHz)
ldi r17, 0
.endif
.if clock == 1000000
ldi r16, 2 ; (19.2Kb/s at 1MHz)
ldi r17, 0
.endif
outr UBRR0H, r17
outr UBRR0L, r16
; set character format
ldi r16, (1<<USBS0)|(3<<UCSZ00)
outr UCSR0C, r16
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Periodically @global
;
; @clobbers R16, Y
ComOnUart0_Periodically:
push r15
in r15, SREG
cli
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall NET_Interface_Periodically
ldd r16, Y+UART_HW2_IFACE_OFFS_MODECOUNTER
inc r16
breq ComOnUart0_Periodically_end
std Y+UART_HW2_IFACE_OFFS_MODECOUNTER, r16
ComOnUart0_Periodically_end:
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0SetMode
;
; @param R16 mode
; @clobbers R17
comOnUart0SetMode:
push r15
in r15, SREG
cli
ldd r17, Y+UART_HW2_IFACE_OFFS_MODE
cp r16, r17
breq comOnUart0SetMode_end
std Y+UART_HW2_IFACE_OFFS_MODE, r16
clr r17
std Y+UART_HW2_IFACE_OFFS_MODECOUNTER, r17
comOnUart0SetMode_end:
out SREG, r15
pop r15
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0StartReading
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, X
comOnUart0StartReading:
mov xl, yl
mov xh, yh
adiw xh:xl, UART_HW2_IFACE_OFFS_BUFFER
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
ldi r16, UART_HW2_BUFFER_SIZE-1
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16
clr r16
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r16
ldi r16, UART_HW2_MODE_READING
rcall comOnUart0SetMode ; (R17)
rcall comOnUart0StartRx ; should be the last call here
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0StartWriting
;
; @param Y pointer to interface data in SRAM
; @param R16 buffer number
; @return CFLAG set if writing started, cleared otherwise
; @clobbers R16, R17, X, Z (R22, R24, R25)
comOnUart0StartWriting:
push r15
inr r15, SREG
cli
rcall comOnUart0StartWriting_noIrq
brcc comOnUart0StartWriting_clc
outr SREG, r15
pop r15
sec
ret
comOnUart0StartWriting_clc:
outr SREG, r15
pop r15
clc
ret
comOnUart0StartWriting_noIrq:
rcall comOnUart0AcquireAttn ; (R22)
brcc comOnUart0StartWriting_ebusy
; copy buffer
rcall NET_Buffer_Locate ; (R17)
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
adiw xh:xl, NETMSG_OFFS_MSGLEN+1
ld r17, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN+1
subi r17, -3 ; add dest addr, msglen, crc
; TODO: check size!
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
; copy into IFACE buffer
mov zl, yl
mov zh, yh
adiw zh:zl, UART_HW2_IFACE_OFFS_BUFFER ; dest
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, zl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, zh
adiw xh:xl, 1 ; src (skip buffer header)
comOnUart0StartWriting_loop:
ld r16, X+
st Z+, r16
dec r17
brne comOnUart0StartWriting_loop
ldi r16, UART_HW2_MODE_WRITING
rcall comOnUart0SetMode ; (R17)
rcall comOnUart0StartTx ; should be the last call here (R16)
sec
rjmp comOnUart0StartWriting_end
comOnUart0StartWriting_ebusy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
comOnUart0StartWriting_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_Run @global
;
; @clobbers all
ComOnUart0_Run:
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
ComOnUart0_Run_loop:
push r16 ; current state
rcall comOnUart0RunMode ; (all but Y)
pop r17 ; previous state (pop from r16 into r17)
; read new state
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
cp r16, r17
brne ComOnUart0_Run_loop ; state changed, run again
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunMode
;
; @clobbers all
comOnUart0RunMode:
cpi r16, UART_HW2_MODE_NUM
brcs ComOnUart0_Run_jump
ldi r16, UART_HW2_MODE_IDLE ; unknown mode, set to idle
rcall comOnUart0SetMode ; (R17)
ret
ComOnUart0_Run_jump:
ldi zl, LOW(comOnUart0ModeJumpTable)
ldi zh, HIGH(comOnUart0ModeJumpTable)
add zl, r16
adc zh, r16
sub zh, r16
ijmp
comOnUart0ModeJumpTable:
rjmp comOnUart0RunIdle
rjmp comOnUart0RunReading
rjmp comOnUart0RunSkipping
rjmp comOnUart0RunMsgReceived
rjmp comOnUart0RunWriting
rjmp comOnUart0RunWaitBufferEmpty
rjmp comOnUart0RunMsgSent
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunIdle
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R24, R25, X, Z
comOnUart0RunIdle:
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcc comOnUart0RunIdle_end ; no outmsg in queue
rcall comOnUart0StartWriting ; (R16, R17, R22, R24, R25, X, Z)
brcc comOnUart0RunIdle_end
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
comOnUart0RunIdle_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunReading
;
; @param Y pointer to interface data in SRAM
; @clobbers none
comOnUart0RunReading:
; TODO: check for timeout
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunSkipping
;
; @param Y pointer to interface data in SRAM
; @clobbers R16 (R17)
comOnUart0RunSkipping:
rcall comOnUart0IsAttnLow ; (none)
brcs comOnUart0RunSkipping_end ; still low
ldi r16, UART_HW2_MODE_IDLE ; is high now, leave skipping mode
rcall comOnUart0SetMode ; (R17)
comOnUart0RunSkipping_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunMsgReceived
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25)
comOnUart0RunMsgReceived:
mov xl, yl
mov xh, yh
adiw xh:xl, UART_HW2_IFACE_OFFS_BUFFER
mov zl, xl ; Z=buffer in IFACE
mov zh, xh
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc comOnUart0RunMsgReceived_econtent
; msg valid, alloc buffer
rcall NET_Buffer_Alloc ; X=buffer, R16=bufnum (R16, R17, X)
brcc comOnUart0RunMsgReceived_enobuf
mov r18, r16 ; buffer num
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
adiw xh:xl, 1 ; skip buffer header
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFUSED ; always is at least 2 here
comOnUart0RunMsgReceived_copyLoop:
ld r16, Z+
st X+, r16
dec r17
brne comOnUart0RunMsgReceived_copyLoop
mov r16, r18 ; buffer num
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
brcc comOnUart0RunMsgReceived_enoadd
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
rjmp comOnUart0RunMsgReceived_setIdleAndEnd
comOnUart0RunMsgReceived_enoadd:
rcall NET_Buffer_ReleaseByNum
rjmp comOnUart0RunMsgReceived_enobuf
comOnUart0RunMsgReceived_enobuf:
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rjmp comOnUart0RunMsgReceived_err
comOnUart0RunMsgReceived_econtent:
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
comOnUart0RunMsgReceived_err:
rcall NET_Interface_IncCounter16 ; (R24, R25)
comOnUart0RunMsgReceived_setIdleAndEnd:
ldi r16, UART_HW2_MODE_IDLE
rcall comOnUart0SetMode ; (R17)
comOnUart0RunMsgReceived_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers none
comOnUart0RunWriting:
; TODO: check for timeout
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWaitBufferEmpty
;
; @clobbers none
comOnUart0RunWaitBufferEmpty:
; TODO: check for timeout etc.
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers R16 (R17, R22, R24, R25, X)
comOnUart0RunMsgSent:
ldd r16, Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM
rcall NET_Buffer_ReleaseByNum ; (R16, X)
ldi r16, 0xff
std Y+UART_HW2_IFACE_OFFS_WRITEBUFNUM, r16
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ldi r16, UART_HW2_MODE_IDLE
rcall comOnUart0SetMode ; (R17)
rcall comOnUart0SetAttnInput ; release ATTN (none)
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least high for a short period (R22)
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0AcquireAttn
;
; Set ATTN low only if it is high.
; @return CFLAG set if ATTN acquired (including waiting time), cleared otherwise
;
; @clobbers R22
comOnUart0AcquireAttn:
rcall comOnUart0IsAttnLow ; (none)
brcc comOnUart0AcquireAttn_isHigh
clc
rjmp comOnUart0AcquireAttn_end
comOnUart0AcquireAttn_isHigh:
; set ATTN low
rcall comOnUart0SetAttnLow ; (none)
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
sec
comOnUart0AcquireAttn_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0StartRx
;
; @clobbers R16
comOnUart0StartRx:
inr r16, UCSR0B
sbr r16, (1<<RXCIE0) | (1<<RXEN0) ; enable RX complete interrupt, enable receive
outr UCSR0B, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0StopRx
;
; @clobbers R16
comOnUart0StopRx:
inr r16, UCSR0B
cbr r16, (1<<RXCIE0 | (1<<RXEN0)) ; disable RX complete interrupt, disable receive
outr UCSR0B, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0StartTx
;
; @clobbers R16
comOnUart0StartTx:
inr r16, UCSR0A
cbr r16, (1<<TXC0) ; clear TXCn interrupt
outr UCSR0A, r16
inr r16, UCSR0B
sbr r16, (1<<UDRIE0) | (1<<TXCIE0) | (1<<TXEN0) ; enable TX UDRE and TXC0 interrupt, enable transceive
outr UCSR0B, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0StopTx
;
; @clobbers R16
comOnUart0StopTx:
inr r16, UCSR0B
cbr r16, (1<<UDRIE0) | (1<<TXCIE0) | (1<<TXEN0) ; disable TX UDRE and TXC0 interrupt, enable transceive
outr UCSR0B, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0SetAttnInput
;
; Set ATTN line as input (making it effectively HIGH due to pull-up resistor on
; the line)
;
; @clobbers none
comOnUart0SetAttnInput:
cbi COM_ATTN0_DDR, COM_ATTN0_PIN ; set ATTN as input
.ifdef COM_ATTN0_PUE
; cbi COM_ATTN0_PUE, COM_ATTN_PIN ; disable pullup on ATTN
.else
cbi COM_ATTN0_OUTPUT, COM_ATTN0_PIN ; disable pullup on ATTN
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0SetAttnLow
;
; Set ATTN line low.
;
; @clobbers none
comOnUart0SetAttnLow:
sbi COM_ATTN0_DDR, COM_ATTN0_PIN ; set ATTN as output
cbi COM_ATTN0_OUTPUT, COM_ATTN0_PIN ; set ATTN low
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0IsAttnLow
;
; Check whether ATTN is low
;
; @return CFLAG set if ATTN1 is low
; @clobbers none
comOnUart0IsAttnLow:
clc
sbis COM_ATTN0_INPUT, COM_ATTN0_PIN ; ATTN high?
sec ; no
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 comOnUart0RxCharIsr ; (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 comOnUart0TxUdreIsr ; (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 yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0TxCharIsr ; (R16, R17)
pop yh
pop yl
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0AttnChangeIsr @global @isr
;
; @clobbers none
ComOnUart0_AttnChangeIsr:
push r15
in r15, SREG
rcall ComOnUart0_HandleAttnChange
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine ComOnUart0_HandleAttnChange @global
;
; @clobbers none
ComOnUart0_HandleAttnChange:
push r16
push r17
push xl
push xh
push yl
push yh
ldi yl, LOW(comOnUart0_iface)
ldi yh, HIGH(comOnUart0_iface)
rcall comOnUart0ActOnAttn ; (R16, R17, X)
pop yh
pop yl
pop xh
pop xl
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0ActOnAttn @global
;
; @param Y pointer to interface data in SRAM
; @clobbers R16 (R17, X)
comOnUart0ActOnAttn:
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
rcall comOnUart0IsAttnLow ; (none)
brcc comOnUart0ActOnAttn_attnHigh
; ATTN low
cpi r16, UART_HW2_MODE_IDLE
brne comOnUart0ActOnAttn_end ; not idle
rcall comOnUart0StartReading ; (R16, R17, X)
rjmp comOnUart0ActOnAttn_end
; ATTN high
comOnUart0ActOnAttn_attnHigh:
cpi r16, UART_HW2_MODE_SKIPPING
brne comOnUart0ActOnAttn_end
ldi r16, UART_HW2_MODE_IDLE ; leave skipping mode
rcall comOnUart0SetMode ; (R17)
comOnUart0ActOnAttn_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0RxCharIsr @global
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R18, R24, R25, X
comOnUart0RxCharIsr:
; check for errors
inr r16, UCSR0A ; check for errors
andi r16, (1<<FE0) | (1<<DOR0) | (1<<UPE0)
brne comOnUart0RxCharIsr_hwerr
inr r16, UCSR0A ; read status: data available?
sbrs r16, RXC0
rjmp comOnUart0RxCharIsr_end ; jmp if no data
inr r16, UDR0 ; r16=received char
; check mode
ldd r17, Y+UART_HW2_IFACE_OFFS_MODE
cpi r17, UART_HW2_MODE_READING
brne comOnUart0RxCharIsr_overrun
; store char
ldd xl, Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW
ldd xh, Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH
st X+, r16 ; last byte written
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
; handle counters
ldd r18, Y+UART_HW2_IFACE_OFFS_BUFUSED
inc r18
std Y+UART_HW2_IFACE_OFFS_BUFUSED, r18
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFLEFT
dec r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
breq comOnUart0RxCharIsr_complete
; check msg size
cpi r18, 2
brne comOnUart0RxCharIsr_end
; determine msg size
inc r16 ; last byte was payload length, add byte for crc
cp r16, r17 ; compare remaining length against remaining space
brcc comOnUart0RxCharIsr_emsgsize ; msg too long
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16 ; set new number of bytes left
tst r16
brne comOnUart0RxCharIsr_end ; jmp if still bytes left to receive
comOnUart0RxCharIsr_complete:
rcall comOnUart0StopRx
ldi r16, UART_HW2_MODE_MSGRECEIVED
rcall comOnUart0SetMode ; (R17)
rjmp comOnUart0RxCharIsr_end
comOnUart0RxCharIsr_hwerr:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
rjmp comOnUart0RxCharIsr_err
comOnUart0RxCharIsr_overrun:
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rjmp comOnUart0RxCharIsr_err
comOnUart0RxCharIsr_emsgsize:
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
comOnUart0RxCharIsr_err:
rcall NET_Interface_IncCounter16 ; (R24, R25)
rcall comOnUart0StopRx ; (R16)
ldi r16, UART_HW2_MODE_SKIPPING ; skipping mode is left after ATTN becomes high again
rcall comOnUart0SetMode ; (R17)
comOnUart0RxCharIsr_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0TxUdreIsr @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
comOnUart0TxUdreIsr:
inr r16, UCSR0A
sbrs r16, UDRE0
rjmp comOnUart0TxUdreIsr_disable_irq ; not ready
; check bytes left
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFLEFT
tst r17
breq comOnUart0TxUdreIsr_finished
; read byte
ldd xl, Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW
ldd xh, Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH
ld r16, X+
std Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW, xl
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
; send byte
outr UDR0, r16 ; send byte
; decreased counter
dec r17
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
brne comOnUart0TxUdreIsr_end ; still bytes left to send, jump
comOnUart0TxUdreIsr_finished:
ldi r16, UART_HW2_MODE_WAITBUFFEREMPTY
rcall comOnUart0SetMode ; (R17)
comOnUart0TxUdreIsr_disable_irq:
; disable further DRE interrupts
inr r16, UCSR0B
cbr r16, (1<<UDRIE0) ; disable TX data register empty interrupt
outr UCSR0B, r16
comOnUart0TxUdreIsr_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine comOnUart0TxCharIsr @global
;
; Handler for TXC0 interrupt called when the 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, R17
comOnUart0TxCharIsr:
; disable further TXC interrupts
inr r16, UCSR0B
cbr r16, (1<<TXCIE0) ; disable TXC1 interrupt
outr UCSR0B, r16
rcall comOnUart0StopTx ; (R16)
ldi r16, UART_HW2_MODE_MSGSENT
rcall comOnUart0SetMode ; (R17)
ret
; @end
#endif ; AVR_MODULES_UART_HW2_COMONUART0_H