avr: added devices, more work on modules.

This commit is contained in:
Martin Preuss
2024-12-15 18:20:54 +01:00
parent c3fd458769
commit 4dc6031d03
61 changed files with 4758 additions and 184 deletions

View File

@@ -46,10 +46,20 @@
.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
.equ UART_IRQ_TIME_BITTIME1 = 4
.equ UART_IRQ_TIME_BITTIME1_5 = 6
.equ UART_IRQ_TIME_BITTIME2 = 8
.equ UART_IRQ_TIME_BITTIME10 = 40
;.equ UART_IRQ_TIME_BITTIME1 = 2
;.equ UART_IRQ_TIME_BITTIME1_5 = 3
;.equ UART_IRQ_TIME_BITTIME2 = 4
;.equ UART_IRQ_TIME_BITTIME10 = 20
;.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

View File

@@ -52,19 +52,23 @@ _readAttnBit:
_writeDataBit:
tst r16
brne _writeDataBit1
cbi @0, @3 ; set data line to output (makes it LOW)
sbi @0, @3 ; set data line to output
cbi @2, @3 ; set line LOW
ret
_writeDataBit1:
sbi @0, @3 ; set data line to output (external pullup R makes it HIGH)
cbi @0, @3 ; set data line to input (external pullup R makes it HIGH)
cbi @2, @3 ; disable internal pullup
ret
_writeAttnBit:
tst r16
brne _writeAttnBit1
cbi @4, @7 ; set ATTN line to output (makes it LOW)
sbi @4, @7 ; set ATTN line to output (makes it LOW)
cbi @2, @7 ; set line LOW
ret
_writeAttnBit1:
sbi @4, @7 ; set ATTN line to output (external pullup R makes it HIGH)
cbi @4, @7 ; set ATTN line to output (external pullup R makes it HIGH)
cbi @2, @7 ; disable internal pullup
ret
.endmacro
; @end
@@ -166,12 +170,31 @@ uartIrqBase: .byte 4
UART_IRQ_BEGIN:
; ---------------------------------------------------------------------------
; @routine UART_Irq_InitIface @global
;
; @param Y pointer to interface data in SRAM (see @ref UART_IRQ_IFACE_OFFS_STATE)
; @clobbers any
UART_Irq_InitIface:
; preset SRAM data area
mov xh, yh
mov xl, yl
clr r16
ldi r17, UART_IRQ_IFACE_SIZE
rcall Utils_FillSram
ret
; @end
; ---------------------------------------------------------------------------
; @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
; @clobbers r16, r17, X
UART_Irq_HandleTick:
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
@@ -181,24 +204,32 @@ UART_Irq_HandleTick:
std Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER, r16
UART_Irq_HandleTick_handle:
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATE
rjmp uart_irq_JumpToStateFunction
rjmp uart_irq_JumpToStateFunction ; (r16, r17, r18, r19, X)
; @end
; r16: function
; ---------------------------------------------------------------------------
; @routine uart_irq_JumpToStateFunction
;
; @param r16 function
; @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 r16, X (r17)
uart_irq_JumpToStateFunction:
cpi r16, UART_IRQ_STATE_COUNT ; invalid function num?
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
ldi xl, LOW(uart_irq_state_jumptable)
ldi xh, HIGH(uart_irq_state_jumptable)
add xl, r16
clr r16
adc r19, r16
push r18
push r19
adc xh, r16
push xl
push xh
uart_irq_JumpToStateFunction_end:
ret ; indirect jump to address we just pushed to the stack
; @end
@@ -213,48 +244,88 @@ uart_irq_state_jumptable:
rjmp uart_irq_handle_sendingdatabit
rjmp uart_irq_handle_sendingstopbit
; z=iface jumptable
; ---------------------------------------------------------------------------
; @routine uart_irq_ReadDataBit
;
; @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 r16
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
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_ReadAttnBit
;
; @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 r16
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
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_WriteDataBit
;
; @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 none
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
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_WriteAttnBit
;
; @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 none
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
; @end
; y=iface sram data
; z=iface jumptable
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_idle
;
; @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 R16
uart_irq_handle_idle:
rcall uart_irq_ReadAttnBit
rjmp uart_irq_handle_idle_checksend ; DEBUG!!
rcall uart_irq_ReadAttnBit ; (R16)
tst r16
brne uart_irq_handle_idle_checksend ; jump if ATTN line high
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
@@ -265,25 +336,33 @@ 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
breq uart_irq_handle_idle_end ; nothing to send
; start sending
clr r16
rcall uart_irq_WriteAttnBit
rcall uart_irq_WriteAttnBit ; (none)
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
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_waitforstartbit
;
; @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 R16
uart_irq_handle_waitforstartbit:
rcall uart_irq_ReadAttnBit
rcall uart_irq_ReadAttnBit ; (R16)
tst r16
brne uart_irq_handle_waitforstartbit_toidle
; ATTN still low
rcall uart_irq_ReadDataBit
rcall uart_irq_ReadDataBit ; (R16)
tst r16
breq uart_irq_handle_waitforstartbit_datalow
; DATA still high
@@ -308,20 +387,28 @@ uart_irq_handle_waitforstartbit_toidle:
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
uart_irq_handle_waitforstartbit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_waitfordatabit
;
; @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 R16
uart_irq_handle_waitfordatabit:
rcall uart_irq_ReadAttnBit
rcall uart_irq_ReadAttnBit ; (R16)
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
rcall uart_irq_ReadDataBit ; (R16)
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
@@ -341,11 +428,19 @@ uart_irq_handle_waitfordatabit_toidle:
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
uart_irq_handle_waitfordatabit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_waitforstopbit
;
; @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 R16 (R17, X)
uart_irq_handle_waitforstopbit:
rcall uart_irq_ReadAttnBit
rcall uart_irq_ReadAttnBit ; (R16)
tst r16
brne uart_irq_handle_waitforstopbit_toidle
rcall uart_irq_ReadDataBit
@@ -358,7 +453,7 @@ uart_irq_handle_waitforstopbit:
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
rcall uart_irq_rdbuf_writebyte ; (R17, X)
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
@@ -374,11 +469,19 @@ uart_irq_handle_waitforstopbit_toidle:
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
uart_irq_handle_waitforstopbit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_waitforattnhigh
;
; @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 R16
uart_irq_handle_waitforattnhigh:
rcall uart_irq_ReadAttnBit
rcall uart_irq_ReadAttnBit ; (R16)
tst r16
breq uart_irq_handle_waitforattnhigh_end ; still low
uart_irq_handle_waitforattnhigh_toidle:
@@ -386,36 +489,52 @@ uart_irq_handle_waitforattnhigh_toidle:
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
uart_irq_handle_waitforattnhigh_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_sendingattn
;
; @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 R16
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
rcall uart_irq_WriteDataBit ; (none)
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
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_sendingstartbit
;
; @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 R16 (R17, X)
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
; get current data byte from ringbuffer
rcall uart_irq_wrbuf_readbyte ; (R17, X)
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
rcall uart_irq_WriteDataBit ; (none)
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA
ror r16
std Y+UART_IRQ_IFACE_OFFS_STATEDATA, r16
@@ -427,9 +546,17 @@ uart_irq_handle_sendingstartbit:
std Y+UART_IRQ_IFACE_OFFS_STATECOUNTER, r16
uart_irq_handle_sendingstartbit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_sendingdatabit
;
; @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 R16
uart_irq_handle_sendingdatabit:
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
tst r16
@@ -442,26 +569,34 @@ uart_irq_handle_sendingdatabit:
; send next data bit
ldd r16, Y+UART_IRQ_IFACE_OFFS_STATEDATA
andi r16, 1
rcall uart_irq_WriteDataBit
rcall uart_irq_WriteDataBit ; (none)
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
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
rcall uart_irq_WriteDataBit ; (none)
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
; @end
; ---------------------------------------------------------------------------
; @routine uart_irq_handle_sendingstopbit
;
; @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 R16
uart_irq_handle_sendingstopbit:
ldd r16, Y+UART_IRQ_IFACE_OFFS_TICKCOUNTER
tst r16
@@ -478,7 +613,7 @@ uart_irq_handle_sendingstopbit:
rjmp uart_irq_handle_sendingstopbit_end
uart_irq_handle_sendingstopbit_toidle:
ldi r16, 1
rcall uart_irq_WriteAttnBit
rcall uart_irq_WriteAttnBit ; (none)
ldi r16, UART_IRQ_STATE_IDLE
std Y+UART_IRQ_IFACE_OFFS_STATE, r16
uart_irq_handle_sendingstopbit_end:
@@ -569,6 +704,84 @@ uart_irq_wrbuf_readbyte:
; ---------------------------------------------------------------------------
; @routine uart_irq_timer_init
;
; setup timer0 for irq every 52/4 ns
uart_irq_timer_init: ; setup timer for IRQ every 52/4 ns
ldi r16, (1<<WGM01) | (0<<WGM00) ; CTC mode
out TCCR0A, r16
;
; Settings for clock 8Mhz
; use timer0 with prescaler 1, OCR0A=104-1 (irq every 13us)
;
ldi r16, (0<<CS02) | (0<<CS01) | (1<<CS00) ; Prescaler 1
out TCCR0B, r16
; ldi r16, 52-1 ; set timer for 8 times baudrate (fixed to 19200 for now)
ldi r16, 104-1 ; set timer for 4 times baudrate (fixed to 19200 for now)
; ldi r16, 208-1 ; set timer for 2 times baudrate (fixed to 19200 for now)
out OCR0A, r16
ldi r16, (1<<OCF0A) ; clear pending interrupts
.ifdef TIFR0
out TIFR0, r16
.else
out TIFR, r16
.endif
ldi r16, (1<<OCIE0A) ; Timer/Counter0 Output Compare Match A Interrupt Enable
.ifdef TIMSK0
out TIMSK0, r16
.else
out TIMSK, r16
.endif
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine uartIrqIsrOC0A @isr
;
; OC0A interrupt handler
;
uartIrqIsrOC0A:
push r15
in r15, SREG
push r16
push r17
push xh
push xl
push yh
push yl
push zh
push zl
push r15
rcall UART_Irq_Iface1_HandleTick
rcall UART_Irq_Iface2_HandleTick
pop r15
pop zl
pop zh
pop yl
pop yh
pop xl
pop xh
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
UART_IRQ_END:
.equ MODULE_SIZE_UART_IRQ = UART_IRQ_END-UART_IRQ_BEGIN

