Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debounce #497

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions movement/movement.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
}
Expand All @@ -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) {
Expand All @@ -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
Expand All @@ -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();
}
}

Expand Down