]> git.earman.xyz Git - sensor-watch.git/commitdiff
using cb_fast_tick again
authorDavid Volovskiy <devolov@gmail.com>
Tue, 30 Jul 2024 00:48:17 +0000 (20:48 -0400)
committerDavid Volovskiy <devolov@gmail.com>
Tue, 30 Jul 2024 00:48:17 +0000 (20:48 -0400)
movement/movement.c
movement/movement.h

index a9ff2fa255e77071800374c125b40bbb501c3d75..1c043fc2d1b6eabb8d600b3935ac3476d7ad3d72 100644 (file)
@@ -99,6 +99,8 @@
 #include <emscripten.h>
 #endif
 
+#define DEBOUNCE_TICKS 20  // In terms of *7.8125ms
+
 movement_state_t movement_state;
 void * watch_face_contexts[MOVEMENT_NUM_FACES];
 watch_date_time scheduled_tasks[MOVEMENT_NUM_FACES];
@@ -169,6 +171,9 @@ 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;
     }
@@ -183,16 +188,6 @@ static inline void _movement_disable_fast_tick_if_possible(void) {
     }
 }
 
-static void cb_debounce(void) {
-    movement_state.debounce_occurring = false;
-    watch_rtc_disable_periodic_callback(64);  // 64 HZ is 15.625ms
-}
-
-static inline void _movement_enable_debounce_tick(void) {
-    movement_state.debounce_occurring = true;
-    watch_rtc_register_periodic_callback(cb_debounce, 64);
-}
-
 static void _movement_handle_background_tasks(void) {
     for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) {
         // For each face, if the watch face wants a background task...
@@ -233,15 +228,15 @@ static void _movement_handle_scheduled_tasks(void) {
 }
 
 void movement_request_tick_frequency(uint8_t freq) {
-    // Movement uses the 128 Hz tick internally; 64 is th edebounce frequency
-    if (freq == 128 || freq == 64 ) return;
+    // Movement uses the 128 Hz tick internally
+    if (freq == 128) return;
 
     // Movement requires at least a 1 Hz tick.
     // If we are asked for an invalid frequency, default back to 1 Hz.
     if (freq == 0 || __builtin_popcount(freq) != 1) freq = 1;
 
     // disable all callbacks except the 128 Hz one
-    watch_rtc_disable_matching_periodic_callbacks(0xFC);
+    watch_rtc_disable_matching_periodic_callbacks(0xFE);
 
     movement_state.subsecond = 0;
     movement_state.tick_frequency = freq;
@@ -625,8 +620,6 @@ bool app_loop(void) {
 static movement_event_type_t _figure_out_button_event(bool pin_level, movement_event_type_t button_down_event_type, uint16_t *down_timestamp) {
     // force alarm off if the user pressed a button.
     if (movement_state.alarm_ticks) movement_state.alarm_ticks = 0;
-    if ( movement_state.debounce_occurring)
-        return EVENT_NONE;
 
     if (pin_level) {
         // handle rising edge
@@ -641,36 +634,46 @@ static movement_event_type_t _figure_out_button_event(bool pin_level, movement_e
         uint16_t diff = movement_state.fast_ticks - *down_timestamp;
         *down_timestamp = 0;
         _movement_disable_fast_tick_if_possible();
-        _movement_enable_debounce_tick();
         // 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;
     }
 }
 
-void cb_light_btn_interrupt(void) {
-    bool pin_level = watch_get_pin_level(BTN_LIGHT);
+static void light_btn_action(bool pin_level) {
     _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) {
-    bool pin_level = watch_get_pin_level(BTN_MODE);
+static void mode_btn_action(bool pin_level) { 
     _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) {
-    bool pin_level = watch_get_pin_level(BTN_ALARM);
+static void alarm_btn_action(bool pin_level) {
     _movement_reset_inactivity_countdown();
     uint8_t event_type = _figure_out_button_event(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) movement_state.ignore_alarm_btn_after_sleep = false;
+        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;
 }
 
+void cb_light_btn_interrupt(void) {
+    movement_state.debounce_btn_trig_light = true;
+    _movement_enable_fast_tick_if_needed();
+}
+
+void cb_mode_btn_interrupt(void) {
+    movement_state.debounce_btn_trig_mode = true;
+    _movement_enable_fast_tick_if_needed();
+}
+
+void cb_alarm_btn_interrupt(void) {
+    movement_state.debounce_btn_trig_alarm = true;
+    _movement_enable_fast_tick_if_needed();
+}
 
 void cb_alarm_btn_extwake(void) {
     // wake up!
@@ -682,23 +685,70 @@ void cb_alarm_fired(void) {
 }
 
 void cb_fast_tick(void) {
-    movement_state.fast_ticks++;
-    if (!movement_state.debounce_occurring) {
-        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
-        // Notice: is it possible that two or more buttons have an identical timestamp? In this case
-        // only one of these buttons would receive the long press event. Don't bother for now...
-        if (movement_state.light_down_timestamp > 0)
-            if (movement_state.fast_ticks - movement_state.light_down_timestamp == MOVEMENT_LONG_PRESS_TICKS + 1)
-                event.event_type = EVENT_LIGHT_LONG_PRESS;
-        if (movement_state.mode_down_timestamp > 0)
-            if (movement_state.fast_ticks - movement_state.mode_down_timestamp == MOVEMENT_LONG_PRESS_TICKS + 1)
-                event.event_type = EVENT_MODE_LONG_PRESS;
-        if (movement_state.alarm_down_timestamp > 0)
-            if (movement_state.fast_ticks - movement_state.alarm_down_timestamp == MOVEMENT_LONG_PRESS_TICKS + 1)
-                event.event_type = EVENT_ALARM_LONG_PRESS;
+    if (movement_state.debounce_ticks_light > 0) movement_state.debounce_ticks_light--;
+    if (movement_state.debounce_ticks_alarm > 0) movement_state.debounce_ticks_alarm--;
+    if (movement_state.debounce_ticks_mode > 0) movement_state.debounce_ticks_mode--;
+    if (movement_state.debounce_btn_trig_light) {
+        bool pin_level = watch_get_pin_level(BTN_LIGHT);
+        movement_state.debounce_btn_trig_light = false;
+        if (pin_level) {
+            light_btn_action(pin_level);
+        }
+        else if (movement_state.debounce_ticks_light == 0) {
+            light_btn_action(pin_level);
+            movement_state.debounce_ticks_light = DEBOUNCE_TICKS;
+        }
+        else {
+            movement_state.light_down_timestamp = 0;
+            _movement_disable_fast_tick_if_possible();
+        }
+    }
+    if (movement_state.debounce_btn_trig_alarm) {
+        bool pin_level = watch_get_pin_level(BTN_ALARM);
+        movement_state.debounce_btn_trig_alarm = false;
+        if (pin_level) {
+            alarm_btn_action(pin_level);
+        }
+        else if (movement_state.debounce_ticks_alarm == 0) {
+            alarm_btn_action(pin_level);
+            movement_state.debounce_ticks_alarm = DEBOUNCE_TICKS;
+        }
+        else {
+            movement_state.alarm_down_timestamp = 0;
+            _movement_disable_fast_tick_if_possible();
+        }
+    }
+    if (movement_state.debounce_btn_trig_mode) {
+        bool pin_level = watch_get_pin_level(BTN_MODE);
+        movement_state.debounce_btn_trig_mode = false;
+        if (pin_level) {
+            mode_btn_action(pin_level);
+        }
+        else if (movement_state.debounce_ticks_mode == 0) {
+            mode_btn_action(pin_level);
+            movement_state.debounce_ticks_mode = DEBOUNCE_TICKS;
+        }
+        else {
+            movement_state.mode_down_timestamp = 0;
+            _movement_disable_fast_tick_if_possible();
+        }
     }
+    if (movement_state.debounce_ticks_light + movement_state.debounce_ticks_mode + movement_state.debounce_ticks_alarm  == 0)
+        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
+    // Notice: is it possible that two or more buttons have an identical timestamp? In this case
+    // only one of these buttons would receive the long press event. Don't bother for now...
+    if (movement_state.light_down_timestamp > 0)
+        if (movement_state.fast_ticks - movement_state.light_down_timestamp == MOVEMENT_LONG_PRESS_TICKS + 1)
+            event.event_type = EVENT_LIGHT_LONG_PRESS;
+    if (movement_state.mode_down_timestamp > 0)
+        if (movement_state.fast_ticks - movement_state.mode_down_timestamp == MOVEMENT_LONG_PRESS_TICKS + 1)
+            event.event_type = EVENT_MODE_LONG_PRESS;
+    if (movement_state.alarm_down_timestamp > 0)
+        if (movement_state.fast_ticks - movement_state.alarm_down_timestamp == MOVEMENT_LONG_PRESS_TICKS + 1)
+            event.event_type = EVENT_ALARM_LONG_PRESS;
     // this is just a fail-safe; fast tick should be disabled as soon as the button is up, the LED times out, and/or the alarm finishes.
     // but if for whatever reason it isn't, this forces the fast tick off after 20 seconds.
     if (movement_state.fast_ticks >= 128 * 20) {
index 5829ba8539aa0cb05f2542084e49cd52599cfacc..81e55ab273c7cc4f93d01969d809f8d3d1a043ab 100644 (file)
@@ -267,10 +267,15 @@ typedef struct {
     bool needs_background_tasks_handled;
     bool has_scheduled_background_task;
     bool needs_wake;
-    bool debounce_occurring;
 
     // 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 debounce_btn_trig_light;
+    bool debounce_btn_trig_alarm;
+    bool debounce_btn_trig_mode;
     bool ignore_alarm_btn_after_sleep;
 
     // app resignation countdown (TODO: consolidate with LE countdown?)