From 8c13fd82557dadbe81023c534cd19c31ec40bde4 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Tue, 12 Dec 2017 15:22:42 -0700 Subject: Debouncing finally works (at least, it does on my two test hosts). --- spaghetti-monster/fsm-pcint.c | 40 +++++++++++++++++----------------------- spaghetti-monster/fsm-pcint.h | 1 - spaghetti-monster/fsm-standby.c | 2 +- spaghetti-monster/fsm-wdt.c | 38 +++++++------------------------------- 4 files changed, 25 insertions(+), 56 deletions(-) (limited to 'spaghetti-monster') diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c index c04375a..722cb88 100644 --- a/spaghetti-monster/fsm-pcint.c +++ b/spaghetti-monster/fsm-pcint.c @@ -24,20 +24,19 @@ #include uint8_t button_is_pressed() { - // debounce a little - uint8_t highcount = 0; - // measure for 16/64ths of a ms - for(uint8_t i=0; i (BP_SAMPLES/2)); - //button_was_pressed = result; - return result; + while ((readings != 0) && (readings != 0xFFFFFFFF)); + button_last_state = readings; + return readings; } inline void PCINT_on() { @@ -59,20 +58,15 @@ ISR(PCINT0_vect) { //DEBUG_FLASH; - /* - uint8_t pressed; + // as it turns out, it's more reliable to detect pin changes from WDT + // because PCINT itself tends to double-tap when connected to a + // noisy / bouncy switch (so the content of this function has been + // moved to a separate function, called from WDT only) + // PCINT_inner(button_is_pressed()); - // add event to current sequence - pressed = button_is_pressed(); - PCINT_inner(pressed); - */ - if (! PCINT_since_WDT) { - PCINT_since_WDT = 1; - PCINT_inner(button_is_pressed()); - } } -// should only be called from PCINT and WDT +// should only be called from PCINT and/or WDT // (is a separate function to reduce code duplication) void PCINT_inner(uint8_t pressed) { uint8_t pushed; diff --git a/spaghetti-monster/fsm-pcint.h b/spaghetti-monster/fsm-pcint.h index a94fc82..ec3ae4b 100644 --- a/spaghetti-monster/fsm-pcint.h +++ b/spaghetti-monster/fsm-pcint.h @@ -23,7 +23,6 @@ //static volatile uint8_t button_was_pressed; #define BP_SAMPLES 32 volatile uint8_t button_last_state; -volatile uint8_t PCINT_since_WDT; uint8_t button_is_pressed(); inline void PCINT_on(); inline void PCINT_off(); diff --git a/spaghetti-monster/fsm-standby.c b/spaghetti-monster/fsm-standby.c index eb631d6..b90ccea 100644 --- a/spaghetti-monster/fsm-standby.c +++ b/spaghetti-monster/fsm-standby.c @@ -37,7 +37,7 @@ void sleep_until_eswitch_pressed() // make sure switch isn't currently pressed while (button_is_pressed()) {} empty_event_sequence(); // cancel pending input on suspend - PCINT_since_WDT = 0; // ensure PCINT won't ignore itself + //PCINT_since_WDT = 0; // ensure PCINT won't ignore itself PCINT_on(); // wake on e-switch event diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c index bee2914..777bef0 100644 --- a/spaghetti-monster/fsm-wdt.c +++ b/spaghetti-monster/fsm-wdt.c @@ -45,47 +45,23 @@ inline void WDT_off() // clock tick -- this runs every 16ms (62.5 fps) ISR(WDT_vect) { + // 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); + //if (ticks_since_last_event < 0xff) 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); - // just in case the pin change interrupt missed something - uint8_t le_num = last_event_num(); - uint8_t last_event = 0; - if (le_num >= 1) last_event = current_event[le_num-1]; - uint8_t pressed = button_is_pressed(); - uint8_t was_pressed_before = (last_event == A_PRESS) || (last_event == A_HOLD); - //if (pressed != button_last_state) { - if (pressed != was_pressed_before) { - PCINT_inner(pressed); - /* - uint8_t pushed; - if (pressed) { - pushed = push_event(A_PRESS); - } else { - pushed = push_event(A_RELEASE); - } - - // check if sequence matches any defined sequences - // if so, send event to current state callback - if (pushed) { - button_last_state = pressed; - emit_current_event(0); - } - */ - } - PCINT_since_WDT = 0; - // if time since last event exceeds timeout, // append timeout to current event sequence, then // send event to current state callback // preload recent events - //uint8_t le_num = last_event_num(); - le_num = last_event_num(); - //uint8_t last_event = 0; - last_event = 0; + 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]; -- cgit v1.2.3