aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster/fsm-wdt.c
diff options
context:
space:
mode:
authorSelene ToyKeeper2019-11-24 16:21:40 -0700
committerSelene ToyKeeper2019-11-24 16:21:40 -0700
commit30510a7948815f3092b8a2eff3321ad85ed5c480 (patch)
tree4a1b68628c779bf4092a64ae027917529d03e158 /spaghetti-monster/fsm-wdt.c
parentmerged changes from fsm branch, including version check and stuck-button safety (diff)
parentadded -fwhole-program gcc flag, suggested by Agro. Signficantly reduces ROM ... (diff)
downloadanduril-30510a7948815f3092b8a2eff3321ad85ed5c480.tar.gz
anduril-30510a7948815f3092b8a2eff3321ad85ed5c480.tar.bz2
anduril-30510a7948815f3092b8a2eff3321ad85ed5c480.zip
merged from upstream fsm branch to get a whole bunch of kernel-level improvements
Diffstat (limited to 'spaghetti-monster/fsm-wdt.c')
-rw-r--r--spaghetti-monster/fsm-wdt.c73
1 files changed, 39 insertions, 34 deletions
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index 6e61e87..0c49a75 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -82,46 +82,52 @@ inline void WDT_off()
// clock tick -- this runs every 16ms (62.5 fps)
ISR(WDT_vect) {
+ irq_wdt = 1; // WDT event happened
+}
+
+void WDT_inner() {
+ irq_wdt = 0; // WDT event handled; reset flag
+
static uint8_t adc_trigger = 0;
- #ifdef TICK_DURING_STANDBY
- f_wdt = 1; // WDT event happened
+ // cache this here to reduce ROM size, because it's volatile
+ uint16_t ticks_since_last = ticks_since_last_event;
+ // increment, but loop from max back to half
+ ticks_since_last = (ticks_since_last + 1) \
+ | (ticks_since_last & 0x8000);
+ // copy back to the original
+ ticks_since_last_event = ticks_since_last;
+
+ // detect and emit button change events (even during standby)
+ uint8_t was_pressed = button_last_state;
+ uint8_t pressed = button_is_pressed();
+ if (was_pressed != pressed) {
+ go_to_standby = 0;
+ PCINT_inner(pressed);
+ }
+ // cache again, in case the value changed
+ ticks_since_last = ticks_since_last_event;
- static uint16_t sleep_counter = 0;
+ #ifdef TICK_DURING_STANDBY
// handle standby mode specially
if (go_to_standby) {
// emit a halfsleep tick, and process it
- emit(EV_sleep_tick, sleep_counter);
- // wrap around from 65535 to 32768, not 0
- sleep_counter = (sleep_counter + 1) | (sleep_counter & 0x8000);
+ emit(EV_sleep_tick, ticks_since_last);
process_emissions();
- #if defined(USE_SLEEP_LVP)
+ #ifndef USE_SLEEP_LVP
+ return; // no sleep LVP needed if nothing drains power while off
+ #else
// stop here, usually... but proceed often enough for sleep LVP to work
- if (0 != (sleep_counter & 0x7f)) return;
+ if (0 != (ticks_since_last & 0x7f)) return;
+
adc_trigger = 255; // make sure a measurement will happen
- #else
- return; // no sleep LVP needed if nothing drains power while off
+ ADC_on(); // enable ADC voltage measurement functions temporarily
#endif
}
- else { sleep_counter = 0; }
+ else { // button handling should only happen while awake
#endif
- // detect and emit button change events
- uint8_t was_pressed = button_last_state;
- uint8_t pressed = button_is_pressed();
- if (was_pressed != pressed) PCINT_inner(pressed);
-
- // cache this here to reduce ROM size, because it's volatile
- uint16_t ticks_since_last = ticks_since_last_event;
-
- // increment, but loop from max back to half
- //if (ticks_since_last < 0xff) ticks_since_last ++;
- ticks_since_last = (ticks_since_last + 1) \
- | (ticks_since_last & 0x8000);
- // copy back to the original
- ticks_since_last_event = ticks_since_last;
-
// if time since last event exceeds timeout,
// append timeout to current event sequence, then
// send event to current state callback
@@ -141,9 +147,9 @@ ISR(WDT_vect) {
emit_current_event(ticks_since_last);
}
// has button been down long enough to become a "hold"?
+ // (first frame of a "hold" event)
else {
if (ticks_since_last >= HOLD_TIMEOUT) {
- //ticks_since_last_event = 0;
current_event |= B_HOLD;
emit_current_event(0);
}
@@ -156,28 +162,27 @@ ISR(WDT_vect) {
// no timeout required when releasing a long-press
// TODO? move this logic to PCINT() and simplify things here?
if (current_event & B_HOLD) {
- //emit_current_event(0); // should have been emitted by PCINT
+ //emit_current_event(0); // should have been emitted by PCINT_inner()
empty_event_sequence();
}
// end and clear event after release timeout
else if (ticks_since_last >= RELEASE_TIMEOUT) {
current_event |= B_TIMEOUT;
- //ticks_since_last_event = 0;
emit_current_event(0);
empty_event_sequence();
}
}
+ #ifdef TICK_DURING_STANDBY
+ }
+ #endif
+
#if defined(USE_LVP) || defined(USE_THERMAL_REGULATION)
// start a new ADC measurement every 4 ticks
adc_trigger ++;
if (0 == (adc_trigger & 3)) {
- #if defined(TICK_DURING_STANDBY) && defined(USE_SLEEP_LVP)
- // we shouldn't be here unless it woke up for a LVP check...
- // so enable ADC voltage measurement functions temporarily
- if (go_to_standby) ADC_on();
- #endif
ADC_start_measurement();
+ irq_adc_stable = 0;
adcint_enable = 1;
}
#endif