avr: improved timer module.
- simplified timer handling. still using cascading counters but in an extendable way - added onEvery5m while on it - renamed everyMinute to every1m (unifies routine names) - send network stats every 5m, not every minute
This commit is contained in:
@@ -279,7 +279,15 @@ onEvery30s:
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Called every minute. Add your routine calls here. No arguments, no results.
|
; Called every minute. Add your routine calls here. No arguments, no results.
|
||||||
|
|
||||||
onEveryMinute:
|
onEvery1m:
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; Called every 5 minutes. Add your routine calls here. No arguments, no results.
|
||||||
|
|
||||||
|
onEvery5m:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -326,28 +326,39 @@ onEvery30s:
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Called every minute. Add your routine calls here. No arguments, no results.
|
; Called every minute. Add your routine calls here. No arguments, no results.
|
||||||
|
|
||||||
onEveryMinute:
|
onEvery1m:
|
||||||
#ifdef MODULES_COM
|
#ifdef MODULES_COM
|
||||||
lds r16, comAddress ; do we have an address assigned?
|
lds r16, comAddress ; do we have an address assigned?
|
||||||
tst r16
|
tst r16
|
||||||
breq onEveryMinute_l1 ; no, do nothing
|
breq onEvery1m_l1 ; no, do nothing
|
||||||
|
|
||||||
; will later send this only every hour or so
|
; will later send this only every hour or so
|
||||||
|
ldi r16, 0xff ; send device info to everybody
|
||||||
|
rcall CPRO_EnqueueDevice
|
||||||
|
onEvery1m_l1:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; Called every 5 minutes. Add your routine calls here. No arguments, no results.
|
||||||
|
|
||||||
|
onEvery5m:
|
||||||
|
|
||||||
|
#ifdef MODULES_COM
|
||||||
|
; will later send these only every hour or so
|
||||||
ldi r16, 0xff ; send stats to everybody
|
ldi r16, 0xff ; send stats to everybody
|
||||||
rcall CPRO_EnqueueComSendStats
|
rcall CPRO_EnqueueComSendStats
|
||||||
|
|
||||||
ldi r16, 0xff ; send recv to everybody
|
ldi r16, 0xff ; send recv to everybody
|
||||||
rcall CPRO_EnqueueComRecvStats
|
rcall CPRO_EnqueueComRecvStats
|
||||||
|
|
||||||
ldi r16, 0xff ; send device info to everybody
|
|
||||||
rcall CPRO_EnqueueDevice
|
|
||||||
onEveryMinute_l1:
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Called every 15 minutes. Add your routine calls here. No arguments, no results.
|
; Called every 15 minutes. Add your routine calls here. No arguments, no results.
|
||||||
|
|
||||||
|
|||||||
260
avr/timer.asm
260
avr/timer.asm
@@ -23,18 +23,11 @@
|
|||||||
.dseg
|
.dseg
|
||||||
|
|
||||||
timerModuleData:
|
timerModuleData:
|
||||||
timerModuleTickCounter: .byte 1 ; only low byte used
|
timerModuleTickCounter: .byte 1
|
||||||
timerModuleFlags: .byte 1
|
timerModuleFlags: .byte 1
|
||||||
timerModuleCounterSecs: .byte 4
|
timerModuleCounterSecs: .byte 4
|
||||||
|
|
||||||
timerModuleDerivedCounters: ; order of the following vars matters!!
|
timerModuleDerivedCounters: .byte 9 ; must correspond to entries in timer table!
|
||||||
timerModuleCounterFor10s: .byte 1 ; change Timer_IncrementCounters when changing the
|
|
||||||
timerModuleCounterFor1m: .byte 1 ; order here!
|
|
||||||
timerModuleCounterFor15m: .byte 1
|
|
||||||
timerModuleCounterFor30m: .byte 1
|
|
||||||
timerModuleCounterFor1h: .byte 1
|
|
||||||
timerModuleCounterFor12h: .byte 1
|
|
||||||
timerModuleCounterFor1d: .byte 1
|
|
||||||
|
|
||||||
timerModuleData_end:
|
timerModuleData_end:
|
||||||
|
|
||||||
@@ -47,8 +40,22 @@ timerModuleData_end:
|
|||||||
.cseg
|
.cseg
|
||||||
|
|
||||||
|
|
||||||
|
; number of entries here must be equal to bytes in timerModuleDerivedCounters!
|
||||||
|
timerTable:
|
||||||
|
.db 10, 0, LOW(onEvery10s), HIGH(onEvery10s) ; 10s: overflow after 10*1s (1)
|
||||||
|
.db 3, 0, LOW(onEvery30s), HIGH(onEvery30s) ; 30s: overflow after 3*10s (2)
|
||||||
|
.db 2, 0, LOW(onEvery1m), HIGH(onEvery1m) ; 1m : overflow after 2*30s (3)
|
||||||
|
.db 5, 0, LOW(onEvery5m), HIGH(onEvery5m) ; 5m : overflow after 5*1m (4)
|
||||||
|
.db 3, 0, LOW(onEvery15m), HIGH(onEvery15m) ; 15m: overflow after 3*5m (5)
|
||||||
|
.db 2, 0, LOW(onEvery30m), HIGH(onEvery30m) ; 30m: overflow after 2*15m (6)
|
||||||
|
.db 2, 0, LOW(onEvery1h), HIGH(onEvery1h) ; 1h: overflow after 2*30m (7)
|
||||||
|
.db 12, 0, LOW(onEvery12h), HIGH(onEvery12h) ; 12h: overflow after 12*1h (8)
|
||||||
|
.db 2, 0, LOW(onEvery1d), HIGH(onEvery1d) ; 1d: overflow after 2*12h (9)
|
||||||
|
.db 0, 0
|
||||||
|
|
||||||
; ***************************************************************************
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
; Timer_Init
|
; Timer_Init
|
||||||
;
|
;
|
||||||
; IN:
|
; IN:
|
||||||
@@ -131,177 +138,114 @@ Timer_Run_100ms_passed:
|
|||||||
sec
|
sec
|
||||||
ret
|
ret
|
||||||
Timer_Run_1s_passed:
|
Timer_Run_1s_passed:
|
||||||
clr r19 ; flags for additional callbacks to be called
|
rcall timerIncrementCounters ; 1s passed, handle cascading counters, get number of callable handlers
|
||||||
rcall Timer_IncrementCounters ; 1s passed, handle depending counters, sample callback flags
|
|
||||||
out SREG, r15 ; restore global IRQ flag
|
out SREG, r15 ; restore global IRQ flag
|
||||||
mov r16, r19
|
rcall timerCallFirstOnEveryHandlers
|
||||||
rcall Timer_CallOnEveryHandlers
|
|
||||||
sec
|
sec
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; Call "onEvery*" handlers according to given flags.
|
; Increment cascading timer counters.
|
||||||
;
|
;
|
||||||
|
; This routine starts with the first cascaded counter and increments it.
|
||||||
|
; If that counter value does not overflow (according to timer table entry) then
|
||||||
|
; handling the timer table is stopped.
|
||||||
|
; Otherwise the return value is incremented and the next counter entry is inspected
|
||||||
|
; until the full table is handled.
|
||||||
|
;
|
||||||
|
; The result value has to be interpreted as the number of entries started at the first
|
||||||
|
; which have overflowed.
|
||||||
|
;
|
||||||
|
; Example: A return value of 1 means that the first entry overflowed, meaning that 10s have
|
||||||
|
; elapsed.
|
||||||
|
; A return value of 2 means that the first entry overflowed (i.e. 10s elapsed) and also the nex
|
||||||
|
; entry overflowed (i.e. also 30s elapsed).
|
||||||
|
;
|
||||||
; IN:
|
; IN:
|
||||||
; - R16: flags
|
; - nothing
|
||||||
|
; OUT:
|
||||||
|
; - R16: number of timer table entries which caused an overflow
|
||||||
|
; REGS: R16, R17, R18, X, Z
|
||||||
|
|
||||||
|
timerIncrementCounters:
|
||||||
|
ldi xl, LOW(timerModuleDerivedCounters) ; points to first counter: timerModuleCounterFor10s
|
||||||
|
ldi xh, HIGH(timerModuleDerivedCounters)
|
||||||
|
ldi zl, LOW(timerTable*2)
|
||||||
|
ldi zh, HIGH(timerTable*2)
|
||||||
|
|
||||||
|
clr r18
|
||||||
|
|
||||||
|
timerIncrementCounters_loop:
|
||||||
|
lpm r17, Z ; overflow value
|
||||||
|
tst r17
|
||||||
|
breq timerIncrementCounters_done ; end of list
|
||||||
|
ld r16, X ; get current counter value
|
||||||
|
inc r16
|
||||||
|
cp r16, r17 ; compare against overflow value
|
||||||
|
brcs timerIncrementCounters_counterSmaller
|
||||||
|
clr r16 ; overflow occurred
|
||||||
|
st X+, r16
|
||||||
|
; next
|
||||||
|
inc r18
|
||||||
|
adiw zh:zl, 4
|
||||||
|
rjmp timerIncrementCounters_loop
|
||||||
|
|
||||||
|
timerIncrementCounters_counterSmaller:
|
||||||
|
st X, r16
|
||||||
|
timerIncrementCounters_done:
|
||||||
|
mov r16, r18
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------------------
|
||||||
|
; Call first N handlers from the timer table.
|
||||||
|
;
|
||||||
|
; IN:
|
||||||
|
; - R16: number of handlers to call (returned by timerIncrementCounters)
|
||||||
; OUT:
|
; OUT:
|
||||||
; - nothing
|
; - nothing
|
||||||
; REGS: depending on called routines, expect clobbering of all registers
|
; REGS: depening on handler called (expect all registers to be clobbered)
|
||||||
|
|
||||||
Timer_CallOnEveryHandlers:
|
timerCallFirstOnEveryHandlers:
|
||||||
push r16
|
push r16
|
||||||
rcall onEvery100ms ; always call this one
|
rcall onEvery100ms ; always call this one
|
||||||
rcall onEverySecond ; and this
|
rcall onEverySecond ; and this
|
||||||
pop r16
|
pop r16
|
||||||
tst r16 ; any flag set?
|
|
||||||
breq Timer_CallOnEveryHandlers_done ; nope, nothing more to call
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_10S
|
|
||||||
breq Timer_CallOnEveryHandlers_l1
|
|
||||||
push r16
|
|
||||||
rcall onEvery10s
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l1:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_30S
|
|
||||||
breq Timer_CallOnEveryHandlers_l2
|
|
||||||
push r16
|
|
||||||
rcall onEvery30s
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l2:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_1M
|
|
||||||
breq Timer_CallOnEveryHandlers_l3
|
|
||||||
push r16
|
|
||||||
rcall onEveryMinute
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l3:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_15M
|
|
||||||
breq Timer_CallOnEveryHandlers_l4
|
|
||||||
push r16
|
|
||||||
rcall onEvery15m
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l4:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_30M
|
|
||||||
breq Timer_CallOnEveryHandlers_l5
|
|
||||||
push r16
|
|
||||||
rcall onEvery30m
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l5:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_1H
|
|
||||||
breq Timer_CallOnEveryHandlers_l6
|
|
||||||
push r16
|
|
||||||
rcall onEvery1h
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l6:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_12H
|
|
||||||
breq Timer_CallOnEveryHandlers_l7
|
|
||||||
push r16
|
|
||||||
rcall onEvery12h
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_l7:
|
|
||||||
mov r17, r16
|
|
||||||
andi r17, TIMER_CALLBACK_1D
|
|
||||||
breq Timer_CallOnEveryHandlers_done
|
|
||||||
push r16
|
|
||||||
rcall onEvery1d
|
|
||||||
pop r16
|
|
||||||
Timer_CallOnEveryHandlers_done:
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
tst r16
|
||||||
|
breq timerCallFirstOnEveryHandlers_done
|
||||||
; ---------------------------------------------------------------------------
|
|
||||||
; Increments the list of dependent counters and sets flag in R19 accordingly.
|
|
||||||
;
|
|
||||||
; IN:
|
|
||||||
; - R19: flags to add to
|
|
||||||
; OUT:
|
|
||||||
; - R19: flags for callback handlers to be called
|
|
||||||
; REGS: R16, R19, X
|
|
||||||
|
|
||||||
Timer_IncrementCounters:
|
|
||||||
ldi xl, LOW(timerModuleDerivedCounters) ; points to first counter: timerModuleCounterFor10s
|
|
||||||
ldi xh, HIGH(timerModuleDerivedCounters)
|
|
||||||
clr r19
|
|
||||||
|
|
||||||
ldi r17, 10 ; overflow after 10s
|
ldi zl, LOW(timerTable*2)
|
||||||
ldi r18, TIMER_CALLBACK_10S
|
ldi zh, HIGH(timerTable*2)
|
||||||
rcall timerInc8CheckVar
|
|
||||||
brcc Timer_IncrementCounters_done
|
|
||||||
|
|
||||||
ldi r17, 3 ; overflow after 3*10s
|
|
||||||
ldi r18, TIMER_CALLBACK_30S
|
|
||||||
rcall timerInc8CheckVar
|
|
||||||
brcc Timer_IncrementCounters_done
|
|
||||||
|
|
||||||
ldi r17, 2 ; overflow after 2*30s
|
timerCallFirstOnEveryHandlers_loop:
|
||||||
ldi r18, TIMER_CALLBACK_1M
|
lpm r17, Z ; overflow value
|
||||||
rcall timerInc8CheckVar
|
tst r17 ; 0?
|
||||||
brcc Timer_IncrementCounters_done
|
breq timerCallFirstOnEveryHandlers_done ; yes: end of list
|
||||||
|
adiw zh:zl, 2 ; skip to handler address
|
||||||
|
lpm r20, Z+ ; read handler address
|
||||||
|
lpm r21, Z+
|
||||||
|
push r16 ; call handler
|
||||||
|
push zl
|
||||||
|
push zh
|
||||||
|
rcall timerCallR21R20
|
||||||
|
pop zh
|
||||||
|
pop zl
|
||||||
|
pop r16
|
||||||
|
dec r16
|
||||||
|
brne timerCallFirstOnEveryHandlers_loop
|
||||||
|
|
||||||
ldi r17, 30 ; overflow after 30*1m
|
timerCallFirstOnEveryHandlers_done:
|
||||||
ldi r18, TIMER_CALLBACK_30M
|
|
||||||
rcall timerInc8CheckVar
|
|
||||||
brcc Timer_IncrementCounters_done
|
|
||||||
|
|
||||||
ldi r17, 2 ; overflow after 2*30m
|
|
||||||
ldi r18, TIMER_CALLBACK_1H
|
|
||||||
rcall timerInc8CheckVar
|
|
||||||
brcc Timer_IncrementCounters_done
|
|
||||||
|
|
||||||
ldi r17, 12 ; overflow after 12*1h
|
|
||||||
ldi r18, TIMER_CALLBACK_12H
|
|
||||||
rcall timerInc8CheckVar
|
|
||||||
brcc Timer_IncrementCounters_done
|
|
||||||
|
|
||||||
ldi r17, 2 ; overflow after 2*12h
|
|
||||||
ldi r18, TIMER_CALLBACK_1D
|
|
||||||
rcall timerInc8CheckVar
|
|
||||||
brcc Timer_IncrementCounters_done
|
|
||||||
Timer_IncrementCounters_done:
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
timerCallR21R20:
|
||||||
; ---------------------------------------------------------------------------
|
push r20
|
||||||
; Increment an 8 bit counter and check result.
|
push r21
|
||||||
;
|
|
||||||
; If the incremented counter is equal or greater than the given value the counter
|
|
||||||
; is reset, the given flag is ORed to the flags and carry flag is set on return.
|
|
||||||
; Otherwise the counter is just incremented and carry flag cleared.
|
|
||||||
;
|
|
||||||
; IN:
|
|
||||||
; - X: ptr to counter
|
|
||||||
; - R17: value to compare against
|
|
||||||
; - R18: flag to add on overflow
|
|
||||||
; - R19: flags to add to
|
|
||||||
; OUT:
|
|
||||||
; - CFLAG set if overflow occurred, cleared otherwise
|
|
||||||
; - X: points to next counter (advanced by one byte)
|
|
||||||
; REGS: R16, R19, X
|
|
||||||
|
|
||||||
timerInc8CheckVar:
|
|
||||||
ld r16, X
|
|
||||||
inc r16
|
|
||||||
cp r16, r17
|
|
||||||
brcs timerInc8CheckVar_stillSmaller
|
|
||||||
clr r16
|
|
||||||
st X+, r16
|
|
||||||
or r19, r18
|
|
||||||
sec
|
|
||||||
ret
|
ret
|
||||||
timerInc8CheckVar_stillSmaller:
|
|
||||||
st X+, r16
|
|
||||||
clc
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user