; *************************************************************************** ; 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< 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