279 lines
6.0 KiB
NASM
279 lines
6.0 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. *
|
|
; ***************************************************************************
|
|
|
|
; not used for now
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; macros
|
|
|
|
|
|
.macro mAttnInitInt0
|
|
; select falling edge of ATTN
|
|
inr r16, MCUCR
|
|
cbr r16, (1<<ISC01) | (1<<ISC00)
|
|
sbr r16, (1<<ISC01) | (0<<ISC00)
|
|
outr MCUCR, r16
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro mAttnInitPCI
|
|
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
|
ori r16, (1<<COM_IRQ_GIMSK_ATTN)
|
|
out GIMSK, R16
|
|
ldi r16, (1<<COM_IRQ_GIFR_ATTN) ; clear pending irq by writing 1 to ATTN bit
|
|
out GIFR, r16
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro mAttnEnableIrqInt0
|
|
inr r16, COM_IRQ_ADDR_ATTN
|
|
sbr r16, (1<<ATTN_IRQ_BIT)
|
|
outr COM_IRQ_ADDR_ATTN, r16
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro mAttnEnableIrqPCI
|
|
sbi COM_IRQ_ADDR_ATTN, ATTN_IRQ_BIT ; enable pin change irq for ATTN line
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro mAttnDisableIrqInt0
|
|
inr r16, COM_IRQ_ADDR_ATTN ; disable irq for ATTN line
|
|
cbr r16, (1<<ATTN_IRQ_BIT)
|
|
outr COM_IRQ_ADDR_ATTN, r16
|
|
.endmacro
|
|
|
|
|
|
|
|
.macro mAttnDisableIrqPCI
|
|
cbi COM_IRQ_ADDR_ATTN, ATTN_IRQ_BIT ; disable pin change irq for ATTN line
|
|
.endmacro
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_Init @global
|
|
;
|
|
; @clobbers R16
|
|
|
|
ATTN_Init:
|
|
.ifdef INT0
|
|
.if ATTN_IRQ_BIT == INT0
|
|
mAttnInitInt0
|
|
.else
|
|
mAttnInitPCI
|
|
.endif
|
|
.else
|
|
mAttnInitPCI
|
|
.endif
|
|
|
|
rcall ATTN_SetHighEnableIrq
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_SetLowDisableIrq @global
|
|
;
|
|
; @clobbers R16
|
|
|
|
ATTN_SetLowDisableIrq:
|
|
.ifdef INT0
|
|
.if ATTN_IRQ_BIT == INT0
|
|
mAttnDisableIrqInt0
|
|
.else
|
|
mAttnDisableIrqPCI
|
|
.endif
|
|
.else
|
|
mAttnDisableIrqPCI
|
|
.endif
|
|
|
|
sbi ATTN_DDR, ATTN_PIN ; set ATTN as output
|
|
cbi ATTN_OUTPUT, ATTN_PIN ; set ATTN low
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_SetHighEnableIrq @global
|
|
;
|
|
; @clobbers R16
|
|
|
|
ATTN_SetHighEnableIrq:
|
|
cbi ATTN_DDR, ATTN_PIN ; set ATTN as input
|
|
.ifdef ATTN_PUE
|
|
cbi ATTN_PUE, ATTN_PIN ; disable pullup on ATTN
|
|
.else
|
|
cbi ATTN_OUTPUT, ATTN_PIN ; disable pullup on ATTN
|
|
.endif
|
|
|
|
.ifdef INT0
|
|
.if ATTN_IRQ_BIT == INT0
|
|
mAttnEnableIrqInt0
|
|
.else
|
|
mAttnEnableIrqPCI
|
|
.endif
|
|
.else
|
|
mAttnEnableIrqPCI
|
|
.endif
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_IsHigh @global
|
|
;
|
|
; @return CFLAG set if ATTN is high
|
|
; @clobbers none
|
|
|
|
ATTN_IsHigh:
|
|
clc
|
|
sbic ATTN_INPUT, ATTN_PIN ; ATTN low?
|
|
sec ; yes, set CF
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_WaitForStateSeconds
|
|
;
|
|
; Wait for ATTN state max given seconds
|
|
;
|
|
; @return CFLAG set if okay (data available), cleared on error
|
|
; @param R16 expected state (0xff for high, 0 for low)
|
|
; @param r20 maximum number of seconds to wait
|
|
; @clobbers: r20, r22
|
|
|
|
ATTN_WaitForStateSeconds:
|
|
ATTN_WaitForStateSeconds_loop:
|
|
push r20
|
|
rcall ATTN_WaitForState1s ; (r20, r22)
|
|
pop r20
|
|
brcs ATTN_WaitForStateSeconds_gotit
|
|
sbi LED_PIN, LED_PINNUM ; toggle (doen't work on AtMega8515)
|
|
dec r20
|
|
brne ATTN_WaitForStateSeconds_loop
|
|
clc
|
|
ATTN_WaitForStateSeconds_gotit:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_WaitForState1s
|
|
;
|
|
; Wait for ATTN state for max 1s
|
|
;
|
|
; @param R16 expected state (0xff for high, 0 for low)
|
|
; @return CFLAG set if okay (ATTN state reached), cleared on error
|
|
; @clobbers: r20, r22
|
|
|
|
ATTN_WaitForState1s:
|
|
ldi r20, 100
|
|
ATTN_WaitForState1s_loop:
|
|
push r20
|
|
rcall ATTN_WaitForState10ms ; (R20, R22)
|
|
pop r20
|
|
brcs ATTN_WaitForState1s_gotit
|
|
dec r20
|
|
brne ATTN_WaitForState1s_loop
|
|
clc
|
|
ATTN_WaitForState1s_gotit:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_WaitForState10ms
|
|
;
|
|
; Wait for ATTN state for max 10 milliseconds.
|
|
;
|
|
; @param R16 expected state (0xff for high, 0 for low)
|
|
; @return CFLAG set if okay (ATTN state reached), cleared on error
|
|
; @clobbers: r20, r22
|
|
|
|
ATTN_WaitForState10ms:
|
|
.if clock == 8000000
|
|
ldi r20, 80
|
|
.endif
|
|
.if clock == 1000000
|
|
ldi r20, 10
|
|
.endif
|
|
ATTN_WaitForState10ms_loop:
|
|
push r20
|
|
rcall ATTN_WaitForState1000Cycles ; (r20, r22)
|
|
pop r20
|
|
brcs ATTN_WaitForState10ms_gotit
|
|
dec r20
|
|
brne ATTN_WaitForState10ms_loop
|
|
clc
|
|
ATTN_WaitForState10ms_gotit:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine ATTN_WaitForStateState1000Cycles
|
|
;
|
|
; Wait for ATTN state for max 1000 clock cycles
|
|
; (about 1ms at 1MHz, 0.125ms at 8MHz)
|
|
;
|
|
; @param R16 expected state (0xff for high, 0 for low)
|
|
; @return CFLAG set if okay (packet received), cleared on error
|
|
; @clobbers: r20, r22
|
|
|
|
ATTN_WaitForState1000Cycles:
|
|
ldi r20, 90 ; 1
|
|
ATTN_WaitForState1000Cycles_loop:
|
|
push r17 ; +2
|
|
in r17, COM_ATTN_INPUT ; +1
|
|
eor r17, r16 ; +1
|
|
andi r17, (1<<COM_ATTN_PIN) ; +1
|
|
pop r17 ; +2
|
|
breq ATTN_WaitForState1000Cycles_stateReached ; +1
|
|
dec r20 ; +1
|
|
brne ATTN_WaitForState1000Cycles_loop ; +2
|
|
clc
|
|
ret
|
|
ATTN_WaitForState1000Cycles_stateReached:
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|