diff --git a/movement/movement.c b/movement/movement.c index c81e0a7fc..f0bc6231b 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -176,12 +176,25 @@ static inline void _movement_reset_inactivity_countdown(void) { movement_state.timeout_ticks = movement_timeout_inactivity_deadlines[movement_state.settings.bit.to_interval]; } +static inline void _reset_debounce_ticks(void) { +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) + movement_state.debounce_ticks_light = 0; + movement_state.debounce_ticks_alarm = 0; + movement_state.debounce_ticks_mode = 0; +#endif +} + +static inline bool _debounce_ticks_all_zero(void) { +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) + return ((movement_state.debounce_ticks_light | movement_state.debounce_ticks_mode | movement_state.debounce_ticks_alarm) == 0); +#else + return true; +#endif +} + 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; } @@ -190,7 +203,7 @@ 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) && + _debounce_ticks_all_zero() && ((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); @@ -546,6 +559,7 @@ bool app_loop(void) { woke_up_for_buzzer = true; } event.event_type = EVENT_ACTIVATE; + _reset_debounce_ticks(); // Likely unneeded, but good to reset the debounce timers on wake. // this is a hack tho: waking from sleep mode, app_setup does get called, but it happens before we have reset our ticks. // need to figure out if there's a better heuristic for determining how we woke up. app_setup(); @@ -622,6 +636,8 @@ bool app_loop(void) { // if the LED is on, we need to stay awake to keep the TCC running. if (movement_state.light_ticks != -1) can_sleep = false; + // if we're checking debounce, stay awake + if (!_debounce_ticks_all_zero()) can_sleep = false; return can_sleep; } @@ -670,10 +686,12 @@ static void alarm_btn_action(bool pin_level) { event.event_type = event_type; } +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) 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); + _reset_debounce_ticks(); // Avoids adding the debounce time of one btn into this one becoming a long press *debounce_ticks = pin_level ? DEBOUNCE_TICKS_DOWN : DEBOUNCE_TICKS_UP; if (*debounce_ticks != 0) _movement_enable_fast_tick_if_needed(); } @@ -691,17 +709,33 @@ static void movement_disable_if_debounce_complete(void) { disable_if_needed(&movement_state.debounce_ticks_alarm); disable_if_needed(&movement_state.debounce_ticks_mode); } +#endif void cb_light_btn_interrupt(void) { +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) debounce_btn_press(BTN_LIGHT, &movement_state.debounce_ticks_light, &movement_state.light_down_timestamp, light_btn_action); +#else + bool pin_level = watch_get_pin_level(BTN_LIGHT); + light_btn_action(pin_level); +#endif } void cb_mode_btn_interrupt(void) { +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) debounce_btn_press(BTN_MODE, &movement_state.debounce_ticks_mode, &movement_state.mode_down_timestamp, mode_btn_action); +#else + bool pin_level = watch_get_pin_level(BTN_MODE); + mode_btn_action(pin_level); +#endif } void cb_alarm_btn_interrupt(void) { +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) debounce_btn_press(BTN_ALARM, &movement_state.debounce_ticks_alarm, &movement_state.alarm_down_timestamp, alarm_btn_action); +#else + bool pin_level = watch_get_pin_level(BTN_ALARM); + alarm_btn_action(pin_level); +#endif } void cb_alarm_btn_extwake(void) { @@ -714,9 +748,13 @@ void cb_alarm_fired(void) { } void cb_fast_tick(void) { +#if (DEBOUNCE_TICKS_DOWN || DEBOUNCE_TICKS_UP) movement_disable_if_debounce_complete(); - if (movement_state.debounce_ticks_light + movement_state.debounce_ticks_mode + movement_state.debounce_ticks_alarm == 0) + if (_debounce_ticks_all_zero()) movement_state.fast_ticks++; +#else + movement_state.fast_ticks++; +#endif 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 @@ -736,6 +774,7 @@ void cb_fast_tick(void) { if (movement_state.fast_ticks >= 128 * 20) { watch_rtc_disable_periodic_callback(128); movement_state.fast_tick_enabled = false; + _reset_debounce_ticks(); } }