uart_hw2: basically works, but skips messages.
This commit is contained in:
@@ -466,7 +466,7 @@ comOnUart0StopRx:
|
||||
; @clobbers R16
|
||||
|
||||
comOnUart0StartTx:
|
||||
lds r16, UCSR0A
|
||||
inr r16, UCSR0A
|
||||
cbr r16, (1<<TXC0) ; clear TXCn interrupt
|
||||
outr UCSR0A, r16
|
||||
inr r16, UCSR0B
|
||||
@@ -639,7 +639,7 @@ ComOnUart0_TxCharIsr:
|
||||
; @clobbers none
|
||||
|
||||
|
||||
ComOnUart0AttnChangeIsr:
|
||||
ComOnUart0_AttnChangeIsr:
|
||||
push r15
|
||||
in r15, SREG
|
||||
rcall ComOnUart0_HandleAttnChange
|
||||
|
||||
@@ -27,6 +27,9 @@ comOnUart1_iface: .byte UART_HW2_IFACE_SIZE
|
||||
; @clobbers R16, R17, Y (X)
|
||||
|
||||
ComOnUart1_Init:
|
||||
rcall comOnUart1StopRx
|
||||
rcall comOnUart1StopTx
|
||||
|
||||
ldi yl, LOW(comOnUart1_iface)
|
||||
ldi yh, HIGH(comOnUart1_iface)
|
||||
rcall NET_Interface_Init ; (R16, R17, X)
|
||||
@@ -36,13 +39,23 @@ ComOnUart1_Init:
|
||||
std Y+UART_HW2_IFACE_OFFS_MODE, r16
|
||||
clr r16
|
||||
std Y+NET_IFACE_OFFS_IFACENUM, r16
|
||||
|
||||
rcall comOnUart1SetAttnInput
|
||||
|
||||
sbi COM_IRQ_ADDR_ATTN1, COM_IRQ_BIT_ATTN1 ; enable pin change irq for ATTN line
|
||||
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
.ifdef COM_ATTN1_PUE
|
||||
inr r16, COM_ATTN1_PUE
|
||||
cbr r16, (1<<COM_ATTN1_PIN)
|
||||
outr COM_ATTN1_PUE, r16
|
||||
.endif
|
||||
|
||||
inr r16, COM_IRQ_ADDR_ATTN1
|
||||
sbr r16, (1<<COM_IRQ_BIT_ATTN1) ; enable pin change irq for ATTN line
|
||||
outr COM_IRQ_ADDR_ATTN1, r16
|
||||
|
||||
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
sbr r16, (1<<COM_IRQ_GIMSK_ATTN1)
|
||||
outr GIMSK, r16
|
||||
ldi r16, (1<<COM_IRQ_GIFR_ATTN1) ; clear pending irq by writing 1 to ATTN bit
|
||||
ldi r16, (1<<COM_IRQ_GIFR_ATTN1) ; clear pending irq by writing 1 to ATTN bit
|
||||
outr GIFR, r16
|
||||
|
||||
; set baudrate
|
||||
@@ -210,6 +223,14 @@ comOnUart1StartWriting_end:
|
||||
; @clobbers all
|
||||
|
||||
ComOnUart1_Run:
|
||||
push r15
|
||||
inr r15, SREG
|
||||
cli
|
||||
rcall ComOnUart1_Run_noirq
|
||||
outr SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
ComOnUart1_Run_noirq:
|
||||
ldi yl, LOW(comOnUart1_iface)
|
||||
ldi yh, HIGH(comOnUart1_iface)
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
@@ -323,7 +344,7 @@ comOnUart1RunMsgReceived:
|
||||
brcc comOnUart1RunMsgReceived_enobuf
|
||||
mov r18, r16 ; buffer num
|
||||
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
|
||||
adiw xh:xl, 1
|
||||
adiw xh:xl, 1 ; skip buffer header
|
||||
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFUSED ; always is at least 2 here
|
||||
comOnUart1RunMsgReceived_copyLoop:
|
||||
ld r16, Z+
|
||||
@@ -396,7 +417,7 @@ comOnUart1RunMsgSent:
|
||||
ldi r16, UART_HW2_MODE_IDLE
|
||||
rcall comOnUart1SetMode ; (R17)
|
||||
rcall comOnUart1SetAttnInput ; release ATTN (none)
|
||||
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least for a short period high (R22)
|
||||
rcall Utils_WaitFor10MicroSecs ; make sure ATTN is at least high for a short period (R22)
|
||||
ret
|
||||
; @end
|
||||
|
||||
@@ -463,11 +484,11 @@ comOnUart1StopRx:
|
||||
; @clobbers R16
|
||||
|
||||
comOnUart1StartTx:
|
||||
lds r16, UCSR1A
|
||||
inr r16, UCSR1A
|
||||
cbr r16, (1<<TXC1) ; clear TXCn interrupt
|
||||
outr UCSR1A, r16
|
||||
inr r16, UCSR1B
|
||||
sbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; enable TX UDRE and TXC1 interrupt, enable transceive
|
||||
sbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; enable TX UDRE and TXC0 interrupt, enable transceive
|
||||
outr UCSR1B, r16
|
||||
ret
|
||||
; @end
|
||||
@@ -481,7 +502,7 @@ comOnUart1StartTx:
|
||||
|
||||
comOnUart1StopTx:
|
||||
inr r16, UCSR1B
|
||||
cbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; disable TX UDRE and TXC1 interrupt, enable transceive
|
||||
cbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; disable TX UDRE and TXC0 interrupt, enable transceive
|
||||
outr UCSR1B, r16
|
||||
ret
|
||||
; @end
|
||||
@@ -499,7 +520,7 @@ comOnUart1StopTx:
|
||||
comOnUart1SetAttnInput:
|
||||
cbi COM_ATTN1_DDR, COM_ATTN1_PIN ; set ATTN as input
|
||||
.ifdef COM_ATTN1_PUE
|
||||
; cbi COM_ATTN1_PUE, COM_ATTN_PIN ; disable pullup on ATTN
|
||||
; cbi COM_ATTN1_PUE, COM_ATTN_PIN ; disable pullup on ATTN
|
||||
.else
|
||||
cbi COM_ATTN1_OUTPUT, COM_ATTN1_PIN ; disable pullup on ATTN
|
||||
.endif
|
||||
@@ -636,7 +657,7 @@ ComOnUart1_TxCharIsr:
|
||||
; @clobbers none
|
||||
|
||||
|
||||
ComOnUart1AttnChangeIsr:
|
||||
ComOnUart1_AttnChangeIsr:
|
||||
push r15
|
||||
in r15, SREG
|
||||
rcall ComOnUart1_HandleAttnChange
|
||||
@@ -680,19 +701,19 @@ ComOnUart1_HandleAttnChange:
|
||||
; @clobbers R16 (R17, X)
|
||||
|
||||
comOnUart1ActOnAttn:
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
rcall comOnUart1IsAttnLow ; (none)
|
||||
brcc comOnUart1ActOnAttn_attnHigh
|
||||
; ATTN low
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
cpi r16, UART_HW2_MODE_IDLE
|
||||
brne comOnUart1ActOnAttn_end ; not idle
|
||||
rcall comOnUart1StartReading ; (R16, R17, X)
|
||||
rjmp comOnUart1ActOnAttn_end
|
||||
; ATTN high
|
||||
comOnUart1ActOnAttn_attnHigh:
|
||||
cpi r16, UART_HW2_MODE_SKIPPING
|
||||
cpi r16, UART_HW2_MODE_SKIPPING
|
||||
brne comOnUart1ActOnAttn_end
|
||||
ldi r16, UART_HW2_MODE_IDLE
|
||||
ldi r16, UART_HW2_MODE_IDLE ; leave skipping mode
|
||||
rcall comOnUart1SetMode ; (R17)
|
||||
comOnUart1ActOnAttn_end:
|
||||
ret
|
||||
@@ -723,7 +744,7 @@ comOnUart1RxCharIsr:
|
||||
; store char
|
||||
ldd xl, Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW
|
||||
ldd xh, Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH
|
||||
st X+, r16
|
||||
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
|
||||
@@ -792,7 +813,7 @@ comOnUart1TxUdreIsr:
|
||||
std Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH, xh
|
||||
; send byte
|
||||
outr UDR1, r16 ; send byte
|
||||
; decrease counter
|
||||
; decreased counter
|
||||
dec r17
|
||||
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
|
||||
brne comOnUart1TxUdreIsr_end ; still bytes left to send, jump
|
||||
@@ -813,7 +834,7 @@ comOnUart1TxUdreIsr_end:
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine comOnUart1TxCharIsr @global
|
||||
;
|
||||
; Handler for TXC1 interrupt called when the last byte has been completely sent and
|
||||
; 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)
|
||||
|
||||
@@ -39,5 +39,17 @@
|
||||
|
||||
|
||||
|
||||
; comOnUart1Init UART_HW2_FN_INIT =0
|
||||
; comOnUart1Fini UART_HW2_FN_FINI =1
|
||||
; comOnUart1StartRx UART_HW2_FN_STARTRX =2
|
||||
; comOnUart1StopRx UART_HW2_FN_STOPRX =3
|
||||
; comOnUart1StartTx UART_HW2_FN_STARTTX =4
|
||||
; comOnUart1StopTx UART_HW2_FN_STOPTX =5
|
||||
; comOnUart1AcquireAttn UART_HW2_FN_ACQATTN =6
|
||||
; comOnUart1SetAttnInput UART_HW2_FN_SETATTNINPUT =7
|
||||
; comOnUart1SetAttnLow UART_HW2_FN_SETATTNLOW =8
|
||||
; comOnUart1IsAttnLow UART_HW2_FN_ISATTNLOW =9
|
||||
|
||||
|
||||
#endif ; AVR_MODULES_UART_HW2_DEFS_H
|
||||
|
||||
|
||||
739
avr/modules/uart_hw2/ttyonuart1.asm
Normal file
739
avr/modules/uart_hw2/ttyonuart1.asm
Normal file
@@ -0,0 +1,739 @@
|
||||
; ***************************************************************************
|
||||
; 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_TTYONUART1_H
|
||||
#define AVR_MODULES_UART_HW2_TTYONUART1_H
|
||||
|
||||
|
||||
.equ TTYONUART1_SKIPTIME = 2
|
||||
|
||||
.equ TTYONUART_IFACE_OFFS_BEGIN = UART_HW2_IFACE_SIZE
|
||||
.equ TTYONUART_IFACE_OFFS_BUFFER2 = TTYONUART_IFACE_OFFS_BEGIN
|
||||
.equ TTYONUART_IFACE_SIZE = TTYONUART_IFACE_OFFS_BUFFER2+UART_HW2_BUFFER_SIZE
|
||||
|
||||
|
||||
.dseg
|
||||
|
||||
; ttyOnUart1_iface: .byte TTYONUART_IFACE_SIZE
|
||||
ttyOnUart1_iface: .byte UART_HW2_IFACE_SIZE
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine TtyOnUart1_Init @global
|
||||
;
|
||||
; @clobbers R16, R17, Y (X)
|
||||
|
||||
TtyOnUart1_Init:
|
||||
rcall comOnUart0StopRx
|
||||
rcall comOnUart0StopTx
|
||||
|
||||
ldi yl, LOW(ttyOnUart1_iface)
|
||||
ldi yh, HIGH(ttyOnUart1_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
|
||||
|
||||
; 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 UBRR1H, r17
|
||||
outr UBRR1L, r16
|
||||
|
||||
; set character format
|
||||
; ldi r16, (1<<USBS1)|(3<<UCSZ10)
|
||||
; outr UCSR1C, r16
|
||||
|
||||
ldi r16, (1<<UCSZ11) | (1<<UCSZ10) ; 1 stop bit, 8 databits
|
||||
outr UCSR1C, r16
|
||||
|
||||
; receiver always on!
|
||||
rcall ttyOnUart1StartRx
|
||||
sec
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine TtyOnUart1_Periodically @global
|
||||
;
|
||||
; @clobbers R16, Y
|
||||
|
||||
TtyOnUart1_Periodically:
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
ldi yl, LOW(ttyOnUart1_iface)
|
||||
ldi yh, HIGH(ttyOnUart1_iface)
|
||||
rcall NET_Interface_Periodically
|
||||
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODECOUNTER
|
||||
inc r16
|
||||
breq TtyOnUart1_Periodically_end
|
||||
std Y+UART_HW2_IFACE_OFFS_MODECOUNTER, r16
|
||||
TtyOnUart1_Periodically_end:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1SetMode
|
||||
;
|
||||
; @param R16 mode
|
||||
; @clobbers R17
|
||||
|
||||
ttyOnUart1SetMode:
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
ldd r17, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
cp r16, r17
|
||||
breq ttyOnUart1SetMode_end
|
||||
std Y+UART_HW2_IFACE_OFFS_MODE, r16
|
||||
clr r17
|
||||
std Y+UART_HW2_IFACE_OFFS_MODECOUNTER, r17
|
||||
ttyOnUart1SetMode_end:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1StartReading
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers R16, R17, X
|
||||
|
||||
ttyOnUart1StartReading:
|
||||
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 ttyOnUart1SetMode ; (R17)
|
||||
; rcall ttyOnUart1StartRx ; should be the last call here
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1StartWriting
|
||||
;
|
||||
; @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)
|
||||
|
||||
ttyOnUart1StartWriting:
|
||||
push r15
|
||||
inr r15, SREG
|
||||
cli
|
||||
rcall ttyOnUart1StartWriting_noIrq
|
||||
brcc ttyOnUart1StartWriting_clc
|
||||
outr SREG, r15
|
||||
pop r15
|
||||
sec
|
||||
ret
|
||||
ttyOnUart1StartWriting_clc:
|
||||
outr SREG, r15
|
||||
pop r15
|
||||
clc
|
||||
ret
|
||||
|
||||
ttyOnUart1StartWriting_noIrq:
|
||||
; 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
|
||||
inc r17 ; add dest addr
|
||||
inc r17 ; add msg len
|
||||
inc r17 ; add crc
|
||||
; 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)
|
||||
ttyOnUart1StartWriting_loop:
|
||||
ld r16, X+
|
||||
st Z+, r16
|
||||
dec r17
|
||||
brne ttyOnUart1StartWriting_loop
|
||||
ldi r16, UART_HW2_MODE_WRITING
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
rcall ttyOnUart1StartTx ; should be the last call here (R16)
|
||||
sec
|
||||
ttyOnUart1StartWriting_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine TtyOnUart1_Run @global
|
||||
;
|
||||
; @clobbers all
|
||||
|
||||
TtyOnUart1_Run:
|
||||
ldi yl, LOW(ttyOnUart1_iface)
|
||||
ldi yh, HIGH(ttyOnUart1_iface)
|
||||
push r15
|
||||
inr r15, SREG
|
||||
cli
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
TtyOnUart1_Run_loop:
|
||||
push r16 ; current state
|
||||
rcall ttyOnUart1RunMode ; (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 TtyOnUart1_Run_loop ; state changed, run again
|
||||
outr SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunMode
|
||||
;
|
||||
; @clobbers all
|
||||
|
||||
ttyOnUart1RunMode:
|
||||
cpi r16, UART_HW2_MODE_NUM
|
||||
brcs TtyOnUart1_Run_jump
|
||||
ldi r16, UART_HW2_MODE_IDLE ; unknown mode, set to idle
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
ret
|
||||
TtyOnUart1_Run_jump:
|
||||
ldi zl, LOW(ttyOnUart1ModeJumpTable)
|
||||
ldi zh, HIGH(ttyOnUart1ModeJumpTable)
|
||||
add zl, r16
|
||||
adc zh, r16
|
||||
sub zh, r16
|
||||
ijmp
|
||||
ttyOnUart1ModeJumpTable:
|
||||
rjmp ttyOnUart1RunIdle
|
||||
rjmp ttyOnUart1RunReading
|
||||
rjmp ttyOnUart1RunSkipping
|
||||
rjmp ttyOnUart1RunMsgReceived
|
||||
rjmp ttyOnUart1RunWriting
|
||||
rjmp ttyOnUart1RunWaitBufferEmpty
|
||||
rjmp ttyOnUart1RunMsgSent
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunIdle
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers R16, R17, R24, R25, X, Z
|
||||
|
||||
ttyOnUart1RunIdle:
|
||||
; look for outbound message
|
||||
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
|
||||
brcc ttyOnUart1RunIdle_end ; no outmsg in queue
|
||||
rcall ttyOnUart1StartWriting ; (R16, R17, R22, R24, R25, X, Z)
|
||||
brcc ttyOnUart1RunIdle_end
|
||||
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
|
||||
ttyOnUart1RunIdle_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunReading
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers none
|
||||
|
||||
ttyOnUart1RunReading:
|
||||
; TODO: check for timeout
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunSkipping
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers R16 (R17)
|
||||
|
||||
ttyOnUart1RunSkipping:
|
||||
ldd r16, Y+NET_IFACE_OFFS_READTIMER
|
||||
cpi r16, TTYONUART1_SKIPTIME
|
||||
brcs ttyOnUart1RunSkipping_end
|
||||
; leave skip mode (enter idle)
|
||||
ldi r16, UART_HW2_MODE_IDLE
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
ttyOnUart1RunSkipping_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunMsgReceived
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers R16, R17, R18, X, Z (R19, R20, R24, R25)
|
||||
|
||||
ttyOnUart1RunMsgReceived:
|
||||
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 ttyOnUart1RunMsgReceived_econtent
|
||||
; msg valid, alloc buffer
|
||||
rcall NET_Buffer_Alloc ; X=buffer, R16=bufnum (R16, R17, X)
|
||||
brcc ttyOnUart1RunMsgReceived_enobuf
|
||||
mov r18, r16 ; buffer num
|
||||
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
|
||||
adiw xh:xl, 1
|
||||
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFUSED ; always is at least 2 here
|
||||
ttyOnUart1RunMsgReceived_copyLoop:
|
||||
ld r16, Z+
|
||||
st X+, r16
|
||||
dec r17
|
||||
brne ttyOnUart1RunMsgReceived_copyLoop
|
||||
mov r16, r18 ; buffer num
|
||||
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
||||
brcc ttyOnUart1RunMsgReceived_enoadd
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
rjmp ttyOnUart1RunMsgReceived_setIdleAndEnd
|
||||
ttyOnUart1RunMsgReceived_enoadd:
|
||||
rcall NET_Buffer_ReleaseByNum
|
||||
rjmp ttyOnUart1RunMsgReceived_enobuf
|
||||
ttyOnUart1RunMsgReceived_enobuf:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
||||
rjmp ttyOnUart1RunMsgReceived_err
|
||||
ttyOnUart1RunMsgReceived_econtent:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
||||
ttyOnUart1RunMsgReceived_err:
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
ttyOnUart1RunMsgReceived_setIdleAndEnd:
|
||||
ldi r16, UART_HW2_MODE_IDLE
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
ttyOnUart1RunMsgReceived_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunWriting
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers none
|
||||
|
||||
ttyOnUart1RunWriting:
|
||||
; TODO: check for timeout
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunWaitBufferEmpty
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
ttyOnUart1RunWaitBufferEmpty:
|
||||
; TODO: check for timeout etc.
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RunWriting
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers R16 (R17, R22, R24, R25, X)
|
||||
|
||||
ttyOnUart1RunMsgSent:
|
||||
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 ttyOnUart1SetMode ; (R17)
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1StartRx
|
||||
;
|
||||
; @clobbers R16
|
||||
|
||||
ttyOnUart1StartRx:
|
||||
inr r16, UCSR1B
|
||||
sbr r16, (1<<RXCIE1) | (1<<RXEN1) ; enable RX complete interrupt, enable receive
|
||||
outr UCSR1B, r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1StopRx
|
||||
;
|
||||
; @clobbers R16
|
||||
|
||||
ttyOnUart1StopRx:
|
||||
inr r16, UCSR1B
|
||||
cbr r16, (1<<RXCIE1 | (1<<RXEN1)) ; disable RX complete interrupt, disable receive
|
||||
outr UCSR1B, r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1StartTx
|
||||
;
|
||||
; @clobbers R16
|
||||
|
||||
ttyOnUart1StartTx:
|
||||
inr r16, UCSR1A
|
||||
cbr r16, (1<<TXC1) ; clear TXCn interrupt
|
||||
outr UCSR1A, r16
|
||||
inr r16, UCSR1B
|
||||
; sbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; enable TX UDRE and TXC1 interrupt, enable transceive
|
||||
sbr r16, (1<<UDRIE1) | (1<<TXEN1) ; enable TX UDRE interrupt, enable transceive
|
||||
outr UCSR1B, r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1StopTx
|
||||
;
|
||||
; @clobbers R16
|
||||
|
||||
ttyOnUart1StopTx:
|
||||
inr r16, UCSR1B
|
||||
cbr r16, (1<<UDRIE1) | (1<<TXCIE1) | (1<<TXEN1) ; disable TX UDRE and TXC1 interrupt, enable transceive
|
||||
outr UCSR1B, r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine TtyOnUart1_RxCharIsr @global @isr
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
TtyOnUart1_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(ttyOnUart1_iface)
|
||||
ldi yh, HIGH(ttyOnUart1_iface)
|
||||
rcall ttyOnUart1RxCharIsr ; (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 TtyOnUart1_TxUdreIsr @global @isr
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
TtyOnUart1_TxUdreIsr:
|
||||
push r15
|
||||
in r15, SREG
|
||||
push r16
|
||||
push r17
|
||||
push xl
|
||||
push xh
|
||||
push yl
|
||||
push yh
|
||||
ldi yl, LOW(ttyOnUart1_iface)
|
||||
ldi yh, HIGH(ttyOnUart1_iface)
|
||||
rcall ttyOnUart1TxUdreIsr ; (R16, R17, X)
|
||||
pop yh
|
||||
pop yl
|
||||
pop xh
|
||||
pop xl
|
||||
pop r17
|
||||
pop r16
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine TtyOnUart1_TxCharIsr @global @isr
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
TtyOnUart1_TxCharIsr:
|
||||
push r15
|
||||
in r15, SREG
|
||||
push r16
|
||||
push r17
|
||||
push yl
|
||||
push yh
|
||||
ldi yl, LOW(ttyOnUart1_iface)
|
||||
ldi yh, HIGH(ttyOnUart1_iface)
|
||||
rcall ttyOnUart1TxCharIsr ; (R16, R17)
|
||||
pop yh
|
||||
pop yl
|
||||
pop r17
|
||||
pop r16
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1RxCharIsr @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers R16, R17, R18, R24, R25, X
|
||||
|
||||
ttyOnUart1RxCharIsr:
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
cpi r16, UART_HW2_MODE_READING
|
||||
breq ttyOnUart1RxCharIsr_readChar
|
||||
cpi r16, UART_HW2_MODE_SKIPPING
|
||||
breq ttyOnUart1RxCharIsr_skipChar
|
||||
cpi r16, UART_HW2_MODE_IDLE
|
||||
brne ttyOnUart1RxCharIsr_skipChar
|
||||
; is in idle mode, start reading mode (prepare buffer etc)
|
||||
rcall ttyOnUart1StartReading ; (R16, R17, X)
|
||||
ttyOnUart1RxCharIsr_readChar:
|
||||
; check for errors
|
||||
inr r16, UCSR1A ; check for errors
|
||||
andi r16, (1<<FE1) | (1<<DOR1) | (1<<UPE1)
|
||||
brne ttyOnUart1RxCharIsr_hwerr
|
||||
|
||||
inr r16, UCSR1A ; read status: data available?
|
||||
sbrs r16, RXC1
|
||||
rjmp ttyOnUart1RxCharIsr_end ; jmp if no data
|
||||
inr r16, UDR1 ; r16=received char
|
||||
; check mode
|
||||
ldd r17, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
cpi r17, UART_HW2_MODE_READING
|
||||
brne ttyOnUart1RxCharIsr_overrun
|
||||
; store char
|
||||
ldd xl, Y+UART_HW2_IFACE_OFFS_BUFPOS_LOW
|
||||
ldd xh, Y+UART_HW2_IFACE_OFFS_BUFPOS_HIGH
|
||||
st X+, r16
|
||||
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 ttyOnUart1RxCharIsr_complete
|
||||
; check msg size
|
||||
cpi r18, 2
|
||||
brne ttyOnUart1RxCharIsr_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 ttyOnUart1RxCharIsr_emsgsize ; msg too long
|
||||
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r16 ; set new number of bytes left
|
||||
tst r16
|
||||
brne ttyOnUart1RxCharIsr_end ; jmp if still bytes left to receive
|
||||
ttyOnUart1RxCharIsr_complete:
|
||||
; rcall ttyOnUart1StopRx
|
||||
ldi r16, UART_HW2_MODE_MSGRECEIVED
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
rjmp ttyOnUart1RxCharIsr_end
|
||||
ttyOnUart1RxCharIsr_hwerr:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
|
||||
rjmp ttyOnUart1RxCharIsr_err
|
||||
ttyOnUart1RxCharIsr_overrun:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
||||
rjmp ttyOnUart1RxCharIsr_err
|
||||
ttyOnUart1RxCharIsr_emsgsize:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
|
||||
ttyOnUart1RxCharIsr_err:
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
; rcall ttyOnUart1StopRx ; (R16)
|
||||
ldi r16, UART_HW2_MODE_SKIPPING
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
rjmp ttyOnUart1RxCharIsr_end
|
||||
ttyOnUart1RxCharIsr_skipChar:
|
||||
inr r16, UCSR1A ; read status: data available?
|
||||
sbrs r16, RXC1
|
||||
rjmp ttyOnUart1RxCharIsr_end ; jmp if no data
|
||||
inr r16, UDR1 ; r16=received char
|
||||
ttyOnUart1RxCharIsr_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1TxUdreIsr @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
|
||||
|
||||
ttyOnUart1TxUdreIsr:
|
||||
inr r16, UCSR1A
|
||||
sbrs r16, UDRE1
|
||||
rjmp ttyOnUart1TxUdreIsr_disable_irq ; not ready
|
||||
|
||||
; check bytes left
|
||||
ldd r17, Y+UART_HW2_IFACE_OFFS_BUFLEFT
|
||||
tst r17
|
||||
breq ttyOnUart1TxUdreIsr_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 UDR1, r16 ; send byte
|
||||
; decrease counter
|
||||
dec r17
|
||||
std Y+UART_HW2_IFACE_OFFS_BUFLEFT, r17
|
||||
brne ttyOnUart1TxUdreIsr_end ; still bytes left to send, jump
|
||||
ttyOnUart1TxUdreIsr_finished:
|
||||
ldi r16, UART_HW2_MODE_WAITBUFFEREMPTY
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
ttyOnUart1TxUdreIsr_disable_irq:
|
||||
; disable further DRE interrupts
|
||||
inr r16, UCSR1B
|
||||
cbr r16, (1<<UDRIE1) ; disable TX data register empty interrupt
|
||||
sbr r16, (1<<TXC1) ; enable TXC1 interrupt
|
||||
outr UCSR1B, r16
|
||||
ttyOnUart1TxUdreIsr_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ttyOnUart1TxCharIsr @global
|
||||
;
|
||||
; Handler for TXC1 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
|
||||
|
||||
ttyOnUart1TxCharIsr:
|
||||
; disable further TXC interrupts
|
||||
inr r16, UCSR1B
|
||||
cbr r16, (1<<TXCIE1) ; disable TXC1 interrupt
|
||||
outr UCSR1B, r16
|
||||
rcall ttyOnUart1StopTx ; (R16)
|
||||
|
||||
ldd r16, Y+UART_HW2_IFACE_OFFS_MODE
|
||||
cpi r16, UART_HW2_MODE_WAITBUFFEREMPTY
|
||||
breq ttyOnUart1TxCharIsr_setMode
|
||||
ldi r16, UART_HW2_MODE_IDLE
|
||||
rjmp ttyOnUart1TxCharIsr_setMode
|
||||
ttyOnUart1TxCharIsr_msgComplete:
|
||||
ldi r16, UART_HW2_MODE_MSGSENT
|
||||
ttyOnUart1TxCharIsr_setMode:
|
||||
rcall ttyOnUart1SetMode ; (R17)
|
||||
ttyOnUart1TxCharIsr_disableIrq:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif ; AVR_MODULES_UART_HW2_TTYONUART1_H
|
||||
@@ -11,5 +11,5 @@
|
||||
|
||||
.equ FIRMWARE_VERSION_MAJOR = 1
|
||||
.equ FIRMWARE_VERSION_MINOR = 0
|
||||
.equ FIRMWARE_VERSION_PATCHLEVEL = 8
|
||||
.equ FIRMWARE_VERSION_PATCHLEVEL = 10
|
||||
|
||||
|
||||
Reference in New Issue
Block a user