avr started working on irq driven uart module.
will be used for routers and usb-serial interface.
This commit is contained in:
59
avr/modules/uart_irq/defs.asm
Normal file
59
avr/modules/uart_irq/defs.asm
Normal file
@@ -0,0 +1,59 @@
|
||||
; ***************************************************************************
|
||||
; copyright : (C) 2024 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 UART_IRQ_STATE_IDLE = 0
|
||||
.equ UART_IRQ_STATE_WAITFORATTNHIGH = 1
|
||||
.equ UART_IRQ_STATE_WAITFORSTARTBIT = 2
|
||||
.equ UART_IRQ_STATE_WAITFORDATABIT = 3
|
||||
.equ UART_IRQ_STATE_WAITFORSTOPBIT = 4
|
||||
.equ UART_IRQ_STATE_SENDINGATTN = 5
|
||||
.equ UART_IRQ_STATE_SENDINGSTARTBIT = 6
|
||||
.equ UART_IRQ_STATE_SENDINGDATABIT = 7
|
||||
.equ UART_IRQ_STATE_SENDINGSTOPBIT = 8
|
||||
.equ UART_IRQ_STATE_COUNT = 9
|
||||
|
||||
|
||||
.equ UART_IRQ_IFACE_OFFS_STATE = 0
|
||||
.equ UART_IRQ_IFACE_OFFS_TICKCOUNTER = 1
|
||||
.equ UART_IRQ_IFACE_OFFS_STATECOUNTER = 2
|
||||
.equ UART_IRQ_IFACE_OFFS_STATEDATA = 3
|
||||
.equ UART_IRQ_IFACE_OFFS_READBUF_USED = 4
|
||||
.equ UART_IRQ_IFACE_OFFS_READBUF_RDPOS = 5
|
||||
.equ UART_IRQ_IFACE_OFFS_READBUF_WRPOS = 6
|
||||
.equ UART_IRQ_IFACE_OFFS_READBUF_BUF = 7 ; 8 bytes
|
||||
.equ UART_IRQ_IFACE_OFFS_WRITEBUF_USED = 15
|
||||
.equ UART_IRQ_IFACE_OFFS_WRITEBUF_RDPOS = 16
|
||||
.equ UART_IRQ_IFACE_OFFS_WRITEBUF_WRPOS = 17
|
||||
.equ UART_IRQ_IFACE_OFFS_WRITEBUF_BUF = 18 ; 8 bytes
|
||||
.equ UART_IRQ_IFACE_SIZE = 26
|
||||
|
||||
|
||||
|
||||
.equ UART_IRQ_IFACE_READBUF_SIZE = 8
|
||||
.equ UART_IRQ_IFACE_WRITEBUF_SIZE = 8
|
||||
|
||||
.equ UART_IRQ_IFACE_PINFN_READDATA = 0
|
||||
.equ UART_IRQ_IFACE_PINFN_READATTN = 1
|
||||
.equ UART_IRQ_IFACE_PINFN_WRITEDATA = 2
|
||||
.equ UART_IRQ_IFACE_PINFN_WRITEATTN = 3
|
||||
|
||||
.equ UART_IRQ_TIME_BITTIME1 = 8
|
||||
.equ UART_IRQ_TIME_BITTIME1_5 = 12
|
||||
.equ UART_IRQ_TIME_BITTIME2 = 16
|
||||
.equ UART_IRQ_TIME_BITTIME10 = 80
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
576
avr/modules/uart_irq/iface.asm
Normal file
576
avr/modules/uart_irq/iface.asm
Normal file
@@ -0,0 +1,576 @@
|
||||
; ***************************************************************************
|
||||
; copyright : (C) 2024 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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @macro m_uart_irq_handle_tick
|
||||
;
|
||||
; @clobbers any
|
||||
;
|
||||
; @param %0 COM_DATA_DDR
|
||||
; @param %1 COM_DATA_INPUT
|
||||
; @param %2 COM_DATA_OUTPUT
|
||||
; @param %3 COM_DATA_PIN
|
||||
; @param %4 COM_ATTN_DDR
|
||||
; @param %5 COM_ATTN_INPUT
|
||||
; @param %6 COM_ATTN_OUTPUT
|
||||
; @param %7 COM_ATTN_PIN
|
||||
; @param %8 uartIrqDataIface1
|
||||
|
||||
.macro m_uart_irq_handle_tick
|
||||
ldi yl, LOW(@8)
|
||||
ldi yh, HIGH(@8)
|
||||
ldi zl, LOW(_jumptable)
|
||||
ldi zh, HIGH(_jumptable)
|
||||
rjmp UART_Irq_HandleTick
|
||||
|
||||
_jumptable:
|
||||
rjmp _readDataBit ; read DATA BIT (r16=bit)
|
||||
rjmp _readAttnBit ; read ATTN BIT (r16=bit)
|
||||
rjmp _writeDataBit ; write DATA BIT (r16=bit)
|
||||
rjmp _writeAttnBit ; write ATTN BIT (r16=bit)
|
||||
|
||||
_readDataBit:
|
||||
clr r16
|
||||
sbic @1, @3
|
||||
inc r16
|
||||
ret
|
||||
|
||||
_readAttnBit:
|
||||
clr r16
|
||||
sbic @5, @7
|
||||
inc r16
|
||||
ret
|
||||
|
||||
_writeDataBit:
|
||||
tst r16
|
||||
brne _writeDataBit1
|
||||
cbi @0, @3 ; set data line to output (makes it LOW)
|
||||
ret
|
||||
_writeDataBit1:
|
||||
sbi @0, @3 ; set data line to output (external pullup R makes it HIGH)
|
||||
ret
|
||||
|
||||
_writeAttnBit:
|
||||
tst r16
|
||||
brne _writeAttnBit1
|
||||
cbi @4, @7 ; set ATTN line to output (makes it LOW)
|
||||
ret
|
||||
_writeAttnBit1:
|
||||
sbi @4, @7 ; set ATTN line to output (external pullup R makes it HIGH)
|
||||
ret
|
||||
.endmacro
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @macro m_ringbuffer_writebyte
|
||||
;
|
||||
; @param R16 byte to write
|
||||
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @param %0 constant maxBytes
|
||||
; @param %1 offset to Y to access usedBytes variable (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @param %2 offset to Y to access readPos variable
|
||||
; @param %3 offset to Y to access writePos variable
|
||||
; @param %4 offset to Y to access buffer
|
||||
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
|
||||
; @clobbers R17, X
|
||||
|
||||
.macro m_ringbuffer_writebyte
|
||||
ldd r17, Y+@1 ; usedBytes
|
||||
cpi r17, @0 ; maxBytes
|
||||
brcc l_end
|
||||
inc r17
|
||||
std Y+@1, r17 ; usedBytes
|
||||
ldd r17, Y+@3 ; writePos
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, @4
|
||||
add xl, r17
|
||||
adc xh, r17
|
||||
sub xh, r17
|
||||
st X, r16
|
||||
inc r17
|
||||
cpi r17, @0
|
||||
brcs l_store
|
||||
clr r17
|
||||
l_store:
|
||||
std Y+@3, r17 ; writePos
|
||||
sec
|
||||
l_end:
|
||||
.endmacro
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @macro m_ringbuffer_readbyte
|
||||
;
|
||||
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @param %0 constant maxBytes
|
||||
; @param %1 offset to Y to access usedBytes variable (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @param %2 offset to Y to access readPos variable
|
||||
; @param %3 offset to Y to access writePos variable
|
||||
; @param %4 offset to Y to access buffer
|
||||
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
|
||||
; @return R16 byte read
|
||||
; @clobbers R17, X
|
||||
|
||||
.macro m_ringbuffer_readbyte
|
||||
ldd r17, Y+@1 ; usedBytes
|
||||
tst r17
|
||||
clc
|
||||
breq l_end
|
||||
dec r17
|
||||
std Y+@1, r17 ; usedBytes
|
||||
ldd r17, Y+@2 ; readPos
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, @4
|
||||
add xl, r17
|
||||
adc xh, r17
|
||||
sub xh, r17
|
||||
ld r16, X
|
||||
inc r17
|
||||
cpi r17, @0
|
||||
brcs l_store
|
||||
clr r17
|
||||
l_store:
|
||||
std Y+@2, r17 ; readPos
|
||||
sec
|
||||
l_end:
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.dseg
|
||||
|
||||
uartIrqBase: .byte 4
|
||||
;uartIrqState: .byte 1
|
||||
;uartIrqCounter: .byte 1
|
||||
;uartIrqStateCounter: .byte 1
|
||||
;uartIrqCurrentByte: .byte 1
|
||||
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
UART_IRQ_BEGIN:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine UART_Irq_HandleTick @global
|
||||
;
|
||||
; @param Y pointer to interface data in SRAM (see @ref UART_IRQ_IFACE_OFFS_STATE)
|
||||
; @param Z pointer to IFACE jump table for the given interface
|
||||
; @clobbers any
|
||||
|
||||
UART_Irq_HandleTick:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
breq UART_Irq_HandleTick_handle
|
||||
dec r16
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
UART_Irq_HandleTick_handle:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATE
|
||||
rjmp uart_irq_JumpToStateFunction
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; r16: function
|
||||
uart_irq_JumpToStateFunction:
|
||||
cpi r16, UART_IRQ_STATE_COUNT ; invalid function num?
|
||||
brcc uart_irq_JumpToStateFunction_end
|
||||
ldi r18, LOW(uart_irq_state_jumptable)
|
||||
ldi r19, HIGH(uart_irq_state_jumptable)
|
||||
add r18, r16
|
||||
clr r16
|
||||
adc r19, r16
|
||||
push r18
|
||||
push r19
|
||||
uart_irq_JumpToStateFunction_end:
|
||||
ret ; indirect jump to address we just pushed to the stack
|
||||
|
||||
|
||||
|
||||
uart_irq_state_jumptable:
|
||||
rjmp uart_irq_handle_idle
|
||||
rjmp uart_irq_handle_waitforattnhigh
|
||||
rjmp uart_irq_handle_waitforstartbit
|
||||
rjmp uart_irq_handle_waitfordatabit
|
||||
rjmp uart_irq_handle_waitforstopbit
|
||||
rjmp uart_irq_handle_sendingattn
|
||||
rjmp uart_irq_handle_sendingstartbit
|
||||
rjmp uart_irq_handle_sendingdatabit
|
||||
rjmp uart_irq_handle_sendingstopbit
|
||||
|
||||
; z=iface jumptable
|
||||
uart_irq_ReadDataBit:
|
||||
adiw zh:zl, UART_IRQ_IFACE_PINFN_READDATA
|
||||
push zl
|
||||
push zh
|
||||
sbiw zh:zl, UART_IRQ_IFACE_PINFN_READDATA
|
||||
ret ; indirect jump to address we just pushed to the stack
|
||||
|
||||
|
||||
uart_irq_ReadAttnBit:
|
||||
adiw zh:zl, UART_IRQ_IFACE_PINFN_READATTN
|
||||
push zl
|
||||
push zh
|
||||
sbiw zh:zl, UART_IRQ_IFACE_PINFN_READATTN
|
||||
ret ; indirect jump to address we just pushed to the stack
|
||||
|
||||
|
||||
uart_irq_WriteDataBit:
|
||||
adiw zh:zl, UART_IRQ_IFACE_PINFN_WRITEDATA
|
||||
push zl
|
||||
push zh
|
||||
sbiw zh:zl, UART_IRQ_IFACE_PINFN_WRITEDATA
|
||||
ret ; indirect jump to address we just pushed to the stack
|
||||
|
||||
|
||||
uart_irq_WriteAttnBit:
|
||||
adiw zh:zl, UART_IRQ_IFACE_PINFN_WRITEATTN
|
||||
push zl
|
||||
push zh
|
||||
sbiw zh:zl, UART_IRQ_IFACE_PINFN_WRITEATTN
|
||||
ret ; indirect jump to address we just pushed to the stack
|
||||
|
||||
|
||||
|
||||
|
||||
; y=iface sram data
|
||||
; z=iface jumptable
|
||||
|
||||
uart_irq_handle_idle:
|
||||
rcall uart_irq_ReadAttnBit
|
||||
tst r16
|
||||
brne uart_irq_handle_idle_checksend ; jump if ATTN line high
|
||||
; ATTN low, start receiving
|
||||
ldi r16, UART_IRQ_STATE_WAITFORSTARTBIT
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME10
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
rjmp uart_irq_handle_idle_end
|
||||
uart_irq_handle_idle_checksend:
|
||||
; check whether there is something to send
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_WRITEBUF_USED
|
||||
tst r16
|
||||
breq uart_irq_handle_idle_end ; nothing to send
|
||||
; start sending
|
||||
clr r16
|
||||
rcall uart_irq_WriteAttnBit
|
||||
ldi r16, UART_IRQ_STATE_SENDINGATTN
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME2
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
uart_irq_handle_idle_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_waitforstartbit:
|
||||
rcall uart_irq_ReadAttnBit
|
||||
tst r16
|
||||
brne uart_irq_handle_waitforstartbit_toidle
|
||||
; ATTN still low
|
||||
rcall uart_irq_ReadDataBit
|
||||
tst r16
|
||||
breq uart_irq_handle_waitforstartbit_datalow
|
||||
; DATA still high
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
brne uart_irq_handle_waitforstartbit_end
|
||||
ldi r16, UART_IRQ_STATE_WAITFORATTNHIGH
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
rjmp uart_irq_handle_waitforstartbit_end
|
||||
uart_irq_handle_waitforstartbit_datalow:
|
||||
ldi r16, UART_IRQ_STATE_WAITFORDATABIT
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1_5
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
ldi r16, 8 ; 8 bit
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATECOUNTER, r16
|
||||
clr r16
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATEDATA, r16
|
||||
rjmp uart_irq_handle_waitforstartbit_end
|
||||
uart_irq_handle_waitforstartbit_toidle:
|
||||
ldi r16, UART_IRQ_STATE_IDLE
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
uart_irq_handle_waitforstartbit_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_waitfordatabit:
|
||||
rcall uart_irq_ReadAttnBit
|
||||
tst r16
|
||||
brne uart_irq_handle_waitfordatabit_toidle
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
brne uart_irq_handle_waitfordatabit_end
|
||||
; counter=0: read data
|
||||
rcall uart_irq_ReadDataBit
|
||||
ror r16 ; rotate bit into carry flag
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA ; doesn't change carry flag
|
||||
ror r16 ; rotate carry flag into data byte
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATEDATA, r16
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATECOUNTER
|
||||
dec r16
|
||||
brne uart_irq_handle_waitfordatabit_bytecomplete
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1 ; read next bit
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
rjmp uart_irq_handle_waitfordatabit_end
|
||||
uart_irq_handle_waitfordatabit_bytecomplete:
|
||||
ldi r16, UART_IRQ_STATE_WAITFORSTOPBIT
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1_5
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
rjmp uart_irq_handle_waitfordatabit_end
|
||||
uart_irq_handle_waitfordatabit_toidle:
|
||||
ldi r16, UART_IRQ_STATE_IDLE
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
uart_irq_handle_waitfordatabit_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_waitforstopbit:
|
||||
rcall uart_irq_ReadAttnBit
|
||||
tst r16
|
||||
brne uart_irq_handle_waitforstopbit_toidle
|
||||
rcall uart_irq_ReadDataBit
|
||||
tst r16
|
||||
brne uart_irq_handle_waitforstopbit_datahigh
|
||||
; still low
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
breq uart_irq_handle_waitforstopbit_abortmsg ; timeout, abort
|
||||
rjmp uart_irq_handle_waitforstopbit_end
|
||||
uart_irq_handle_waitforstopbit_datahigh:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA ; store received byte
|
||||
rcall uart_irq_rdbuf_writebyte
|
||||
brcc uart_irq_handle_waitforstopbit_abortmsg ; readbuffer full, abort
|
||||
ldi r16, UART_IRQ_STATE_WAITFORSTARTBIT ; wait for next byte
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME10
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
rjmp uart_irq_handle_waitforstopbit_end
|
||||
uart_irq_handle_waitforstopbit_abortmsg:
|
||||
ldi r16, UART_IRQ_STATE_WAITFORATTNHIGH
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
rjmp uart_irq_handle_waitforstopbit_end
|
||||
uart_irq_handle_waitforstopbit_toidle:
|
||||
ldi r16, UART_IRQ_STATE_IDLE
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
uart_irq_handle_waitforstopbit_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_waitforattnhigh:
|
||||
rcall uart_irq_ReadAttnBit
|
||||
tst r16
|
||||
breq uart_irq_handle_waitforattnhigh_end ; still low
|
||||
uart_irq_handle_waitforattnhigh_toidle:
|
||||
ldi r16, UART_IRQ_STATE_IDLE
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
uart_irq_handle_waitforattnhigh_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_sendingattn:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
brne uart_irq_handle_sendingattn_end
|
||||
; send start bit
|
||||
clr r16
|
||||
rcall uart_irq_WriteDataBit
|
||||
ldi r16, UART_IRQ_STATE_SENDINGSTARTBIT
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
uart_irq_handle_sendingattn_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_sendingstartbit:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
brne uart_irq_handle_sendingstartbit_end
|
||||
; store current data byte from ringbuffer
|
||||
rcall uart_irq_wrbuf_readbyte
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATEDATA, r16
|
||||
; send data bit
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA
|
||||
andi r16, 1
|
||||
rcall uart_irq_WriteDataBit
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA
|
||||
ror r16
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATEDATA, r16
|
||||
ldi r16, UART_IRQ_STATE_SENDINGDATABIT
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
ldi r16, 8
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATECOUNTER, r16
|
||||
uart_irq_handle_sendingstartbit_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_sendingdatabit:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
brne uart_irq_handle_sendingdatabit_end
|
||||
; all bits sent?
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATECOUNTER
|
||||
dec r16
|
||||
breq uart_irq_handle_sendingdatabit_tosendstopbit
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATECOUNTER, r16
|
||||
; send next data bit
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA
|
||||
andi r16, 1
|
||||
rcall uart_irq_WriteDataBit
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA
|
||||
ror r16
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATEDATA, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1 ; send next bit
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
rjmp uart_irq_handle_sendingstartbit_end
|
||||
uart_irq_handle_sendingdatabit_tosendstopbit:
|
||||
; send stop bit
|
||||
ldi r16, 1
|
||||
rcall uart_irq_WriteDataBit
|
||||
ldi r16, UART_IRQ_STATE_SENDINGSTOPBIT
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
uart_irq_handle_sendingdatabit_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
uart_irq_handle_sendingstopbit:
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
|
||||
tst r16
|
||||
brne uart_irq_handle_sendingstopbit_end
|
||||
; more to send?
|
||||
ldd r16, Y+UART_IRQ_IFACE_OFFS_WRITEBUF_USED
|
||||
tst r16
|
||||
breq uart_irq_handle_sendingstopbit_toidle ; nothing in buffer, go idle
|
||||
; wait some time before sending next byte
|
||||
ldi r16, UART_IRQ_STATE_SENDINGATTN
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
ldi r16, UART_IRQ_TIME_BITTIME1
|
||||
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
|
||||
rjmp uart_irq_handle_sendingstopbit_end
|
||||
uart_irq_handle_sendingstopbit_toidle:
|
||||
ldi r16, 1
|
||||
rcall uart_irq_WriteAttnBit
|
||||
ldi r16, UART_IRQ_STATE_IDLE
|
||||
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
|
||||
uart_irq_handle_sendingstopbit_end:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uart_irq_rdbuf_writebyte
|
||||
;
|
||||
; @param R16 byte to write
|
||||
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
|
||||
; @clobbers R17, X
|
||||
|
||||
uart_irq_rdbuf_writebyte:
|
||||
m_ringbuffer_writebyte \
|
||||
UART_IRQ_IFACE_READBUF_SIZE, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_USED, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_RDPOS, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_WRPOS, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_BUF
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uart_irq_rdbuf_readbyte
|
||||
;
|
||||
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
|
||||
; @return R16 byte read
|
||||
; @clobbers R17, X
|
||||
|
||||
uart_irq_rdbuf_readbyte:
|
||||
m_ringbuffer_readbyte \
|
||||
UART_IRQ_IFACE_READBUF_SIZE, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_USED, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_RDPOS, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_WRPOS, \
|
||||
UART_IRQ_IFACE_OFFS_READBUF_BUF
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uart_irq_wrbuf_writebyte
|
||||
;
|
||||
; @param R16 byte to write
|
||||
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
|
||||
; @clobbers R17, X
|
||||
|
||||
uart_irq_wrbuf_writebyte:
|
||||
m_ringbuffer_writebyte \
|
||||
UART_IRQ_IFACE_WRITEBUF_SIZE, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_USED, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_RDPOS, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_WRPOS, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_BUF
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine uart_irq_wrbuf_readbyte
|
||||
;
|
||||
; @param Y base address (for "LDD Y+nn" and "STD Y+nn")
|
||||
; @return CFLAG set if okay, cleared on error (i.e. buffer full)
|
||||
; @return R16 byte read
|
||||
; @clobbers R17, X
|
||||
|
||||
uart_irq_wrbuf_readbyte:
|
||||
m_ringbuffer_readbyte \
|
||||
UART_IRQ_IFACE_WRITEBUF_SIZE, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_USED, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_RDPOS, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_WRPOS, \
|
||||
UART_IRQ_IFACE_OFFS_WRITEBUF_BUF
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
UART_IRQ_END:
|
||||
.equ MODULE_SIZE_UART_IRQ = UART_IRQ_END-UART_IRQ_BEGIN
|
||||
|
||||
|
||||
27
avr/modules/uart_irq/iface1.asm
Normal file
27
avr/modules/uart_irq/iface1.asm
Normal file
@@ -0,0 +1,27 @@
|
||||
; ***************************************************************************
|
||||
; copyright : (C) 2024 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
|
||||
|
||||
uartIrqDataIface1: .byte UART_IRQ_IFACE_SIZE
|
||||
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
UART_Irq_Iface1_HandleTick:
|
||||
m_uart_irq_handle_tick \
|
||||
COM_RXD_DDR, COM_RXD_INPUT, COM_RXD_OUTPUT, COM_RXD_PIN, \
|
||||
COM_ATTN_DDR, COM_ATTN_INPUT, COM_ATTN_OUTPUT, COM_ATTN_PIN, \
|
||||
uartIrqDataIface1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user