From e8461984d60a80841a5f4b219358cc20567114f8 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 12:58:14 -0400 Subject: launcher is now movement --- movement/movement.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 movement/movement.c (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c new file mode 100644 index 00000000..9c15833c --- /dev/null +++ b/movement/movement.c @@ -0,0 +1,218 @@ +#include +#include +#include +#include "watch.h" +#include "movement.h" +#include "movement_config.h" + +LauncherState movement_state; +void * widget_contexts[MOVEMENT_NUM_WIDGETS]; +const int32_t movement_screensaver_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; +LauncherEvent event; + +void cb_mode_btn_interrupt(); +void cb_light_btn_interrupt(); +void cb_alarm_btn_interrupt(); +void cb_alarm_btn_extwake(); +void cb_alarm_fired(); +void cb_tick(); + +static inline void _movement_reset_screensaver_countdown() { + // for testing, make the timeout happen 60x faster. + movement_state.screensaver_ticks = movement_screensaver_deadlines[movement_state.movement_settings.bit.screensaver_interval] / 60; +} + +void movement_request_tick_frequency(uint8_t freq) { + watch_rtc_disable_all_periodic_callbacks(); + movement_state.subsecond = 0; + movement_state.tick_frequency = freq; + watch_rtc_register_periodic_callback(cb_tick, freq); +} + +void movement_illuminate_led() { + movement_state.light_ticks = 3; +} + +void movement_move_to_widget(uint8_t widget_index) { + movement_state.widget_changed = true; + movement_state.next_widget = widget_index; +} + +void movement_move_to_next_widget() { + movement_move_to_widget((movement_state.current_widget + 1) % MOVEMENT_NUM_WIDGETS); +} + +void app_init() { + memset(&movement_state, 0, sizeof(movement_state)); + + movement_state.movement_settings.bit.led_green_color = 0xF; + movement_state.movement_settings.bit.button_should_sound = true; + movement_state.movement_settings.bit.screensaver_interval = 1; + _movement_reset_screensaver_countdown(); +} + +void app_wake_from_deep_sleep() { + // This app does not support deep sleep mode. +} + +void app_setup() { + static bool is_first_launch = true; + + if (is_first_launch) { + for(uint8_t i = 0; i < MOVEMENT_NUM_WIDGETS; i++) { + widget_contexts[i] = NULL; + is_first_launch = false; + } + } + if (movement_state.screensaver_ticks != -1) { + watch_disable_extwake_interrupt(BTN_ALARM); + watch_rtc_disable_alarm_callback(); + + watch_enable_external_interrupts(); + watch_register_interrupt_callback(BTN_MODE, cb_mode_btn_interrupt, INTERRUPT_TRIGGER_BOTH); + watch_register_interrupt_callback(BTN_LIGHT, cb_light_btn_interrupt, INTERRUPT_TRIGGER_BOTH); + watch_register_interrupt_callback(BTN_ALARM, cb_alarm_btn_interrupt, INTERRUPT_TRIGGER_BOTH); + + watch_enable_buzzer(); + watch_enable_leds(); + watch_enable_display(); + + movement_request_tick_frequency(1); + + for(uint8_t i = 0; i < MOVEMENT_NUM_WIDGETS; i++) { + widgets[i].setup(&movement_state.movement_settings, &widget_contexts[i]); + } + + widgets[0].activate(&movement_state.movement_settings, widget_contexts[0]); + event.subsecond = 0; + event.event_type = EVENT_ACTIVATE; + } +} + +void app_prepare_for_sleep() { +} + +void app_wake_from_sleep() { +} + +bool app_loop() { + if (movement_state.widget_changed) { + if (movement_state.movement_settings.bit.button_should_sound) { + // low note for nonzero case, high note for return to widget 0 + watch_buzzer_play_note(movement_state.next_widget ? BUZZER_NOTE_C7 : BUZZER_NOTE_C8, 50); + } + widgets[movement_state.current_widget].resign(&movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + movement_state.current_widget = movement_state.next_widget; + watch_clear_display(); + widgets[movement_state.current_widget].activate(&movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + event.subsecond = 0; + event.event_type = EVENT_ACTIVATE; + movement_state.widget_changed = false; + } + + // If the LED is off and should be on, turn it on + if (movement_state.light_ticks > 0 && !movement_state.led_on) { + watch_set_led_color(movement_state.movement_settings.bit.led_red_color ? (0xF | movement_state.movement_settings.bit.led_red_color << 4) : 0, + movement_state.movement_settings.bit.led_green_color ? (0xF | movement_state.movement_settings.bit.led_green_color << 4) : 0); + movement_state.led_on = true; + + } + + // if the LED is on and should be off, turn it off + if (movement_state.led_on && movement_state.light_ticks == 0) { + // unless the user is holding down the LIGHT button, in which case, give them more time. + if (watch_get_pin_level(BTN_LIGHT)) { + movement_state.light_ticks = 3; + } else { + watch_set_led_off(); + movement_state.led_on = false; + } + } + + // if we have timed out of our screensaver countdown, enter screensaver mode. + if (movement_state.screensaver_ticks == 0) { + movement_state.screensaver_ticks = -1; + watch_date_time alarm_time; + alarm_time.reg = 0; + alarm_time.unit.second = 59; // after a match, the alarm fires at the next rising edge of CLK_RTC_CNT, so 59 seconds lets us update at :00 + watch_rtc_register_alarm_callback(cb_alarm_fired, alarm_time, ALARM_MATCH_SS); + watch_register_extwake_callback(BTN_ALARM, cb_alarm_btn_extwake, true); + event.event_type = EVENT_NONE; + event.subsecond = 0; + + // this is a little mini-runloop. + // as long as screensaver_ticks is -1 (i.e. screensaver is active), we wake up here, update the screen, and go right back to sleep. + while (movement_state.screensaver_ticks == -1) { + event.event_type = EVENT_SCREENSAVER; + widgets[movement_state.current_widget].loop(event, &movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + watch_enter_shallow_sleep(true); + } + // as soon as screensaver_ticks is reset by the extwake handler, we bail out of the loop and reactivate ourselves. + event.event_type = EVENT_ACTIVATE; + // this is a hack tho: waking from shallow sleep, 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(); + } + + static bool can_sleep = true; + + if (event.event_type) { + event.subsecond = movement_state.subsecond; + can_sleep = widgets[movement_state.current_widget].loop(event, &movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + event.event_type = EVENT_NONE; + event.subsecond = 0; + } + + return can_sleep && !movement_state.led_on; +} + +LauncherEventType _figure_out_button_event(LauncherEventType button_down_event, uint8_t *down_timestamp) { + watch_date_time date_time = watch_rtc_get_date_time(); + if (*down_timestamp) { + uint8_t diff = ((61 + date_time.unit.second) - *down_timestamp) % 60; + *down_timestamp = 0; + if (diff > 1) return button_down_event + 2; + else return button_down_event + 1; + } else { + *down_timestamp = date_time.unit.second + 1; + return button_down_event; + } +} + +void cb_light_btn_interrupt() { + _movement_reset_screensaver_countdown(); + event.event_type = _figure_out_button_event(EVENT_LIGHT_BUTTON_DOWN, &movement_state.light_down_timestamp); +} + +void cb_mode_btn_interrupt() { + _movement_reset_screensaver_countdown(); + event.event_type = _figure_out_button_event(EVENT_MODE_BUTTON_DOWN, &movement_state.mode_down_timestamp); +} + +void cb_alarm_btn_interrupt() { + _movement_reset_screensaver_countdown(); + event.event_type = _figure_out_button_event(EVENT_ALARM_BUTTON_DOWN, &movement_state.alarm_down_timestamp); +} + +void cb_alarm_btn_extwake() { + // wake up! + _movement_reset_screensaver_countdown(); +} + +void cb_alarm_fired() { + event.event_type = EVENT_SCREENSAVER; +} + +void cb_tick() { + event.event_type = EVENT_TICK; + watch_date_time date_time = watch_rtc_get_date_time(); + if (date_time.unit.second != movement_state.last_second) { + if (movement_state.light_ticks) movement_state.light_ticks--; + if (movement_state.movement_settings.bit.screensaver_interval && movement_state.screensaver_ticks > 0) movement_state.screensaver_ticks--; + + movement_state.last_second = date_time.unit.second; + movement_state.subsecond = 0; + } else { + movement_state.subsecond++; + } +} -- cgit v1.2.3 From d5ac4cb71b4e328a27e26843cfdc6719b152ac7d Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 13:14:52 -0400 Subject: widgets are now watch faces --- movement/movement.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 9c15833c..3417345c 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -6,7 +6,7 @@ #include "movement_config.h" LauncherState movement_state; -void * widget_contexts[MOVEMENT_NUM_WIDGETS]; +void * watch_face_contexts[MOVEMENT_NUM_FACES]; const int32_t movement_screensaver_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; LauncherEvent event; @@ -33,13 +33,13 @@ void movement_illuminate_led() { movement_state.light_ticks = 3; } -void movement_move_to_widget(uint8_t widget_index) { - movement_state.widget_changed = true; - movement_state.next_widget = widget_index; +void movement_move_to_face(uint8_t watch_face_index) { + movement_state.watch_face_changed = true; + movement_state.next_face = watch_face_index; } -void movement_move_to_next_widget() { - movement_move_to_widget((movement_state.current_widget + 1) % MOVEMENT_NUM_WIDGETS); +void movement_move_to_next_face() { + movement_move_to_face((movement_state.current_watch_face + 1) % MOVEMENT_NUM_FACES); } void app_init() { @@ -59,8 +59,8 @@ void app_setup() { static bool is_first_launch = true; if (is_first_launch) { - for(uint8_t i = 0; i < MOVEMENT_NUM_WIDGETS; i++) { - widget_contexts[i] = NULL; + for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { + watch_face_contexts[i] = NULL; is_first_launch = false; } } @@ -79,11 +79,11 @@ void app_setup() { movement_request_tick_frequency(1); - for(uint8_t i = 0; i < MOVEMENT_NUM_WIDGETS; i++) { - widgets[i].setup(&movement_state.movement_settings, &widget_contexts[i]); + for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { + watch_faces[i].setup(&movement_state.movement_settings, &watch_face_contexts[i]); } - widgets[0].activate(&movement_state.movement_settings, widget_contexts[0]); + watch_faces[0].activate(&movement_state.movement_settings, watch_face_contexts[0]); event.subsecond = 0; event.event_type = EVENT_ACTIVATE; } @@ -96,18 +96,18 @@ void app_wake_from_sleep() { } bool app_loop() { - if (movement_state.widget_changed) { + if (movement_state.watch_face_changed) { if (movement_state.movement_settings.bit.button_should_sound) { - // low note for nonzero case, high note for return to widget 0 - watch_buzzer_play_note(movement_state.next_widget ? BUZZER_NOTE_C7 : BUZZER_NOTE_C8, 50); + // low note for nonzero case, high note for return to watch_face 0 + watch_buzzer_play_note(movement_state.next_face ? BUZZER_NOTE_C7 : BUZZER_NOTE_C8, 50); } - widgets[movement_state.current_widget].resign(&movement_state.movement_settings, widget_contexts[movement_state.current_widget]); - movement_state.current_widget = movement_state.next_widget; + watch_faces[movement_state.current_watch_face].resign(&movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); + movement_state.current_watch_face = movement_state.next_face; watch_clear_display(); - widgets[movement_state.current_widget].activate(&movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + watch_faces[movement_state.current_watch_face].activate(&movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); event.subsecond = 0; event.event_type = EVENT_ACTIVATE; - movement_state.widget_changed = false; + movement_state.watch_face_changed = false; } // If the LED is off and should be on, turn it on @@ -144,7 +144,7 @@ bool app_loop() { // as long as screensaver_ticks is -1 (i.e. screensaver is active), we wake up here, update the screen, and go right back to sleep. while (movement_state.screensaver_ticks == -1) { event.event_type = EVENT_SCREENSAVER; - widgets[movement_state.current_widget].loop(event, &movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + watch_faces[movement_state.current_watch_face].loop(event, &movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); watch_enter_shallow_sleep(true); } // as soon as screensaver_ticks is reset by the extwake handler, we bail out of the loop and reactivate ourselves. @@ -158,7 +158,7 @@ bool app_loop() { if (event.event_type) { event.subsecond = movement_state.subsecond; - can_sleep = widgets[movement_state.current_widget].loop(event, &movement_state.movement_settings, widget_contexts[movement_state.current_widget]); + can_sleep = watch_faces[movement_state.current_watch_face].loop(event, &movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); event.event_type = EVENT_NONE; event.subsecond = 0; } -- cgit v1.2.3 From d36331ce4e79d275e0ef09414a1a1a1a8949b0ea Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 13:23:23 -0400 Subject: rename types to be more c-like --- movement/movement.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 3417345c..779674c7 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -5,10 +5,10 @@ #include "movement.h" #include "movement_config.h" -LauncherState movement_state; +movement_state_t movement_state; void * watch_face_contexts[MOVEMENT_NUM_FACES]; const int32_t movement_screensaver_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; -LauncherEvent event; +movement_event_t event; void cb_mode_btn_interrupt(); void cb_light_btn_interrupt(); @@ -166,16 +166,16 @@ bool app_loop() { return can_sleep && !movement_state.led_on; } -LauncherEventType _figure_out_button_event(LauncherEventType button_down_event, uint8_t *down_timestamp) { +movement_event_type_t _figure_out_button_event(movement_event_type_t button_down_event_type, uint8_t *down_timestamp) { watch_date_time date_time = watch_rtc_get_date_time(); if (*down_timestamp) { uint8_t diff = ((61 + date_time.unit.second) - *down_timestamp) % 60; *down_timestamp = 0; - if (diff > 1) return button_down_event + 2; - else return button_down_event + 1; + if (diff > 1) return button_down_event_type + 2; + else return button_down_event_type + 1; } else { *down_timestamp = date_time.unit.second + 1; - return button_down_event; + return button_down_event_type; } } -- cgit v1.2.3 From 8f5de18b94ad4b01b43421e13e7d38e56afd54db Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 13:28:52 -0400 Subject: clarify property names --- movement/movement.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 779674c7..1a6ca496 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -19,7 +19,7 @@ void cb_tick(); static inline void _movement_reset_screensaver_countdown() { // for testing, make the timeout happen 60x faster. - movement_state.screensaver_ticks = movement_screensaver_deadlines[movement_state.movement_settings.bit.screensaver_interval] / 60; + movement_state.screensaver_ticks = movement_screensaver_deadlines[movement_state.settings.bit.screensaver_interval] / 60; } void movement_request_tick_frequency(uint8_t freq) { @@ -35,7 +35,7 @@ void movement_illuminate_led() { void movement_move_to_face(uint8_t watch_face_index) { movement_state.watch_face_changed = true; - movement_state.next_face = watch_face_index; + movement_state.next_watch_face = watch_face_index; } void movement_move_to_next_face() { @@ -45,9 +45,9 @@ void movement_move_to_next_face() { void app_init() { memset(&movement_state, 0, sizeof(movement_state)); - movement_state.movement_settings.bit.led_green_color = 0xF; - movement_state.movement_settings.bit.button_should_sound = true; - movement_state.movement_settings.bit.screensaver_interval = 1; + movement_state.settings.bit.led_green_color = 0xF; + movement_state.settings.bit.button_should_sound = true; + movement_state.settings.bit.screensaver_interval = 1; _movement_reset_screensaver_countdown(); } @@ -80,10 +80,10 @@ void app_setup() { movement_request_tick_frequency(1); for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { - watch_faces[i].setup(&movement_state.movement_settings, &watch_face_contexts[i]); + watch_faces[i].setup(&movement_state.settings, &watch_face_contexts[i]); } - watch_faces[0].activate(&movement_state.movement_settings, watch_face_contexts[0]); + watch_faces[0].activate(&movement_state.settings, watch_face_contexts[0]); event.subsecond = 0; event.event_type = EVENT_ACTIVATE; } @@ -97,14 +97,14 @@ void app_wake_from_sleep() { bool app_loop() { if (movement_state.watch_face_changed) { - if (movement_state.movement_settings.bit.button_should_sound) { + if (movement_state.settings.bit.button_should_sound) { // low note for nonzero case, high note for return to watch_face 0 - watch_buzzer_play_note(movement_state.next_face ? BUZZER_NOTE_C7 : BUZZER_NOTE_C8, 50); + watch_buzzer_play_note(movement_state.next_watch_face ? BUZZER_NOTE_C7 : BUZZER_NOTE_C8, 50); } - watch_faces[movement_state.current_watch_face].resign(&movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); - movement_state.current_watch_face = movement_state.next_face; + watch_faces[movement_state.current_watch_face].resign(&movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); + movement_state.current_watch_face = movement_state.next_watch_face; watch_clear_display(); - watch_faces[movement_state.current_watch_face].activate(&movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); + watch_faces[movement_state.current_watch_face].activate(&movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); event.subsecond = 0; event.event_type = EVENT_ACTIVATE; movement_state.watch_face_changed = false; @@ -112,8 +112,8 @@ bool app_loop() { // If the LED is off and should be on, turn it on if (movement_state.light_ticks > 0 && !movement_state.led_on) { - watch_set_led_color(movement_state.movement_settings.bit.led_red_color ? (0xF | movement_state.movement_settings.bit.led_red_color << 4) : 0, - movement_state.movement_settings.bit.led_green_color ? (0xF | movement_state.movement_settings.bit.led_green_color << 4) : 0); + watch_set_led_color(movement_state.settings.bit.led_red_color ? (0xF | movement_state.settings.bit.led_red_color << 4) : 0, + movement_state.settings.bit.led_green_color ? (0xF | movement_state.settings.bit.led_green_color << 4) : 0); movement_state.led_on = true; } @@ -144,7 +144,7 @@ bool app_loop() { // as long as screensaver_ticks is -1 (i.e. screensaver is active), we wake up here, update the screen, and go right back to sleep. while (movement_state.screensaver_ticks == -1) { event.event_type = EVENT_SCREENSAVER; - watch_faces[movement_state.current_watch_face].loop(event, &movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); + watch_faces[movement_state.current_watch_face].loop(event, &movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); watch_enter_shallow_sleep(true); } // as soon as screensaver_ticks is reset by the extwake handler, we bail out of the loop and reactivate ourselves. @@ -158,7 +158,7 @@ bool app_loop() { if (event.event_type) { event.subsecond = movement_state.subsecond; - can_sleep = watch_faces[movement_state.current_watch_face].loop(event, &movement_state.movement_settings, watch_face_contexts[movement_state.current_watch_face]); + can_sleep = watch_faces[movement_state.current_watch_face].loop(event, &movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); event.event_type = EVENT_NONE; event.subsecond = 0; } @@ -208,7 +208,7 @@ void cb_tick() { watch_date_time date_time = watch_rtc_get_date_time(); if (date_time.unit.second != movement_state.last_second) { if (movement_state.light_ticks) movement_state.light_ticks--; - if (movement_state.movement_settings.bit.screensaver_interval && movement_state.screensaver_ticks > 0) movement_state.screensaver_ticks--; + if (movement_state.settings.bit.screensaver_interval && movement_state.screensaver_ticks > 0) movement_state.screensaver_ticks--; movement_state.last_second = date_time.unit.second; movement_state.subsecond = 0; -- cgit v1.2.3 From 3e539a9e6362841b9cd5924f0d309ec15b2698b1 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 13:40:17 -0400 Subject: screensaver mode is now low energy mode --- movement/movement.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 1a6ca496..9b7e90a0 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -7,7 +7,7 @@ movement_state_t movement_state; void * watch_face_contexts[MOVEMENT_NUM_FACES]; -const int32_t movement_screensaver_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; +const int32_t movement_inactivity_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; movement_event_t event; void cb_mode_btn_interrupt(); @@ -17,9 +17,9 @@ void cb_alarm_btn_extwake(); void cb_alarm_fired(); void cb_tick(); -static inline void _movement_reset_screensaver_countdown() { +static inline void _movement_reset_inactivity_countdown() { // for testing, make the timeout happen 60x faster. - movement_state.screensaver_ticks = movement_screensaver_deadlines[movement_state.settings.bit.screensaver_interval] / 60; + movement_state.le_mode_ticks = movement_inactivity_deadlines[movement_state.settings.bit.le_inactivity_interval] / 60; } void movement_request_tick_frequency(uint8_t freq) { @@ -47,8 +47,8 @@ void app_init() { movement_state.settings.bit.led_green_color = 0xF; movement_state.settings.bit.button_should_sound = true; - movement_state.settings.bit.screensaver_interval = 1; - _movement_reset_screensaver_countdown(); + movement_state.settings.bit.le_inactivity_interval = 1; + _movement_reset_inactivity_countdown(); } void app_wake_from_deep_sleep() { @@ -64,7 +64,7 @@ void app_setup() { is_first_launch = false; } } - if (movement_state.screensaver_ticks != -1) { + if (movement_state.le_mode_ticks != -1) { watch_disable_extwake_interrupt(BTN_ALARM); watch_rtc_disable_alarm_callback(); @@ -129,9 +129,9 @@ bool app_loop() { } } - // if we have timed out of our screensaver countdown, enter screensaver mode. - if (movement_state.screensaver_ticks == 0) { - movement_state.screensaver_ticks = -1; + // if we have timed out of our low energy mode countdown, enter low energy mode. + if (movement_state.le_mode_ticks == 0) { + movement_state.le_mode_ticks = -1; watch_date_time alarm_time; alarm_time.reg = 0; alarm_time.unit.second = 59; // after a match, the alarm fires at the next rising edge of CLK_RTC_CNT, so 59 seconds lets us update at :00 @@ -141,13 +141,13 @@ bool app_loop() { event.subsecond = 0; // this is a little mini-runloop. - // as long as screensaver_ticks is -1 (i.e. screensaver is active), we wake up here, update the screen, and go right back to sleep. - while (movement_state.screensaver_ticks == -1) { - event.event_type = EVENT_SCREENSAVER; + // 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) { + event.event_type = EVENT_LOW_POWER_TICK; watch_faces[movement_state.current_watch_face].loop(event, &movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); watch_enter_shallow_sleep(true); } - // as soon as screensaver_ticks is reset by the extwake handler, we bail out of the loop and reactivate ourselves. + // as soon as le_mode_ticks is reset by the extwake handler, we bail out of the loop and reactivate ourselves. event.event_type = EVENT_ACTIVATE; // this is a hack tho: waking from shallow sleep, 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. @@ -180,27 +180,27 @@ movement_event_type_t _figure_out_button_event(movement_event_type_t button_down } void cb_light_btn_interrupt() { - _movement_reset_screensaver_countdown(); + _movement_reset_inactivity_countdown(); event.event_type = _figure_out_button_event(EVENT_LIGHT_BUTTON_DOWN, &movement_state.light_down_timestamp); } void cb_mode_btn_interrupt() { - _movement_reset_screensaver_countdown(); + _movement_reset_inactivity_countdown(); event.event_type = _figure_out_button_event(EVENT_MODE_BUTTON_DOWN, &movement_state.mode_down_timestamp); } void cb_alarm_btn_interrupt() { - _movement_reset_screensaver_countdown(); + _movement_reset_inactivity_countdown(); event.event_type = _figure_out_button_event(EVENT_ALARM_BUTTON_DOWN, &movement_state.alarm_down_timestamp); } void cb_alarm_btn_extwake() { // wake up! - _movement_reset_screensaver_countdown(); + _movement_reset_inactivity_countdown(); } void cb_alarm_fired() { - event.event_type = EVENT_SCREENSAVER; + event.event_type = EVENT_LOW_POWER_TICK; } void cb_tick() { @@ -208,7 +208,7 @@ void cb_tick() { watch_date_time date_time = watch_rtc_get_date_time(); if (date_time.unit.second != movement_state.last_second) { if (movement_state.light_ticks) movement_state.light_ticks--; - if (movement_state.settings.bit.screensaver_interval && movement_state.screensaver_ticks > 0) movement_state.screensaver_ticks--; + if (movement_state.settings.bit.le_inactivity_interval && movement_state.le_mode_ticks > 0) movement_state.le_mode_ticks--; movement_state.last_second = date_time.unit.second; movement_state.subsecond = 0; -- cgit v1.2.3 From 69397e9b0f011cd9108547f05ab21073c4a9ddb6 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 13:47:42 -0400 Subject: implement led duration setting --- movement/movement.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 9b7e90a0..03ddb244 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -30,7 +30,7 @@ void movement_request_tick_frequency(uint8_t freq) { } void movement_illuminate_led() { - movement_state.light_ticks = 3; + movement_state.light_ticks = movement_state.settings.bit.led_duration; } void movement_move_to_face(uint8_t watch_face_index) { @@ -48,6 +48,7 @@ void app_init() { movement_state.settings.bit.led_green_color = 0xF; movement_state.settings.bit.button_should_sound = true; movement_state.settings.bit.le_inactivity_interval = 1; + movement_state.settings.bit.led_duration = 3; _movement_reset_inactivity_countdown(); } -- cgit v1.2.3 From 0cfb37c6716326dea78a8dca512d286e6484e509 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Sat, 16 Oct 2021 16:03:27 -0400 Subject: early work on background tasks, documentation --- movement/movement.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 03ddb244..d43285e1 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -144,7 +144,7 @@ bool app_loop() { // this is a little mini-runloop. // 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) { - event.event_type = EVENT_LOW_POWER_TICK; + event.event_type = EVENT_LOW_ENERGY_UPDATE; watch_faces[movement_state.current_watch_face].loop(event, &movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); watch_enter_shallow_sleep(true); } @@ -201,7 +201,7 @@ void cb_alarm_btn_extwake() { } void cb_alarm_fired() { - event.event_type = EVENT_LOW_POWER_TICK; + event.event_type = EVENT_LOW_ENERGY_UPDATE; } void cb_tick() { -- cgit v1.2.3 From 93624f0b692648eac415a3df5689de6dee06c2db Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Mon, 18 Oct 2021 12:15:57 -0400 Subject: add timeout event to give faces a chance to resign --- movement/movement.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index d43285e1..6576bd75 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -7,7 +7,8 @@ movement_state_t movement_state; void * watch_face_contexts[MOVEMENT_NUM_FACES]; -const int32_t movement_inactivity_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; +const int32_t movement_le_inactivity_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; +const int32_t movement_timeout_inactivity_deadlines[4] = {60, 120, 300, 1800}; movement_event_t event; void cb_mode_btn_interrupt(); @@ -18,8 +19,10 @@ void cb_alarm_fired(); void cb_tick(); static inline void _movement_reset_inactivity_countdown() { - // for testing, make the timeout happen 60x faster. - movement_state.le_mode_ticks = movement_inactivity_deadlines[movement_state.settings.bit.le_inactivity_interval] / 60; + // for testing, make the low energy timeout happen 60x faster. + movement_state.le_mode_ticks = movement_le_inactivity_deadlines[movement_state.settings.bit.le_inactivity_interval] / 60; + // for testing, make the inactivity timeout happen 4x faster. + movement_state.timeout_ticks = movement_timeout_inactivity_deadlines[movement_state.settings.bit.to_inactivity_interval] / 4; } void movement_request_tick_frequency(uint8_t freq) { @@ -130,6 +133,11 @@ bool app_loop() { } } + // if we have timed out of our timeout countdown, give the app a hint that they can resign. + if (movement_state.timeout_ticks == 0) { + event.event_type = EVENT_TIMEOUT; + } + // if we have timed out of our low energy mode countdown, enter low energy mode. if (movement_state.le_mode_ticks == 0) { movement_state.le_mode_ticks = -1; @@ -210,6 +218,7 @@ void cb_tick() { if (date_time.unit.second != movement_state.last_second) { if (movement_state.light_ticks) movement_state.light_ticks--; if (movement_state.settings.bit.le_inactivity_interval && movement_state.le_mode_ticks > 0) movement_state.le_mode_ticks--; + if (movement_state.timeout_ticks > 0) movement_state.timeout_ticks--; movement_state.last_second = date_time.unit.second; movement_state.subsecond = 0; -- cgit v1.2.3 From 86d316008c7e6667c83760a8eaefadf91b1456bb Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Mon, 18 Oct 2021 12:33:07 -0400 Subject: movement: remove faster sleep / timeout intervals --- movement/movement.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'movement/movement.c') diff --git a/movement/movement.c b/movement/movement.c index 6576bd75..8d28cc55 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -19,10 +19,8 @@ void cb_alarm_fired(); void cb_tick(); static inline void _movement_reset_inactivity_countdown() { - // for testing, make the low energy timeout happen 60x faster. - movement_state.le_mode_ticks = movement_le_inactivity_deadlines[movement_state.settings.bit.le_inactivity_interval] / 60; - // for testing, make the inactivity timeout happen 4x faster. - movement_state.timeout_ticks = movement_timeout_inactivity_deadlines[movement_state.settings.bit.to_inactivity_interval] / 4; + movement_state.le_mode_ticks = movement_le_inactivity_deadlines[movement_state.settings.bit.le_inactivity_interval]; + movement_state.timeout_ticks = movement_timeout_inactivity_deadlines[movement_state.settings.bit.to_inactivity_interval]; } void movement_request_tick_frequency(uint8_t freq) { -- cgit v1.2.3