avr: added com2w2 (slightly improved version of com2w).
- move IRQ control to main code (only the main code knows exactly which combination of pins is used for com2) - split one big module into multiple smaller files (easier to maintain)
This commit is contained in:
317
avr/modules/com2w2/io.asm
Normal file
317
avr/modules/com2w2/io.asm
Normal file
@@ -0,0 +1,317 @@
|
||||
; ***************************************************************************
|
||||
; copyright : (C) 2026 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_COM2W2_IO_H
|
||||
#define AVR_MODULES_COM2W2_IO_H
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2EnableClkIrq
|
||||
;
|
||||
; @clobbers
|
||||
|
||||
com2w2EnableClkIrq:
|
||||
.ifdef COM_ENABLEIRQ_FN
|
||||
bigcall COM_ENABLEIRQ_FN
|
||||
.else
|
||||
push r16
|
||||
inr r16, COM_IRQ_ADDR_CLK
|
||||
sbr r16, (1<<COM_IRQ_BIT_CLK) ; enable pin change irq for CLK line
|
||||
outr COM_IRQ_ADDR_CLK, r16
|
||||
pop r16
|
||||
.endif
|
||||
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2DisableClkIrq
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
com2w2DisableClkIrq:
|
||||
push r16
|
||||
inr r16, COM_IRQ_ADDR_CLK
|
||||
cbr r16, (1<<COM_IRQ_BIT_CLK) ; disable pin change irq for CLK line
|
||||
outr COM_IRQ_ADDR_CLK, r16
|
||||
pop r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2ClkSetHigh
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
com2w2ClkSetHigh:
|
||||
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
|
||||
.ifdef COM_CLK_PUE
|
||||
; cbi COM_CLK_PUE, COM_CLK_PIN ; disable pullup on CLK
|
||||
.else
|
||||
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
|
||||
.endif
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2ClkSetLow
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
com2w2ClkSetLow:
|
||||
sbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as output
|
||||
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; set CLK low
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2DataSetHigh
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
com2w2DataSetHigh:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
|
||||
.ifdef COM_DATA_PUE
|
||||
; cbi COM_DATA_PUE, COM_CLK_PIN ; disable pullup on DATA
|
||||
.else
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
|
||||
.endif
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2DataSetLow
|
||||
;
|
||||
; @clobbers none
|
||||
|
||||
com2w2DataSetLow:
|
||||
sbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as output
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; set DATA low
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2WaitForClockHighMulti10Us
|
||||
;
|
||||
; Wait for high CLK
|
||||
;
|
||||
; @param R20 multiple of 10us to wait (e.g. "2" for "20" us)
|
||||
; @return CFLAG set if okay (state reached), cleared on error
|
||||
; @clobbers: r20, r22
|
||||
|
||||
com2w2WaitForClockHighMulti10Us:
|
||||
.if clock > 1000000
|
||||
; begin version for > 1000000 Hz
|
||||
ldi r22, clock/1000000
|
||||
com2w2WaitForClockHighMulti10Us_loop0:
|
||||
push r20
|
||||
com2w2WaitForClockHighMulti10Us_loop: ; 10 cycles per loop
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockHighMulti10Us_stateReached ; (+2 if taken)
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockHighMulti10Us_stateReached ; (+2 if taken)
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockHighMulti10Us_stateReached ; (+2 if taken)
|
||||
nop ; +1
|
||||
dec r20 ; +1
|
||||
brne com2w2WaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE
|
||||
pop r20
|
||||
dec r22 ; +1
|
||||
brne com2w2WaitForClockHighMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE
|
||||
clc ; +1
|
||||
ret ; +4
|
||||
com2w2WaitForClockHighMulti10Us_stateReached:
|
||||
pop r20
|
||||
sec ; +1
|
||||
ret ; +4
|
||||
; end version for > 1000000 Hz
|
||||
.elif clock < 1000000
|
||||
.error "Clock speed too low"
|
||||
.else
|
||||
; begin version for 1000000 Hz
|
||||
com2w2WaitForClockHighMulti10Us_loop: ; 10 cycles per loop
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockHighMulti10Us_stateReached ; (+2 if taken)
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockHighMulti10Us_stateReached ; (+2 if taken)
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockHighMulti10Us_stateReached ; (+2 if taken)
|
||||
nop ; +1
|
||||
dec r20 ; +1
|
||||
brne com2w2WaitForClockHighMulti10Us_loop ; +2 if TRUE, +1 if FALSE
|
||||
clc ; +1
|
||||
ret ; +4
|
||||
com2w2WaitForClockHighMulti10Us_stateReached:
|
||||
sec ; +1
|
||||
ret ; +4
|
||||
; end version for 1000000 Hz
|
||||
.endif
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2WaitForClockLowMulti10Us
|
||||
;
|
||||
; Wait for low CLK
|
||||
;
|
||||
; @param R20 multiple of 10us to wait (e.g. "2" for "20" us)
|
||||
; @return CFLAG set if okay (state reached), cleared on error
|
||||
; @clobbers: r20, r22
|
||||
|
||||
com2w2WaitForClockLowMulti10Us:
|
||||
.if clock > 1000000
|
||||
; begin version for > 1000000 Hz
|
||||
ldi r22, clock/1000000
|
||||
com2w2WaitForClockLowMulti10Us_loop0:
|
||||
push r20
|
||||
com2w2WaitForClockLowMulti10Us_loop: ; 10 cycles per loop
|
||||
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockLowMulti10Us_stateReached ; (+2 if taken)
|
||||
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockLowMulti10Us_stateReached ; (+2 if taken)
|
||||
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockLowMulti10Us_stateReached ; (+2 if taken)
|
||||
nop ; +1
|
||||
dec r20 ; +1
|
||||
brne com2w2WaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE
|
||||
pop r20
|
||||
dec r22 ; +1
|
||||
brne com2w2WaitForClockLowMulti10Us_loop0 ; +1 if FALSE, +2 if TRUE
|
||||
clc ; +1
|
||||
ret ; +4
|
||||
com2w2WaitForClockLowMulti10Us_stateReached:
|
||||
pop r20
|
||||
sec ; +1
|
||||
ret ; +4
|
||||
; end version for > 1000000 Hz
|
||||
.elif clock < 1000000
|
||||
.error "Clock speed too low"
|
||||
.else
|
||||
; begin version for 1000000 Hz
|
||||
com2w2WaitForClockLowMulti10Us_loop: ; 10 cycles per loop
|
||||
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockLowMulti10Us_stateReached ; (+2 if taken)
|
||||
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockLowMulti10Us_stateReached ; (+2 if taken)
|
||||
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if taken
|
||||
rjmp com2w2WaitForClockLowMulti10Us_stateReached ; (+2 if taken)
|
||||
nop ; +1
|
||||
dec r20 ; +1
|
||||
brne com2w2WaitForClockLowMulti10Us_loop ; +2 if TRUE, +1 if FALSE
|
||||
clc ; +1
|
||||
ret ; +4
|
||||
com2w2WaitForClockLowMulti10Us_stateReached:
|
||||
sec ; +1
|
||||
ret ; +4
|
||||
; end version for 1000000 Hz
|
||||
.endif
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2WaitTime1
|
||||
;
|
||||
; waits for longer period (e.g. 30ns)
|
||||
;
|
||||
; @clobbers R22
|
||||
|
||||
com2w2WaitTime1:
|
||||
Utils_WaitNanoSecs COM2W2_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET)
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2WaitTime2
|
||||
;
|
||||
; waits for shorter period (e.g. 10ns)
|
||||
;
|
||||
; @clobbers R22
|
||||
|
||||
com2w2WaitTime2:
|
||||
Utils_WaitNanoSecs COM2W2_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET)
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2PcintIsr @global @isr
|
||||
;
|
||||
; ISR for PCINT0/1
|
||||
;
|
||||
; @clobbers: none
|
||||
|
||||
com2w2PcintIsr:
|
||||
push r15
|
||||
in r15, SREG
|
||||
sbic COM_CLK_INPUT, COM_CLK_PIN
|
||||
rjmp com2w2PcintIsr_end
|
||||
; low, read packet
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push r24
|
||||
push r25
|
||||
push xl
|
||||
push xh
|
||||
push yl
|
||||
push yh
|
||||
ldi yl, LOW(com2w2_iface)
|
||||
ldi yh, HIGH(com2w2_iface)
|
||||
rcall com2w2ReceiveNextPkg ; (R16, R17, R18, R19, R20, R21, R22, R24, R25, X)
|
||||
pop yh
|
||||
pop yl
|
||||
pop xh
|
||||
pop xl
|
||||
pop r25
|
||||
pop r24
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
com2w2PcintIsr_end:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user