Files
aqhomecontrol/avr/modules/com2w/com2wn_irq.asm
Martin Preuss d9e7d4df81 com2w*: allow for higher frequencies than 8MHz
to be used with node S03, which is run at 20MHz.
2025-08-18 18:04:30 +02:00

163 lines
4.1 KiB
NASM

; ***************************************************************************
; copyright : (C) 2025 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_COM2W_COM2WN_IRQ_H
#define AVR_MODULES_COM2W_COM2WN_IRQ_H
.cseg
; ---------------------------------------------------------------------------
; @routine com2wnSetupIrq
;
com2wnSetupIrq:
; setup pin-change interrupt for CLK
rcall com2wnEnableClkIrq
; enable PCIEn irq
inr r16, COM_IRQ_ADDR_M_CLK ; enable pin change irq PCIEn
sbr r16, (1<<COM_IRQ_BIT_M_CLK)
outr COM_IRQ_ADDR_M_CLK, r16
; clear PCIEn interrupt flag
inr r16, COM_IRQ_ADDR_F_CLK ; enable pin change irq PCIEn
sbr r16, (1<<COM_IRQ_BIT_F_CLK)
outr COM_IRQ_ADDR_F_CLK, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wnEnableClkIrq
;
; @clobbers
com2wnEnableClkIrq:
push r16
push r17
ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_IRQ
inr r17, COM_IRQ_ADDR_CLK
or r17, r16
outr COM_IRQ_ADDR_CLK, r17
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wnDisableClkIrq
;
; @clobbers none
com2wnDisableClkIrq:
push r16
push r17
ldd r16, Y+COM2W_IFACE_OFFS_PINMASK_IRQ
com r16
inr r17, COM_IRQ_ADDR_CLK
and r17, r16 ; clear bit for clock line
outr COM_IRQ_ADDR_CLK, r17
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2WN_ClkChangeIsr @global @isr
;
; Interrupt service routine for dual or single port (i.e. one port contains all
; CLOCK and DATA bits like in node R05 and R06).
;
; @clobbers none
COM2WN_ClkChangeIsr:
.if COM_DATA_INPUT == COM_CLK_INPUT
; routine for single port
push r15
in r15, SREG
push r16
inr r16, COM_CLK_INPUT ; read clk state early
push r17
push r18
push xl
push xh
push yl
push yh
ldi yl, LOW(com2wnIoRingBuffer)
ldi yh, HIGH(com2wnIoRingBuffer)
rcall RingBufferY_WriteByte ; (R17, R18, X)
brcs COM2WN_ClkChangeIsr_popRet
lds r16, com2wnIoFlags
ori r16, (1<<COM2W_IO_FLAGS_BIT_OVR)
sts com2wnIoFlags, r16
COM2WN_ClkChangeIsr_popRet:
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
.else
; routine for two port
push r15
in r15, SREG
push r16
push r17
inr r16, COM_CLK_INPUT ; read clk state early
inr r17, COM_DATA_INPUT ; read data state early
push r18
push xl
push xh
push yl
push yh
ldi yl, LOW(com2wnIoRingBuffer)
ldi yh, HIGH(com2wnIoRingBuffer)
push r17
rcall RingBufferY_WriteByte ; push clk state (R17, R18, X)
pop r16 ; pop DATA input into r16 (from r17)
brcc COM2WN_ClkChangeIsr_ovr
rcall RingBufferY_WriteByte ; push data state (R17, R18, X)
brcs COM2WN_ClkChangeIsr_popRet
COM2WN_ClkChangeIsr_ovr:
lds r16, com2wnIoFlags
ori r16, (1<<COM2W_IO_FLAGS_BIT_OVR)
sts com2wnIoFlags, r16
COM2WN_ClkChangeIsr_popRet:
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
.endif
; @end
#endif ; AVR_MODULES_COM2W_COM2WN_IRQ_H