avr: rewrote timer code (split into timer and basetimer).
Only basetimer depends on hardware and clock speed. Works onj AtTiny 84 at 1 MHz and 8 MHz.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
<gwbuild>
|
||||
|
||||
<subdirs>
|
||||
basetimer
|
||||
bmp280
|
||||
cny70
|
||||
com2
|
||||
|
||||
12
avr/modules/basetimer/0BUILD
Normal file
12
avr/modules/basetimer/0BUILD
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml?>
|
||||
|
||||
<gwbuild>
|
||||
|
||||
<extradist>
|
||||
main.asm
|
||||
</extradist>
|
||||
|
||||
</gwbuild>
|
||||
|
||||
|
||||
|
||||
188
avr/modules/basetimer/main.asm
Normal file
188
avr/modules/basetimer/main.asm
Normal file
@@ -0,0 +1,188 @@
|
||||
; ***************************************************************************
|
||||
; 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
|
||||
|
||||
|
||||
|
||||
@@ -38,9 +38,8 @@ CPRO_WriteSysStats:
|
||||
lds r17, com2Interrupts+1
|
||||
st X+, r17
|
||||
|
||||
lds r17, timerInterrupts
|
||||
st X+, r17 ; timer interrupts
|
||||
lds r17, timerInterrupts+1
|
||||
clr r17
|
||||
st X+, r17 ; timer interrupts (not used anymore)
|
||||
st X+, r17
|
||||
pop xl
|
||||
pop xh
|
||||
|
||||
@@ -26,9 +26,7 @@
|
||||
|
||||
timerModuleData:
|
||||
timerModuleTickCounter: .byte 1
|
||||
timerTicksSinceLastRun: .byte 2
|
||||
timerModuleCounterSecs: .byte 4
|
||||
timerInterrupts: .byte 2
|
||||
timerModuleData_end:
|
||||
|
||||
|
||||
@@ -44,15 +42,11 @@ TIMER_BEGIN:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Timer_Init
|
||||
; @routine Timer_Init
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - nothing
|
||||
; USED: r16, r17, x
|
||||
; @clobbers r16, r17, x
|
||||
|
||||
Timer_Init: ; setup timer for IRQ every 100ms
|
||||
Timer_Init:
|
||||
; reset data in SDRAM
|
||||
ldi xh, HIGH(timerModuleData)
|
||||
ldi xl, LOW(timerModuleData)
|
||||
@@ -60,107 +54,63 @@ Timer_Init: ; setup timer for IRQ every 100ms
|
||||
ldi r17, (timerModuleData_end-timerModuleData)
|
||||
rcall Utils_FillSram
|
||||
|
||||
; CTC mode (WGM2:0=2, OCR0A=value, OCF0A Flag =1, -> IRQ_OC0A
|
||||
|
||||
; CMP-A interrupt about every 100ms
|
||||
ldi r16, (1<<CS02) | (1<<CS00) ; Prescaler 1024
|
||||
out TCCR0B, r16
|
||||
|
||||
ldi r16, (1<<WGM01) ; CTC mode
|
||||
out TCCR0A, r16
|
||||
|
||||
ldi r16, 98-1 ; (1,000,000/1024)/10 = 97.65625
|
||||
out OCR0A, r16
|
||||
|
||||
ldi r16, (1<<OCF0A) ; clear pending interrupts
|
||||
out TIFR0, r16
|
||||
|
||||
ldi r16, (1<<OCIE0A)
|
||||
out TIMSK0, r16
|
||||
ldi r16, 10 ; every sec
|
||||
sts timerModuleTickCounter, r16
|
||||
|
||||
rcall timerInitTimers
|
||||
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Timer_Fini
|
||||
; @routine Timer_Fini
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - nothing
|
||||
; USED:
|
||||
|
||||
Timer_Fini:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Timer_Run
|
||||
; @routine onSystemTimerTick
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if something done, cleared otherwise
|
||||
; USED: r15, r16, r24, r25 (more depending on called routines)
|
||||
; @return CFLAG set if something done, cleared otherwise
|
||||
; @clobbers all
|
||||
|
||||
Timer_Run:
|
||||
in r15, SREG
|
||||
cli
|
||||
lds r24, timerTicksSinceLastRun
|
||||
lds r25, timerTicksSinceLastRun+1
|
||||
clr r16 ; replace with 0 for next IRQ
|
||||
sts timerTicksSinceLastRun, r16
|
||||
sts timerTicksSinceLastRun+1, r16
|
||||
out SREG, r15 ; restore global IRQ flag
|
||||
sbiw r25:r24, 0
|
||||
clc ; flag "nothing done"
|
||||
breq Timer_Run_End
|
||||
Timer_Run_loop: ; for every occurred 100ms irq
|
||||
push r24
|
||||
push r25
|
||||
rcall timerRunTimers
|
||||
rcall onEvery100ms
|
||||
pop r25
|
||||
pop r24
|
||||
lds r16, timerModuleTickCounter
|
||||
inc r16
|
||||
cpi r16, 10
|
||||
brcc Timer_Run_SecondElapsed
|
||||
sts timerModuleTickCounter, r16
|
||||
rjmp Timer_Run_loop_end
|
||||
Timer_Run_SecondElapsed:
|
||||
clr r16
|
||||
sts timerModuleTickCounter, r16
|
||||
; push r24
|
||||
; push r25
|
||||
; rcall timerRunTimers
|
||||
; pop r25
|
||||
; pop r24
|
||||
Timer_Run_loop_end:
|
||||
sbiw r25:r24, 1
|
||||
brne Timer_Run_loop
|
||||
sec
|
||||
Timer_Run_End:
|
||||
onSystemTimerTick:
|
||||
lds r16, timerModuleTickCounter
|
||||
dec r16
|
||||
breq onSystemTimerTick_SecondElapsed
|
||||
sts timerModuleTickCounter, r16
|
||||
rjmp onSystemTimerTick_call
|
||||
|
||||
onSystemTimerTick_SecondElapsed:
|
||||
ldi r16, 10 ; reload counter (10=every sec)
|
||||
sts timerModuleTickCounter, r16
|
||||
ldi xl, LOW(timerModuleCounterSecs)
|
||||
ldi xh, HIGH(timerModuleCounterSecs)
|
||||
rcall Utils_IncrementCounter32 ; inc uptime counter
|
||||
|
||||
onSystemTimerTick_call:
|
||||
rcall timerRunTimers
|
||||
rcall onEvery100ms
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Set timer value.
|
||||
; @routine Timer_SetValue @global
|
||||
;
|
||||
; Set timer value.
|
||||
; Setting a timer to 0 effectively stops the timer.
|
||||
;
|
||||
; IN:
|
||||
; - r16: new timer value (low)
|
||||
; - r17: new timer value (high)
|
||||
; - X : pointer to timer value in SRAM
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: X
|
||||
; @param r16 new timer value (low)
|
||||
; @param r17 new timer value (high)
|
||||
; @param X pointer to timer value in SRAM
|
||||
; @clobbers X
|
||||
|
||||
Timer_SetValue:
|
||||
push r15
|
||||
@@ -171,17 +121,17 @@ Timer_SetValue:
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine Timer_SetValueTo1s @global
|
||||
;
|
||||
; Set timer value to 1s.
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to timer value in SRAM
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: X
|
||||
; @param X pointer to timer value in SRAM
|
||||
; @clobbers X
|
||||
|
||||
Timer_SetValueTo1s:
|
||||
push r16
|
||||
@@ -192,10 +142,18 @@ Timer_SetValueTo1s:
|
||||
pop r17
|
||||
pop r16
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine timerInitTimers
|
||||
;
|
||||
; Init timers in table.
|
||||
;
|
||||
; @clobbers all
|
||||
|
||||
timerInitTimers:
|
||||
ldi zl, LOW(timerList*2)
|
||||
ldi zh, HIGH(timerList*2)
|
||||
@@ -220,13 +178,18 @@ timerInitTimers_writeInitial:
|
||||
|
||||
timerInitTimers_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine timerRunTimers
|
||||
;
|
||||
; Run timers in table.
|
||||
;
|
||||
; @clobbers all
|
||||
|
||||
timerRunTimers:
|
||||
ldi xl, LOW(timerModuleCounterSecs)
|
||||
ldi xh, HIGH(timerModuleCounterSecs)
|
||||
rcall Utils_IncrementCounter32
|
||||
ldi zl, LOW(timerList*2)
|
||||
ldi zh, HIGH(timerList*2)
|
||||
timerRunTimers_loop:
|
||||
@@ -260,20 +223,23 @@ timerRunTimers_reachedZero:
|
||||
rjmp timerRunTimers_loop
|
||||
timerRunTimers_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; read time table entry.
|
||||
; @routine timerReadTableEntry
|
||||
;
|
||||
; IN:
|
||||
; - Z : pointer to time list entry (suitable for LPM)
|
||||
; read timer table entry.
|
||||
;
|
||||
; @param Z pointer to time list entry (suitable for LPM)
|
||||
; OUT:
|
||||
; - r19:r18: handler routine
|
||||
; - X : SRAM address for counter
|
||||
; - r21:r20: initial value
|
||||
; - r22 : flags
|
||||
; - r23 : reserved
|
||||
; @return r19:r18 handler routine
|
||||
; @return X SRAM address for counter
|
||||
; @return r21:r20 initial value
|
||||
; @return r22 flags
|
||||
; @return r23 reserved
|
||||
|
||||
timerReadTableEntry:
|
||||
lpm xl, Z+ ; SRAM address of counter
|
||||
lpm xh, Z+
|
||||
@@ -284,45 +250,19 @@ timerReadTableEntry:
|
||||
lpm r20, Z+ ; initial value
|
||||
lpm r21, Z+
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine timerCallR19R18
|
||||
; Call route at address r19:r18
|
||||
|
||||
timerCallR19R18:
|
||||
push r18
|
||||
push r19
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; OC0A interrupt handler
|
||||
;
|
||||
; Called every 100 milliseconds, increments timerTicksSinceLastRun. The rest is done outside ISR
|
||||
; in Timer_Run.
|
||||
|
||||
timerIrqOC0A:
|
||||
push r15
|
||||
in r15, SREG
|
||||
|
||||
push r24
|
||||
push r25
|
||||
lds r24, timerTicksSinceLastRun
|
||||
lds r25, timerTicksSinceLastRun+1
|
||||
adiw r25:r24, 1
|
||||
sts timerTicksSinceLastRun, r24
|
||||
sts timerTicksSinceLastRun+1, r25
|
||||
|
||||
lds r24, timerInterrupts
|
||||
lds r25, timerInterrupts+1
|
||||
adiw r25:r24, 1
|
||||
sts timerInterrupts, r24
|
||||
sts timerInterrupts+1, r25
|
||||
|
||||
pop r25
|
||||
pop r24
|
||||
out SREG, r15
|
||||
pop r15
|
||||
reti
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user