From c9cbb8216365b07b9d8d8a9aa7fd521639fc155b Mon Sep 17 00:00:00 2001 From: Matheus Afonso Martins Moreira Date: Sun, 15 Sep 2024 21:00:22 -0300 Subject: [PATCH] Revert merge of PR #437 - debouncing logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a715265af61ecab41eaefe0c5a7e7c806d0db41b, reversing changes made to 9c093f954084e61614cba1c259e4581a87420813. Insidious issues were found in the course of long term testing by the community, and further reviews of the code were not enough to pinpoint the issue and fix it. So for now the appropriate action is to revert these changes while development continues, and possibly merge them back in once they have been stabilized. Tested-on-hardware-by: David Volovskiy Tested-on-hardware-by: CarpeNoctem Tested-on-hardware-by: Krzysztof Gałka <@kshysztof@Discord> --- movement/movement.c | 76 +++++++-------------------------------------- movement/movement.h | 4 --- 2 files changed, 11 insertions(+), 69 deletions(-) diff --git a/movement/movement.c b/movement/movement.c index 617f79a..a8a22bd 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -23,16 +23,6 @@ */ #define MOVEMENT_LONG_PRESS_TICKS 64 -#define DEBOUNCE_TICKS_DOWN 0 -#define DEBOUNCE_TICKS_UP 0 -/* -DEBOUNCE_TICKS_DOWN and DEBOUNCE_TICKS_UP are in terms of fast_cb ticks after a button is pressed. -The logic is that pressed of a button are ignored until the cb_fast_tick function runs this variable amount of times. -Without modifying the code, the cb_fast_tick frequency is 128Hz, or 7.8125ms. -It is not suggested to set this value to one for debouncing, as the callback occurs asynchronously of the button's press, -meaning that if a button was pressed and 7ms passed since th elast time cb_fast_tick was called, then there will be only 812.5us -of debounce time. -*/ #include #include @@ -243,9 +233,6 @@ static inline void _movement_reset_inactivity_countdown(void) { static inline void _movement_enable_fast_tick_if_needed(void) { if (!movement_state.fast_tick_enabled) { movement_state.fast_ticks = 0; - movement_state.debounce_ticks_light = 0; - movement_state.debounce_ticks_alarm = 0; - movement_state.debounce_ticks_mode = 0; watch_rtc_register_periodic_callback(cb_fast_tick, 128); movement_state.fast_tick_enabled = true; } @@ -254,7 +241,6 @@ static inline void _movement_enable_fast_tick_if_needed(void) { static inline void _movement_disable_fast_tick_if_possible(void) { if ((movement_state.light_ticks == -1) && (movement_state.alarm_ticks == -1) && - ((movement_state.debounce_ticks_light + movement_state.debounce_ticks_mode + movement_state.debounce_ticks_alarm) == 0) && ((movement_state.light_down_timestamp + movement_state.mode_down_timestamp + movement_state.alarm_down_timestamp) == 0)) { movement_state.fast_tick_enabled = false; watch_rtc_disable_periodic_callback(128); @@ -610,7 +596,6 @@ void app_wake_from_standby(void) { static void _sleep_mode_app_loop(void) { movement_state.needs_wake = false; - movement_state.ignore_alarm_btn_after_sleep = true; // as long as le_mode_ticks is -1 (i.e. we are in low energy mode), we wake up here, update the screen, and go right back to sleep. while (movement_state.le_mode_ticks == -1) { // we also have to handle background tasks here in the mini-runloop @@ -785,66 +770,29 @@ static movement_event_type_t _figure_out_button_event(bool pin_level, movement_e // now that that's out of the way, handle falling edge uint16_t diff = movement_state.fast_ticks - *down_timestamp; *down_timestamp = 0; + _movement_disable_fast_tick_if_possible(); // any press over a half second is considered a long press. Fire the long-up event if (diff > MOVEMENT_LONG_PRESS_TICKS) return button_down_event_type + 3; else return button_down_event_type + 1; } } -static movement_event_type_t btn_action(bool pin_level, int code, uint16_t *timestamp) { - _movement_reset_inactivity_countdown(); - return _figure_out_button_event(pin_level, code, timestamp); -} - -static void light_btn_action(bool pin_level) { - event.event_type = btn_action(pin_level, EVENT_LIGHT_BUTTON_DOWN, &movement_state.light_down_timestamp); -} - -static void mode_btn_action(bool pin_level) { - event.event_type = btn_action(pin_level, EVENT_MODE_BUTTON_DOWN, &movement_state.mode_down_timestamp); -} - -static void alarm_btn_action(bool pin_level) { - uint8_t event_type = btn_action(pin_level, EVENT_ALARM_BUTTON_DOWN, &movement_state.alarm_down_timestamp); - if (movement_state.ignore_alarm_btn_after_sleep){ - if (event_type == EVENT_ALARM_BUTTON_UP || event_type == EVENT_ALARM_LONG_UP) movement_state.ignore_alarm_btn_after_sleep = false; - return; - } - event.event_type = event_type; -} - -static void debounce_btn_press(uint8_t pin, uint8_t *debounce_ticks, uint16_t *down_timestamp, void (*function)(bool)) { - if (*debounce_ticks == 0) { - bool pin_level = watch_get_pin_level(pin); - function(pin_level); - *debounce_ticks = pin_level ? DEBOUNCE_TICKS_DOWN : DEBOUNCE_TICKS_UP; - if (*debounce_ticks != 0) _movement_enable_fast_tick_if_needed(); - } - else - *down_timestamp = 0; -} - -static void disable_if_needed(uint8_t *ticks) { - if (*ticks > 0 && --*ticks == 0) - _movement_disable_fast_tick_if_possible(); -} - -static void movement_disable_if_debounce_complete(void) { - disable_if_needed(&movement_state.debounce_ticks_light); - disable_if_needed(&movement_state.debounce_ticks_alarm); - disable_if_needed(&movement_state.debounce_ticks_mode); -} - void cb_light_btn_interrupt(void) { - debounce_btn_press(BTN_LIGHT, &movement_state.debounce_ticks_light, &movement_state.light_down_timestamp, light_btn_action); + bool pin_level = watch_get_pin_level(BTN_LIGHT); + _movement_reset_inactivity_countdown(); + event.event_type = _figure_out_button_event(pin_level, EVENT_LIGHT_BUTTON_DOWN, &movement_state.light_down_timestamp); } void cb_mode_btn_interrupt(void) { - debounce_btn_press(BTN_MODE, &movement_state.debounce_ticks_mode, &movement_state.mode_down_timestamp, mode_btn_action); + bool pin_level = watch_get_pin_level(BTN_MODE); + _movement_reset_inactivity_countdown(); + event.event_type = _figure_out_button_event(pin_level, EVENT_MODE_BUTTON_DOWN, &movement_state.mode_down_timestamp); } void cb_alarm_btn_interrupt(void) { - debounce_btn_press(BTN_ALARM, &movement_state.debounce_ticks_alarm, &movement_state.alarm_down_timestamp, alarm_btn_action); + bool pin_level = watch_get_pin_level(BTN_ALARM); + _movement_reset_inactivity_countdown(); + event.event_type = _figure_out_button_event(pin_level, EVENT_ALARM_BUTTON_DOWN, &movement_state.alarm_down_timestamp); } void cb_alarm_btn_extwake(void) { @@ -857,9 +805,7 @@ void cb_alarm_fired(void) { } void cb_fast_tick(void) { - movement_disable_if_debounce_complete(); - if (movement_state.debounce_ticks_light + movement_state.debounce_ticks_mode + movement_state.debounce_ticks_alarm == 0) - movement_state.fast_ticks++; + movement_state.fast_ticks++; if (movement_state.light_ticks > 0) movement_state.light_ticks--; if (movement_state.alarm_ticks > 0) movement_state.alarm_ticks--; // check timestamps and auto-fire the long-press events diff --git a/movement/movement.h b/movement/movement.h index 6ca6537..46be32f 100644 --- a/movement/movement.h +++ b/movement/movement.h @@ -273,10 +273,6 @@ typedef struct { // low energy mode countdown int32_t le_mode_ticks; - uint8_t debounce_ticks_light; - uint8_t debounce_ticks_alarm; - uint8_t debounce_ticks_mode; - bool ignore_alarm_btn_after_sleep; // app resignation countdown (TODO: consolidate with LE countdown?) int16_t timeout_ticks;