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