Only basetimer depends on hardware and clock speed. Works onj AtTiny 84 at 1 MHz and 8 MHz.
189 lines
4.3 KiB
NASM
189 lines
4.3 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:
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @rotuine 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
|
|
|
|
ldi r16, (1<<CS02) | (1<<CS00) ; Prescaler 1024
|
|
out TCCR0B, r16
|
|
|
|
ldi r16, (1<<WGM01) ; CTC mode
|
|
out TCCR0A, r16
|
|
|
|
ldi r16, (1<<OCF0A) ; clear pending interrupts
|
|
out TIFR0, r16
|
|
|
|
ldi r16, (1<<OCIE0A)
|
|
out TIMSK0, r16
|
|
|
|
;
|
|
; Settings for clock 1Mhz (default)
|
|
; use timer0 with OCR0A=98-1 (irq every 97.65625 millisecs), baseTimerModuleReloadValue 1
|
|
;
|
|
.if clock == 1000000
|
|
; CMP-A interrupt about every 100ms
|
|
ldi r16, 98-1 ; (1,000,000/1024)/10 = 97.65625
|
|
out OCR0A, r16
|
|
|
|
ldi r16, 1
|
|
sts baseTimerModuleReloadValue, r16
|
|
.endif
|
|
|
|
;
|
|
; Settings for clock 8Mhz
|
|
; use timer0 with OCR0A=78 (irq every 9.984 millisecs), baseTimerModuleReloadValue 10
|
|
;
|
|
.if clock == 8000000
|
|
; CMP-A interrupt about every 10ms
|
|
ldi r16, 78-1
|
|
out OCR0A, r16
|
|
|
|
ldi r16, 10
|
|
sts baseTimerModuleReloadValue, r16
|
|
.endif
|
|
|
|
sec
|
|
ret
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @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
|
|
|
|
|
|
|