Files
aqhomecontrol/avr/modules/basetimer/main.asm
2025-05-24 17:25:24 +02:00

153 lines
3.5 KiB
NASM

; ***************************************************************************
; copyright : (C) 2024 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. *
; ***************************************************************************
;
; The base timer makes sure that "onSystemTimerTick" is called about every
; 100ms.
; The setup depends on hardware and clock.
;
; ***************************************************************************
; data
.dseg
baseTimerModuleData:
baseTimerModuleReloadValue: .byte 1
baseTimerModuleTickCounter: .byte 1
baseTimerTicksSinceLastRun: .byte 2
baseTimerModuleData_end:
; ***************************************************************************
; code
.cseg
BASETIMER_BEGIN:
; ---------------------------------------------------------------------------
; @routine BaseTimer_Init @global
;
; @clobbers r16, r17, x
BaseTimer_Init: ; setup timer for IRQ every 100ms
; reset data in SDRAM
ldi xh, HIGH(baseTimerModuleData)
ldi xl, LOW(baseTimerModuleData)
ldi r16, 0
ldi r17, (baseTimerModuleData_end-baseTimerModuleData)
rcall Utils_FillSram
rcall systemSetupTimer0
sec
ret
; @end
; ---------------------------------------------------------------------------
; @routine BaseTimer_Fini @global
;
BaseTimer_Fini:
ret
; @end
; ---------------------------------------------------------------------------
; @routine BaseTimer_Run @global
;
; @return CFLAG set if something done, cleared otherwise
; @clobbers all
BaseTimer_Run:
push r15
in r15, SREG
cli
lds r24, baseTimerTicksSinceLastRun
lds r25, baseTimerTicksSinceLastRun+1
clr r16 ; replace with 0 for next IRQ
sts baseTimerTicksSinceLastRun, r16
sts baseTimerTicksSinceLastRun+1, r16
out SREG, r15 ; restore global IRQ flag
pop r15
sbiw r25:r24, 0
clc ; flag "nothing done"
breq BaseTimer_Run_End
BaseTimer_Run_loop: ; for every timer tick
push r24
push r25
rcall onSystemTimerTick
pop r25
pop r24
sbiw r25:r24, 1
brne BaseTimer_Run_loop
sec
BaseTimer_Run_End:
ret
; @end
; ---------------------------------------------------------------------------
; @routine baseTimerIrqOC0A @isr
;
; OC0A interrupt handler
;
; Increments baseTimerModuleTickCounter, if it reaches 0 then baseTimerTicksSinceLastRun
; is also incremented and the baseTimerModuleTickCounter reloaded.
; The rest is done outside ISR baseTimerTicksSinceLastRun in BaseTimer_Run.
baseTimerIrqOC0A:
push r15
in r15, SREG
push r24
push r25
lds r24, baseTimerModuleTickCounter
dec r24
breq baseTimerIrqOC0A_timerElapsed
sts baseTimerModuleTickCounter, r24
rjmp baseTimerIrqOC0A_end
baseTimerIrqOC0A_timerElapsed:
lds r24, baseTimerModuleReloadValue ; reload counter
sts baseTimerModuleTickCounter, r24
lds r24, baseTimerTicksSinceLastRun
lds r25, baseTimerTicksSinceLastRun+1
adiw r25:r24, 1
sts baseTimerTicksSinceLastRun, r24
sts baseTimerTicksSinceLastRun+1, r25
baseTimerIrqOC0A_end:
pop r25
pop r24
out SREG, r15
pop r15
reti
; @end
BASETIMER_END:
.equ MODULE_SIZE_BASETIMER = BASETIMER_END-BASETIMER_BEGIN