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:
@@ -12,6 +12,7 @@
|
||||
clock
|
||||
cny70
|
||||
com2w
|
||||
com2w2
|
||||
com2w_router
|
||||
ds18b20
|
||||
eeprom
|
||||
|
||||
11
avr/modules/com2w2/0BUILD
Normal file
11
avr/modules/com2w2/0BUILD
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml?>
|
||||
|
||||
<gwbuild>
|
||||
|
||||
<extradist>
|
||||
com2w.asm
|
||||
</extradist>
|
||||
|
||||
</gwbuild>
|
||||
|
||||
|
||||
81
avr/modules/com2w2/byteread.asm
Normal file
81
avr/modules/com2w2/byteread.asm
Normal file
@@ -0,0 +1,81 @@
|
||||
; ***************************************************************************
|
||||
; 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_BYTEREAD_H
|
||||
#define AVR_MODULES_COM2W2_BYTEREAD_H
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2RecvByteWaitForQuietClk
|
||||
;
|
||||
; Wait until the clock line is consistently high for 1ms.
|
||||
;
|
||||
; @clobbers r18, r20, r22
|
||||
|
||||
com2w2RecvByteWaitForQuietClk:
|
||||
ldi r18, 200
|
||||
com2w2RecvByteWaitForQuietClk_loop:
|
||||
ldi r20, 100 ; wait up to 1ms for clock high (R20, R22)
|
||||
rcall com2w2WaitForClockLowMulti10Us ; (r20, r22)
|
||||
brcs com2w2RecvByteWaitForQuietClk_waitForLow
|
||||
dec r18
|
||||
brne com2w2RecvByteWaitForQuietClk_loop
|
||||
rjmp com2w2RecvByteWaitForQuietClk_ret
|
||||
com2w2RecvByteWaitForQuietClk_waitForLow:
|
||||
ldi r20, 100 ; wait up to 1ms for clock low (R20, R22)
|
||||
rcall com2w2WaitForClockLowMulti10Us
|
||||
brcc com2w2RecvByteWaitForQuietClk_ret ; not low within 1ms, assume line is quiet
|
||||
brne com2w2RecvByteWaitForQuietClk_loop
|
||||
com2w2RecvByteWaitForQuietClk_ret:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2RecvByte
|
||||
;
|
||||
; @return CFLAG set if byte received, cleared on error
|
||||
; @return r16 byte received
|
||||
; @clobbers r17, r18, r20, r22
|
||||
|
||||
com2w2RecvByte:
|
||||
ldi r17, 8
|
||||
clr r16
|
||||
com2w2RecvByte_loop:
|
||||
ldi r20, 100 ; wait up to 1ms for clock low
|
||||
rcall com2w2WaitForClockLowMulti10Us ; (R20, R22)
|
||||
brcc com2w2RecvByte_end
|
||||
ldi r20, 100 ; wait up to 1ms for clock high
|
||||
rcall com2w2WaitForClockHighMulti10Us ; (R20, R22)
|
||||
brcc com2w2RecvByte_end
|
||||
; handle received bit
|
||||
inr r18, COM_DATA_INPUT
|
||||
andi r18, (1<<COM_DATA_PIN)
|
||||
clc
|
||||
breq com2w2RecvByte_clockData
|
||||
sec
|
||||
com2w2RecvByte_clockData:
|
||||
ror r16
|
||||
dec r17
|
||||
brne com2w2RecvByte_loop
|
||||
sec
|
||||
com2w2RecvByte_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
76
avr/modules/com2w2/bytewrite.asm
Normal file
76
avr/modules/com2w2/bytewrite.asm
Normal file
@@ -0,0 +1,76 @@
|
||||
; ***************************************************************************
|
||||
; 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_BYTEWRITE_H
|
||||
#define AVR_MODULES_COM2W2_BYTEWRITE_H
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2SendBytes
|
||||
;
|
||||
; @param R18 number of bytes to send
|
||||
; @param X pointer to bytes to send
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @clobbers: r16, r18, X (r17, r22)
|
||||
|
||||
com2w2SendBytes:
|
||||
com2w2SendBytes_loop:
|
||||
rcall com2w2ClkSetLow ; (none)
|
||||
rcall com2w2WaitTime1 ; longer wait period (R22)
|
||||
ld r16, X+
|
||||
rcall com2w2SendByte ; (R16, R17, R22)
|
||||
dec r18
|
||||
brne com2w2SendBytes_loop
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2SendByte
|
||||
;
|
||||
; @param R16 byte to send
|
||||
; @clobbers: r16, r17 (r22)
|
||||
|
||||
com2w2SendByte:
|
||||
push r15
|
||||
in r15, SREG
|
||||
ldi r17, 8
|
||||
com2w2SendByte_loop:
|
||||
M_COM2WCLKSETLOW
|
||||
out SREG, r15 ; probably enable irqs
|
||||
rcall com2w2WaitTime1 ; wait for longer time (R22)
|
||||
lsr r16
|
||||
brcs com2w2SendByte_send1
|
||||
M_COM2WDATASETLOW
|
||||
rjmp com2w2SendByte_sent
|
||||
com2w2SendByte_send1:
|
||||
M_COM2WDATASETHIGH
|
||||
com2w2SendByte_sent:
|
||||
Utils_WaitNanoSecs 5000, 0, r22 ; wait for very short time to ensure data is stable when clock rises
|
||||
cli ; ensure time period by disabling irqs
|
||||
M_COM2WCLKSETHIGH
|
||||
rcall com2w2WaitTime2 ; wait for shorter time (R22)
|
||||
dec r17
|
||||
brne com2w2SendByte_loop
|
||||
out SREG, r15
|
||||
pop r15
|
||||
rcall com2w2WaitTime2 ; wait for shorter time (R22)
|
||||
M_COM2WDATASETHIGH ; ensure data line is high
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
20
avr/modules/com2w2/data.asm
Normal file
20
avr/modules/com2w2/data.asm
Normal file
@@ -0,0 +1,20 @@
|
||||
; ***************************************************************************
|
||||
; 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_DATA_H
|
||||
#define AVR_MODULES_COM2W2_DATA_H
|
||||
|
||||
|
||||
.dseg
|
||||
|
||||
com2w2_iface: .byte COM2W2_IFACE_SIZE
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
26
avr/modules/com2w2/defs.asm
Normal file
26
avr/modules/com2w2/defs.asm
Normal file
@@ -0,0 +1,26 @@
|
||||
; ***************************************************************************
|
||||
; 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_DEFS_H
|
||||
#define AVR_MODULES_COM2W2_DEFS_H
|
||||
|
||||
|
||||
.equ COM2W2_WAITTIME1 = 25000
|
||||
.equ COM2W2_WAITTIME2 = 15000
|
||||
|
||||
|
||||
.equ COM2W2_BUFFER_SIZE = NET_BUFFERS_SIZE-1
|
||||
|
||||
.equ COM2W2_IFACE_OFFS_BEGIN = NET_IFACE_SIZE
|
||||
.equ COM2W2_IFACE_OFFS_BUFFER = COM2W2_IFACE_OFFS_BEGIN+0
|
||||
.equ COM2W2_IFACE_SIZE = COM2W2_IFACE_OFFS_BUFFER+COM2W2_BUFFER_SIZE
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
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
|
||||
|
||||
90
avr/modules/com2w2/macros.asm
Normal file
90
avr/modules/com2w2/macros.asm
Normal file
@@ -0,0 +1,90 @@
|
||||
; ***************************************************************************
|
||||
; 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_MACROS_H
|
||||
#define AVR_MODULES_COM2W2_MACROS_H
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WCLKSETLOW
|
||||
sbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as output
|
||||
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; set CLK low
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WCLKSETHIGH
|
||||
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
|
||||
.ifndef COM_CLK_PUE
|
||||
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
|
||||
.endif
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WDATASETLOW
|
||||
sbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as output
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; set DATA low
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WDATASETHIGH
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
|
||||
.ifndef COM_DATA_PUE
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
|
||||
.endif
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WSETUPINT0
|
||||
inr r16, MCUCR
|
||||
cbr r16, (1<<ISC01) | (1<<ISC00)
|
||||
sbr r16, (1<<ISC01) | (0<<ISC00) ; falling edge of ATTN
|
||||
outr MCUCR, r16
|
||||
; sbr r16, (0<<ISC01) | (0<<ISC00) ; low level triggers
|
||||
inr r16, COM_IRQ_ADDR_CLK ; enable irq for ATTN line
|
||||
sbr r16, (1<<COM_IRQ_BIT_CLK)
|
||||
outr COM_IRQ_ADDR_CLK, r16
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WSETUPPCI
|
||||
inr r16, COM_IRQ_ADDR_CLK ; enable pin change irq for CLK line
|
||||
ori r16, (1<<COM_IRQ_BIT_CLK)
|
||||
outr COM_IRQ_ADDR_CLK, r16
|
||||
; sbi COM_IRQ_ADDR_CLK, COM_IRQ_BIT_CLK ; enable pin change irq for CLK line
|
||||
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
ori r16, (1<<COM_IRQ_GIMSK_CLK)
|
||||
out GIMSK, R16
|
||||
ldi r16, (1<<COM_IRQ_GIFR_CLK) ; clear pending irq by writing 1 to CLK bit
|
||||
out GIFR, r16
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
.macro M_COM2WSETUPPCICR
|
||||
inr r16, COM_IRQ_ADDR_CLK ; enable pin change irq for CLK line
|
||||
ori r16, (1<<COM_IRQ_BIT_CLK)
|
||||
outr COM_IRQ_ADDR_CLK, r16
|
||||
|
||||
inr r16, COM_IRQ_ICR_ADDR ; enable pin change irq in PCICR
|
||||
ori r16, (1<<COM_IRQ_ICR_BIT)
|
||||
outr COM_IRQ_ICR_ADDR, R16
|
||||
ldi r16, (1<<COM_IRQ_IFR_BIT) ; clear pending irq by writing 1 to CLK bit
|
||||
out COM_IRQ_IFR_ADDR, r16
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
234
avr/modules/com2w2/main.asm
Normal file
234
avr/modules/com2w2/main.asm
Normal file
@@ -0,0 +1,234 @@
|
||||
; ***************************************************************************
|
||||
; 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_MAIN_H
|
||||
#define AVR_MODULES_COM2W2_MAIN_H
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2W2_Init
|
||||
;
|
||||
; @clobbers
|
||||
|
||||
COM2W2_Init:
|
||||
ldi yl, LOW(com2w2_iface)
|
||||
ldi yh, HIGH(com2w2_iface)
|
||||
rcall NET_Interface_Init ; (R16, R17, X)
|
||||
|
||||
; setup CLK line (as input, disable internal pull-up resistor)
|
||||
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
|
||||
.ifdef COM_CLK_PUE
|
||||
inr r16, COM_CLK_PUE
|
||||
cbr r16, (1<<COM_CLK_PIN) ; disable pullup on CLK
|
||||
outr COM_CLK_PUE, r16
|
||||
.else
|
||||
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
|
||||
.endif
|
||||
|
||||
; setup DATA line (as input, disable internal pull-up resistor)
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
|
||||
.ifdef COM_DATA_PUE
|
||||
inr r16, COM_DATA_PUE
|
||||
cbr r16, (1<<COM_DATA_PIN) ; disable pullup on DATA
|
||||
outr COM_DATA_PUE, r16
|
||||
.else
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
|
||||
.endif
|
||||
|
||||
.ifdef COM_SETUPIRQ_FN
|
||||
bigcall COM_SETUPIRQ_FN
|
||||
.endif
|
||||
|
||||
; setup pin-change interrupt for CLK
|
||||
rcall com2w2EnableClkIrq
|
||||
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2W2_Every100ms @global
|
||||
;
|
||||
; @clobbers R16, Y
|
||||
|
||||
COM2W2_Every100ms:
|
||||
ldi yl, LOW(com2w2_iface)
|
||||
ldi yh, HIGH(com2w2_iface)
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
rcall NET_Interface_Periodically ; (R16)
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine COM2W2_Run @global
|
||||
;
|
||||
; @clobbers (R16, R17, R18, R20, R22, R24, R25, X)
|
||||
|
||||
COM2W2_Run:
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
ldi yl, LOW(com2w2_iface)
|
||||
ldi yh, HIGH(com2w2_iface)
|
||||
rcall com2w2SendNextPkg ; (R16, R17, R18, R20, R22, R24, R25, X)
|
||||
brcs COM2W2_Run_ok
|
||||
pop r15
|
||||
clc
|
||||
rjmp COM2W2_Run_ret
|
||||
COM2W2_Run_ok:
|
||||
pop r15
|
||||
sec
|
||||
COM2W2_Run_ret:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2ReceiveNextPkg
|
||||
;
|
||||
; Receive packet.
|
||||
;
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers R16, R17, R18, R19, R20, R22, R24, R25, X
|
||||
|
||||
com2w2ReceiveNextPkg:
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, COM2W2_IFACE_OFFS_BUFFER
|
||||
ldi r19, COM2W2_BUFFER_SIZE
|
||||
rcall com2w2RecvMsg ; (r16, r17, r18, r19, r20, r22, r24, r25, X)
|
||||
brcc com2w2ReceiveNextPkg_end
|
||||
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, COM2W2_IFACE_OFFS_BUFFER
|
||||
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
||||
brcc com2w2ReceiveNextPkg_eCrc
|
||||
|
||||
#ifndef COM_ACCEPT_ALL_DEST
|
||||
; check destination addr
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, COM2W2_IFACE_OFFS_BUFFER
|
||||
adiw xh:xl, NETMSG_OFFS_DESTADDR
|
||||
ld r16, X ; read destination address
|
||||
cpi r16, 0xff
|
||||
breq com2w2ReceiveNextPkg_forMe
|
||||
ldd r17, Y+NET_IFACE_OFFS_ADDRESS
|
||||
cp r16, r17
|
||||
breq com2w2ReceiveNextPkg_forMe
|
||||
; packet not for me, but correctly received, inc counter, but don't light LED
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
rjmp com2w2ReceiveNextPkg_end
|
||||
com2w2ReceiveNextPkg_forMe:
|
||||
#endif
|
||||
|
||||
; msg received, alloc buffer for it
|
||||
rcall NET_Buffer_Alloc ; R16=buffer num (R16, R17, X)
|
||||
brcs com2w2ReceiveNextPkg_gotBuffer
|
||||
; out of memory
|
||||
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
rjmp com2w2ReceiveNextPkg_end
|
||||
|
||||
; copy received message into allocated buffer
|
||||
com2w2ReceiveNextPkg_gotBuffer:
|
||||
mov r19, r16 ; save buffer num
|
||||
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
|
||||
mov r16, r19 ; restore buffer num
|
||||
push zl
|
||||
push zh
|
||||
mov zl, yl
|
||||
mov zh, yh
|
||||
adiw zh:zl, COM2W2_IFACE_OFFS_BUFFER ; Z=SRC
|
||||
adiw xh:xl, 1 ; X=DEST
|
||||
ldd r18, Z+NETMSG_OFFS_MSGLEN
|
||||
inc r18
|
||||
inc r18
|
||||
inc r18
|
||||
com2w2ReceiveNextPkg_copyLoop:
|
||||
ld r17, Z+
|
||||
st X+, r17
|
||||
dec r18
|
||||
brne com2w2ReceiveNextPkg_copyLoop
|
||||
pop zh
|
||||
pop zl
|
||||
|
||||
; add to incoming msg pool
|
||||
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
|
||||
brcc com2w2ReceiveNextPkg_eMissed
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
#ifdef LED1_NETWORK_ACTIVITY
|
||||
bigcall LED1_SetActivityTiming
|
||||
#endif
|
||||
rjmp com2w2ReceiveNextPkg_end
|
||||
com2w2ReceiveNextPkg_eCrc:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
rjmp com2w2ReceiveNextPkg_end
|
||||
com2w2ReceiveNextPkg_eMissed:
|
||||
push r16
|
||||
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
pop r16
|
||||
; fall-through to release buffer
|
||||
com2w2ReceiveNextPkg_relBuffer:
|
||||
rcall NET_Buffer_ReleaseByNum ; (R16, X)
|
||||
com2w2ReceiveNextPkg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2SendNextPkg @global
|
||||
;
|
||||
; Check whether there is an outgoing message in interface data
|
||||
; and send it if possible.
|
||||
;
|
||||
; @return CFLAG set if okay, clear on error
|
||||
; @param Y pointer to start of interface data
|
||||
; @clobbers (R16, R17, R18, R20, R22, R24, R25, X)
|
||||
|
||||
com2w2SendNextPkg:
|
||||
rcall NET_Interface_PeekNextOutgoingMsgNum ; (R17, R18, X)
|
||||
brcc com2w2SendNextPkg_end
|
||||
rcall NET_Buffer_Locate ; get pointer to buffer (R17)
|
||||
brcc com2w2SendNextPkg_end
|
||||
adiw xh:xl, 1 ; skip buffer header
|
||||
rcall com2w2SendMsg ; (R16, R18, R20, R22, R24, R25, X)
|
||||
brcc com2w2SendNextPkg_end
|
||||
rcall NET_Interface_GetNextOutgoingMsgNum ; remove from stack (R17, R18, X)
|
||||
rcall NET_Buffer_ReleaseByNum ; release buffer (R16, X)
|
||||
sec
|
||||
com2w2SendNextPkg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
71
avr/modules/com2w2/msgread.asm
Normal file
71
avr/modules/com2w2/msgread.asm
Normal file
@@ -0,0 +1,71 @@
|
||||
; ***************************************************************************
|
||||
; 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_MSGREAD_H
|
||||
#define AVR_MODULES_COM2W2_MSGREAD_H
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2RecvMsg
|
||||
;
|
||||
; Receive a packet into buffer pointed to by X.
|
||||
; Expects interrupts to be disabled.
|
||||
;
|
||||
; @param R19 max buffer size
|
||||
; @param X buffer to receive to
|
||||
; @return CFLAG set if msg received, cleared on error (see R16)
|
||||
; @return R16 if CFLAG cleared: 0=message not for this node, otherwise error
|
||||
; @clobbers r16, r17, r18, r19, r20, r22, r24, r25, X
|
||||
|
||||
com2w2RecvMsg:
|
||||
; check buffer size
|
||||
subi r19, 2
|
||||
brcs com2w2RecvMsg_eBadSize
|
||||
; read destination address
|
||||
rcall com2w2RecvByte ; (r17, r18, r20, r22)
|
||||
brcc com2w2RecvMsg_eIo
|
||||
st X+, r16
|
||||
; read remaining msg size
|
||||
rcall com2w2RecvByte ; (r17, r18, r20, r22)
|
||||
brcc com2w2RecvMsg_eIo
|
||||
st X+, r16
|
||||
inc r16 ; account for CRC byte
|
||||
sub r19, r16
|
||||
brcs com2w2RecvMsg_eBadSize
|
||||
mov r19, r16
|
||||
com2w2RecvMsg_loop:
|
||||
rcall com2w2RecvByte ; (r17, r18, r20, r22)
|
||||
brcc com2w2RecvMsg_eIo
|
||||
st X+, r16
|
||||
dec r19
|
||||
brne com2w2RecvMsg_loop
|
||||
sec
|
||||
rjmp com2w2RecvMsg_end
|
||||
com2w2RecvMsg_eBadSize:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_MSGSIZE_LOW
|
||||
rjmp com2w2RecvMsg_incCounterRet
|
||||
com2w2RecvMsg_eIo:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
|
||||
com2w2RecvMsg_incCounterRet:
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
rcall com2w2RecvByteWaitForQuietClk ; (r18, r20, r22)
|
||||
com2w2RecvMsg_clcRet:
|
||||
clc
|
||||
com2w2RecvMsg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
65
avr/modules/com2w2/msgwrite.asm
Normal file
65
avr/modules/com2w2/msgwrite.asm
Normal file
@@ -0,0 +1,65 @@
|
||||
; ***************************************************************************
|
||||
; 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_MSGWRITE_H
|
||||
#define AVR_MODULES_COM2W2_MSGWRITE_H
|
||||
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine com2w2SendMsg
|
||||
;
|
||||
; @param X pointer to bytes to send
|
||||
; @param Y pointer to interface data in SRAM
|
||||
; @return CFLAG set if message sent, cleared otherwise
|
||||
; @clobbers R16, R18 (R20, R22, R24, R25, X)
|
||||
|
||||
com2w2SendMsg:
|
||||
ldi r20, 6 ; wait for about 60us for clock low
|
||||
rcall com2w2WaitForClockLowMulti10Us ; (R16, R20, R22)
|
||||
brcs com2w2SendMsg_busy ; CLK got low while waiting, so line is busy
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli ; atomic disable irq and set CLK low
|
||||
rcall com2w2DisableClkIrq ; (none)
|
||||
rcall com2w2ClkSetLow ; reserve bus (none)
|
||||
out SREG, r15
|
||||
pop r15
|
||||
adiw xh:xl, NETMSG_OFFS_MSGLEN
|
||||
ld r18, X
|
||||
sbiw xh:xl, NETMSG_OFFS_MSGLEN
|
||||
inc r18 ; adjust for DESTADDR
|
||||
inc r18 ; adjust for MSGLEN
|
||||
inc r18 ; adjust for CRCBYTE
|
||||
rcall com2w2WaitTime1 ; longer wait period (R22)
|
||||
rcall com2w2SendBytes ; (r16, r17, r18, r22, X)
|
||||
rcall com2w2ClkSetHigh ; make sure bus is released
|
||||
rcall com2w2DataSetHigh
|
||||
|
||||
rcall com2w2EnableClkIrq ; (none)
|
||||
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
sec
|
||||
ret
|
||||
com2w2SendMsg_busy:
|
||||
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
|
||||
rcall NET_Interface_IncCounter16 ; (R24, R25)
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user