Files
aqhomecontrol/avr/modules/com2w/com2wn_irq.asm

166 lines
4.3 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 and clear PCIE0/1 (@TODO put later into general setup)
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_CLK)
outr GIMSK, r16
ldi r16, (1<<COM_IRQ_GIFR_CLK) ; clear pending irq by writing 1 to GIFR bit
outr GIFR, 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_ClkChangeOnePortIsr @global @isr
;
; Interrupt service routine for single port (i.e. one port contains all
; CLOCK and DATA bits like in node R05).
;
; @clobbers none
COM2WN_ClkChangeOnePortIsr:
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_ClkChangeOnePortIsr_popRet
lds r16, com2wnIoFlags
ori r16, (1<<COM2W_IO_FLAGS_BIT_OVR)
sts com2wnIoFlags, r16
COM2WN_ClkChangeOnePortIsr_popRet:
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine COM2WN_ClkChangeTwoPortIsr @global @isr
;
; Interrupt service routine for single port (i.e. one port contains all
; CLOCK and DATA bits like in node R05).
;
; @clobbers none
COM2WN_ClkChangeTwoPortIsr:
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_ClkChangeTwoPortIsr_ovr
rcall RingBufferY_WriteByte ; push data state (R17, R18, X)
brcs COM2WN_ClkChangeTwoPortIsr_popRet
COM2WN_ClkChangeTwoPortIsr_ovr:
lds r16, com2wnIoFlags
ori r16, (1<<COM2W_IO_FLAGS_BIT_OVR)
sts com2wnIoFlags, r16
COM2WN_ClkChangeTwoPortIsr_popRet:
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
out SREG, r15
pop r15
reti
; @end
#endif ; AVR_MODULES_COM2W_COM2WN_IRQ_H