View File

@@ -18,6 +18,21 @@ uartIrqDataIface1: .byte UART_IRQ_IFACE_SIZE
.cseg
UART_Irq_InitIface1:
ldi yl, LOW(uartIrqDataIface1)
ldi yh, HIGH(uartIrqDataIface1)
rcall UART_Irq_InitIface
; setup pins and interrupts
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
ret
UART_Irq_Iface1_HandleTick:
m_uart_irq_handle_tick \
COM_DATA_DDR, COM_DATA_INPUT, COM_DATA_OUTPUT, COM_DATA_PIN, \
@@ -25,3 +40,4 @@ UART_Irq_Iface1_HandleTick:
uartIrqDataIface1

View File

@@ -0,0 +1,39 @@
; ***************************************************************************
; 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
uartIrqDataIface2: .byte UART_IRQ_IFACE_SIZE
.cseg
UART_Irq_InitIface2:
ldi yl, LOW(uartIrqDataIface2)
ldi yh, HIGH(uartIrqDataIface2)
rcall UART_Irq_InitIface
; setup pins and interrupts
cbi COM_DATA2_DDR, COM_DATA2_PIN ; set DATA port as input
cbi COM_DATA2_OUTPUT, COM_DATA2_PIN ; disable internal pullup for TXD
cbi COM_ATTN2_DDR, COM_ATTN2_PIN ; set ATTN port as input
cbi COM_ATTN2_OUTPUT, COM_ATTN2_PIN ; disable internal pullup for ATTN
UART_Irq_Iface2_HandleTick:
m_uart_irq_handle_tick \
COM_DATA2_DDR, COM_DATA2_INPUT, COM_DATA2_OUTPUT, COM_DATA2_PIN, \
COM_ATTN2_DDR, COM_ATTN2_INPUT, COM_ATTN2_OUTPUT, COM_ATTN2_PIN, \
uartIrqDataIface2