5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
24 volatile tmr10ms_t g_tmr10ms
;
26 #if TIMERS > MAX_TIMERS
27 #error "Timers cannot exceed " .. MAX_TIMERS
30 TimerState timersStates
[TIMERS
] = { { 0 } };
32 void timerReset(uint8_t idx
)
34 TimerState
& timerState
= timersStates
[idx
];
35 timerState
.state
= TMR_OFF
; // is changed to RUNNING dep from mode
36 timerState
.val
= g_model
.timers
[idx
].start
;
37 timerState
.val_10ms
= 0 ;
40 void timerSet(int idx
, int val
)
42 TimerState
& timerState
= timersStates
[idx
];
43 timerState
.state
= TMR_OFF
; // is changed to RUNNING dep from mode
45 timerState
.val_10ms
= 0 ;
50 for (uint8_t i
=0; i
<TIMERS
; i
++) {
51 if (g_model
.timers
[i
].persistent
) {
52 timersStates
[i
].val
= g_model
.timers
[i
].value
;
59 for (uint8_t i
=0; i
<TIMERS
; i
++) {
60 if (g_model
.timers
[i
].persistent
) {
61 TimerState
*timerState
= &timersStates
[i
];
62 if (g_model
.timers
[i
].value
!= (uint16_t)timerState
->val
) {
63 g_model
.timers
[i
].value
= timerState
->val
;
64 storageDirty(EE_MODEL
);
70 #define THR_TRG_TRESHOLD 13 // approximately 10% full throttle
72 void evalTimers(int16_t throttle
, uint8_t tick10ms
)
74 for (uint8_t i
=0; i
<TIMERS
; i
++) {
75 tmrmode_t timerMode
= g_model
.timers
[i
].mode
;
76 tmrstart_t timerStart
= g_model
.timers
[i
].start
;
77 TimerState
* timerState
= &timersStates
[i
];
80 if ((timerState
->state
== TMR_OFF
) && (timerMode
!= TMRMODE_THR_TRG
)) {
81 timerState
->state
= TMR_RUNNING
;
86 if (timerMode
== TMRMODE_THR_REL
) {
88 timerState
->sum
+= throttle
;
91 if ((timerState
->val_10ms
+= tick10ms
) >= 100) {
92 if (timerState
->val
== TIMER_MAX
) break;
93 if (timerState
->val
== TIMER_MIN
) break;
95 timerState
->val_10ms
-= 100 ;
96 tmrval_t newTimerVal
= timerState
->val
;
97 if (timerStart
) newTimerVal
= timerStart
- newTimerVal
;
99 if (timerMode
== TMRMODE_ABS
) {
102 else if (timerMode
== TMRMODE_THR
) {
103 if (throttle
) newTimerVal
++;
105 else if (timerMode
== TMRMODE_THR_REL
) {
106 if ((timerState
->sum
/timerState
->cnt
) >= 128) { // throttle was normalized to 0 to 128 value (throttle/64*2 (because - range is added as well)
107 newTimerVal
++; // add second used of throttle
108 timerState
->sum
-= 128*timerState
->cnt
;
112 else if (timerMode
== TMRMODE_THR_TRG
) {
113 // we can't rely on (throttle || newTimerVal > 0) as a detection if timer should be running
114 // because having persistent timer brakes this rule
115 if ((throttle
> THR_TRG_TRESHOLD
) && timerState
->state
== TMR_OFF
) {
116 timerState
->state
= TMR_RUNNING
; // start timer running
119 // TRACE("Timer[%d] THr triggered", i);
121 if (timerState
->state
!= TMR_OFF
) newTimerVal
++;
124 if (timerMode
> 0) timerMode
-= (TMRMODE_COUNT
-1);
125 if (getSwitch(timerMode
)) {
130 switch (timerState
->state
) {
132 if (timerStart
&& newTimerVal
>=(tmrval_t
)timerStart
) {
133 AUDIO_TIMER_ELAPSED(i
);
134 timerState
->state
= TMR_NEGATIVE
;
135 // TRACE("Timer[%d] negative", i);
139 if (newTimerVal
>= (tmrval_t
)timerStart
+ MAX_ALERT_TIME
) {
140 timerState
->state
= TMR_STOPPED
;
141 // TRACE("Timer[%d] stopped state at %d", i, newTimerVal);
146 if (timerStart
) newTimerVal
= timerStart
- newTimerVal
; // if counting backwards - display backwards
148 if (newTimerVal
!= timerState
->val
) {
149 timerState
->val
= newTimerVal
;
150 if (timerState
->state
== TMR_RUNNING
) {
151 if (g_model
.timers
[i
].countdownBeep
&& g_model
.timers
[i
].start
) {
152 AUDIO_TIMER_COUNTDOWN(i
, newTimerVal
);
154 if (g_model
.timers
[i
].minuteBeep
&& (newTimerVal
% 60)==0) {
155 AUDIO_TIMER_MINUTE(newTimerVal
);
156 // TRACE("Timer[%d] %d minute announcement", i, newTimerVal/60);