From e942fa7c47f446891e3bb0a07316d22cc32c00c2 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sun, 11 Nov 2018 05:14:47 -0700 Subject: Rewrote the event system to use a single byte for each event instead of an array of actions. Not thoroughly tested yet, not done yet, have only updated Anduril to fit, and only partially. --- spaghetti-monster/fsm-wdt.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) (limited to 'spaghetti-monster/fsm-wdt.c') diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c index e8419bc..cfff1fa 100644 --- a/spaghetti-monster/fsm-wdt.c +++ b/spaghetti-monster/fsm-wdt.c @@ -85,15 +85,8 @@ ISR(WDT_vect) { // append timeout to current event sequence, then // send event to current state callback - // preload recent events - uint8_t le_num = last_event_num(); - uint8_t last_event = 0; - uint8_t prev_event = 0; - if (le_num >= 1) last_event = current_event[le_num-1]; - if (le_num >= 2) prev_event = current_event[le_num-2]; - // callback on each timer tick - if (last_event == A_HOLD) { + if ((current_event & B_FLAGS) == (B_HOLD | B_PRESS)) { emit(EV_tick, 0); // override tick counter while holding button } else { @@ -101,29 +94,32 @@ ISR(WDT_vect) { } // user held button long enough to count as a long click? - if (last_event == A_PRESS) { - if (ticks_since_last_event >= HOLD_TIMEOUT) { - push_event(A_HOLD); - emit_current_event(0); + if (current_event & B_PRESS) { + // during a "hold", send a hold event each tick, with a timer + if (current_event & B_HOLD) { + emit_current_event(ticks_since_last_event); + } + // has button been down long enough to become a "hold"? + else { + if (ticks_since_last_event >= HOLD_TIMEOUT) { + current_event |= B_HOLD; + emit_current_event(0); + } } } - // user is still holding button, so tick - else if (last_event == A_HOLD) { - emit_current_event(ticks_since_last_event); - } - - // detect completed button presses with expired timeout - else if (last_event == A_RELEASE) { + // event in progress, but button not currently down + else if (current_event) { + // "hold" event just ended // no timeout required when releasing a long-press // TODO? move this logic to PCINT() and simplify things here? - if (prev_event == A_HOLD) { + if (current_event & B_HOLD) { //emit_current_event(0); // should have been emitted by PCINT empty_event_sequence(); } // end and clear event after release timeout else if (ticks_since_last_event >= RELEASE_TIMEOUT) { - push_event(A_RELEASE_TIMEOUT); + current_event |= B_TIMEOUT; emit_current_event(0); empty_event_sequence(); } -- cgit v1.2.3 From 6b41b5df92128c8810cbe14fd56258d90c3bb2b2 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sun, 11 Nov 2018 06:09:07 -0700 Subject: Several fixes... - Made momentary+lockout modes smaller and work better. - Fixed buggy timing on hold events; made ticks_since_last_event reset when it should. - Reduced ROM size by caching volatile ticks_since_last_event sometimes. - Swapped what the top Event bit means, because it makes event handlers easier to write. - Made the maximum click event keep triggering if user keeps pressing, instead of dropping everything after the limit. --- spaghetti-monster/fsm-wdt.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'spaghetti-monster/fsm-wdt.c') diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c index cfff1fa..3606c67 100644 --- a/spaghetti-monster/fsm-wdt.c +++ b/spaghetti-monster/fsm-wdt.c @@ -76,32 +76,38 @@ ISR(WDT_vect) { uint8_t pressed = button_is_pressed(); if (was_pressed != pressed) PCINT_inner(pressed); - //if (ticks_since_last_event < 0xff) ticks_since_last_event ++; + // 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_event = (ticks_since_last_event + 1) \ - | (ticks_since_last_event & 0x8000); + //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 // callback on each timer tick - if ((current_event & B_FLAGS) == (B_HOLD | B_PRESS)) { + if ((current_event & B_FLAGS) == (B_CLICK | B_HOLD | B_PRESS)) { emit(EV_tick, 0); // override tick counter while holding button } else { - emit(EV_tick, ticks_since_last_event); + emit(EV_tick, ticks_since_last); } // user held button long enough to count as a long click? if (current_event & B_PRESS) { // during a "hold", send a hold event each tick, with a timer if (current_event & B_HOLD) { - emit_current_event(ticks_since_last_event); + emit_current_event(ticks_since_last); } // has button been down long enough to become a "hold"? else { - if (ticks_since_last_event >= HOLD_TIMEOUT) { + if (ticks_since_last >= HOLD_TIMEOUT) { + //ticks_since_last_event = 0; current_event |= B_HOLD; emit_current_event(0); } @@ -118,8 +124,9 @@ ISR(WDT_vect) { empty_event_sequence(); } // end and clear event after release timeout - else if (ticks_since_last_event >= 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(); } -- cgit v1.2.3 From 69d0d92c7902aa27510ab52a533bf91c37363910 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Sun, 11 Nov 2018 16:01:12 -0700 Subject: Fixed the sleep tick counter wrapping around to 0 instead of 32768. --- spaghetti-monster/fsm-wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'spaghetti-monster/fsm-wdt.c') diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c index 3606c67..d5bbdb9 100644 --- a/spaghetti-monster/fsm-wdt.c +++ b/spaghetti-monster/fsm-wdt.c @@ -64,7 +64,9 @@ ISR(WDT_vect) { // handle standby mode specially if (go_to_standby) { // emit a halfsleep tick, and process it - emit(EV_sleep_tick, sleep_counter++); + emit(EV_sleep_tick, sleep_counter); + // wrap around from 65535 to 32768, not 0 + sleep_counter = (sleep_counter + 1) | (sleep_counter & 0x8000); process_emissions(); return; } -- cgit v1.2.3