From 03e107b81a63c08443165497d57dc2d756b78094 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Mon, 20 Dec 2021 12:35:37 -0600 Subject: Movement: allow scheduling precisely timed background tasks (resolves #28) --- movement/movement.c | 36 ++++++++++++++++++++++++++++++++++++ movement/movement.h | 9 +++++++++ 2 files changed, 45 insertions(+) (limited to 'movement') diff --git a/movement/movement.c b/movement/movement.c index cdd4ff06..783c666c 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -7,6 +7,7 @@ movement_state_t movement_state; void * watch_face_contexts[MOVEMENT_NUM_FACES]; +watch_date_time scheduled_tasks[MOVEMENT_NUM_FACES]; const int32_t movement_le_inactivity_deadlines[8] = {INT_MAX, 3600, 7200, 21600, 43200, 86400, 172800, 604800}; const int16_t movement_timeout_inactivity_deadlines[4] = {60, 120, 300, 1800}; movement_event_t event; @@ -99,6 +100,29 @@ static void _movement_handle_background_tasks(void) { movement_state.needs_background_tasks_handled = false; } +static void _movement_handle_scheduled_tasks(void) { + watch_date_time date_time = watch_rtc_get_date_time(); + uint8_t num_active_tasks = 0; + + for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { + if (scheduled_tasks[i].reg) { + if (scheduled_tasks[i].reg == date_time.reg) { + scheduled_tasks[i].reg = 0; + movement_event_t background_event = { EVENT_BACKGROUND_TASK, 0 }; + watch_faces[i].loop(background_event, &movement_state.settings, watch_face_contexts[i]); + } else { + num_active_tasks++; + } + } + } + + if (num_active_tasks == 0) { + movement_state.has_scheduled_background_task = false; + } else { + _movement_reset_inactivity_countdown(); + } +} + void movement_request_tick_frequency(uint8_t freq) { if (freq == 128) return; // Movement uses the 128 Hz tick internally RTC->MODE2.INTENCLR.reg = 0xFE; // disable all callbacks except the 128 Hz one @@ -125,6 +149,14 @@ void movement_move_to_next_face(void) { movement_move_to_face((movement_state.current_watch_face + 1) % MOVEMENT_NUM_FACES); } +void movement_schedule_background_task(watch_date_time date_time) { + watch_date_time now = watch_rtc_get_date_time(); + if (date_time.reg > now.reg) { + movement_state.has_scheduled_background_task = true; + scheduled_tasks[movement_state.current_watch_face].reg = date_time.reg; + } +} + void movement_play_signal(void) { watch_buzzer_play_note(BUZZER_NOTE_C8, 75); watch_buzzer_play_note(BUZZER_NOTE_REST, 100); @@ -161,6 +193,7 @@ void app_setup(void) { if (is_first_launch) { for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { watch_face_contexts[i] = NULL; + scheduled_tasks[i].reg = 0; is_first_launch = false; } @@ -230,6 +263,9 @@ bool app_loop(void) { // handle background tasks, if the alarm handler told us we need to if (movement_state.needs_background_tasks_handled) _movement_handle_background_tasks(); + // if we have a scheduled background task, handle that here: + if (event.event_type == EVENT_TICK && movement_state.has_scheduled_background_task) _movement_handle_scheduled_tasks(); + // 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; diff --git a/movement/movement.h b/movement/movement.h index 62e4120b..b99f4e8b 100644 --- a/movement/movement.h +++ b/movement/movement.h @@ -2,6 +2,7 @@ #define MOVEMENT_H_ #include #include +#include "watch.h" // Movement Preferences // These four 32-bit structs store information about the wearer and their preferences. Tentatively, the plan is @@ -228,6 +229,7 @@ typedef struct { // background task handling bool needs_background_tasks_handled; + bool has_scheduled_background_task; // low energy mode countdown int32_t le_mode_ticks; @@ -244,8 +246,15 @@ typedef struct { void movement_move_to_face(uint8_t watch_face_index); void movement_move_to_next_face(void); void movement_illuminate_led(void); + +// note: requesting a tick frequency of 0 will break any scheduled background tasks. +// this will be fixed in a future refactor of the tick mechanism. void movement_request_tick_frequency(uint8_t freq); +// note: watch faces can only schedule a background task when in the foreground, since +// movement will associate the scheduled task with the currently active face. +void movement_schedule_background_task(watch_date_time date_time); + void movement_play_signal(void); void movement_play_alarm(void); -- cgit v1.2.3 From 60fe9691917f7e40effc72b1b6c929f9ba0ba3ee Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Mon, 20 Dec 2021 17:02:17 -0600 Subject: Movement: give watch faces their index at setup time --- movement/README.md | 4 ++-- movement/movement.c | 2 +- movement/movement.h | 2 +- movement/watch_faces/clock/simple_clock_face.c | 3 ++- movement/watch_faces/clock/simple_clock_face.h | 2 +- movement/watch_faces/clock/world_clock_face.c | 3 ++- movement/watch_faces/clock/world_clock_face.h | 2 +- movement/watch_faces/complications/beats_face.c | 3 ++- movement/watch_faces/complications/beats_face.h | 2 +- movement/watch_faces/complications/day_one_face.c | 3 ++- movement/watch_faces/complications/day_one_face.h | 2 +- movement/watch_faces/complications/pulsometer_face.c | 3 ++- movement/watch_faces/complications/pulsometer_face.h | 2 +- movement/watch_faces/complications/stopwatch_face.c | 3 ++- movement/watch_faces/complications/stopwatch_face.h | 2 +- movement/watch_faces/complications/totp_face.c | 3 ++- movement/watch_faces/complications/totp_face.h | 2 +- movement/watch_faces/demos/character_set_face.c | 3 ++- movement/watch_faces/demos/character_set_face.h | 2 +- movement/watch_faces/demos/demo_face.c | 3 ++- movement/watch_faces/demos/demo_face.h | 2 +- movement/watch_faces/demos/lis2dh_logging_face.c | 3 ++- movement/watch_faces/demos/lis2dh_logging_face.h | 2 +- movement/watch_faces/demos/voltage_face.c | 3 ++- movement/watch_faces/demos/voltage_face.h | 2 +- movement/watch_faces/settings/preferences_face.c | 3 ++- movement/watch_faces/settings/preferences_face.h | 2 +- movement/watch_faces/settings/set_time_face.c | 3 ++- movement/watch_faces/settings/set_time_face.h | 2 +- movement/watch_faces/thermistor/thermistor_logging_face.c | 3 ++- movement/watch_faces/thermistor/thermistor_logging_face.h | 2 +- movement/watch_faces/thermistor/thermistor_readout_face.c | 3 ++- movement/watch_faces/thermistor/thermistor_readout_face.h | 2 +- 33 files changed, 49 insertions(+), 34 deletions(-) (limited to 'movement') diff --git a/movement/README.md b/movement/README.md index f5b9cb15..66c1f890 100644 --- a/movement/README.md +++ b/movement/README.md @@ -91,7 +91,7 @@ typedef struct { Finally, we define the four required functions, and define the watch face struct that users will use to add the face to their watch: ```c -void pulsometer_face_setup(movement_settings_t *settings, void ** context_ptr); +void pulsometer_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void pulsometer_face_activate(movement_settings_t *settings, void *context); bool pulsometer_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void pulsometer_face_resign(movement_settings_t *settings, void *context); @@ -119,7 +119,7 @@ These define the tick frequency: when the pulsometer widget is updating the scre #### Watch Face Setup ```c -void pulsometer_face_setup(movement_settings_t *settings, void ** context_ptr) { +void pulsometer_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(pulsometer_state_t)); } diff --git a/movement/movement.c b/movement/movement.c index 783c666c..3e22ace5 100644 --- a/movement/movement.c +++ b/movement/movement.c @@ -218,7 +218,7 @@ void app_setup(void) { movement_request_tick_frequency(1); for(uint8_t i = 0; i < MOVEMENT_NUM_FACES; i++) { - watch_faces[i].setup(&movement_state.settings, &watch_face_contexts[i]); + watch_faces[i].setup(&movement_state.settings, i, &watch_face_contexts[i]); } watch_faces[movement_state.current_watch_face].activate(&movement_state.settings, watch_face_contexts[movement_state.current_watch_face]); diff --git a/movement/movement.h b/movement/movement.h index b99f4e8b..5431436b 100644 --- a/movement/movement.h +++ b/movement/movement.h @@ -120,7 +120,7 @@ extern const char movement_valid_position_1_chars[]; * data required for your watch face. * */ -typedef void (*watch_face_setup)(movement_settings_t *settings, void ** context_ptr); +typedef void (*watch_face_setup)(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); /** @brief Prepare to go on-screen. * @details This function is called just before your watch enters the foreground. If your watch face has any diff --git a/movement/watch_faces/clock/simple_clock_face.c b/movement/watch_faces/clock/simple_clock_face.c index 72f7713f..0b26812f 100644 --- a/movement/watch_faces/clock/simple_clock_face.c +++ b/movement/watch_faces/clock/simple_clock_face.c @@ -3,8 +3,9 @@ #include "watch.h" #include "watch_utility.h" -void simple_clock_face_setup(movement_settings_t *settings, void ** context_ptr) { +void simple_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; // the only context we need is the timestamp of the previous tick. if (*context_ptr == NULL) *context_ptr = malloc(sizeof(uint32_t)); } diff --git a/movement/watch_faces/clock/simple_clock_face.h b/movement/watch_faces/clock/simple_clock_face.h index 3db894d2..a6cb6ac2 100644 --- a/movement/watch_faces/clock/simple_clock_face.h +++ b/movement/watch_faces/clock/simple_clock_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void simple_clock_face_setup(movement_settings_t *settings, void ** context_ptr); +void simple_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void simple_clock_face_activate(movement_settings_t *settings, void *context); bool simple_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void simple_clock_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/clock/world_clock_face.c b/movement/watch_faces/clock/world_clock_face.c index e1d96c97..5f2a1a86 100644 --- a/movement/watch_faces/clock/world_clock_face.c +++ b/movement/watch_faces/clock/world_clock_face.c @@ -4,8 +4,9 @@ #include "watch.h" #include "watch_utility.h" -void world_clock_face_setup(movement_settings_t *settings, void ** context_ptr) { +void world_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(world_clock_state_t)); world_clock_state_t *state = (world_clock_state_t *)*context_ptr; diff --git a/movement/watch_faces/clock/world_clock_face.h b/movement/watch_faces/clock/world_clock_face.h index 1c4525a4..b5e766bd 100644 --- a/movement/watch_faces/clock/world_clock_face.h +++ b/movement/watch_faces/clock/world_clock_face.h @@ -15,7 +15,7 @@ typedef struct { uint32_t previous_date_time; } world_clock_state_t; -void world_clock_face_setup(movement_settings_t *settings, void ** context_ptr); +void world_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void world_clock_face_activate(movement_settings_t *settings, void *context); bool world_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void world_clock_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/complications/beats_face.c b/movement/watch_faces/complications/beats_face.c index 519d3e4e..b4c76db1 100644 --- a/movement/watch_faces/complications/beats_face.c +++ b/movement/watch_faces/complications/beats_face.c @@ -5,8 +5,9 @@ const uint8_t BEAT_REFRESH_FREQUENCY = 8; -void beats_face_setup(movement_settings_t *settings, void ** context_ptr) { +void beats_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; (void) context_ptr; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(beats_face_state_t)); diff --git a/movement/watch_faces/complications/beats_face.h b/movement/watch_faces/complications/beats_face.h index bbe2396c..f11126d1 100644 --- a/movement/watch_faces/complications/beats_face.h +++ b/movement/watch_faces/complications/beats_face.h @@ -9,7 +9,7 @@ typedef struct { } beats_face_state_t; uint32_t clock2beats(uint32_t hours, uint32_t minutes, uint32_t seconds, uint32_t subseconds, int16_t utc_offset); -void beats_face_setup(movement_settings_t *settings, void ** context_ptr); +void beats_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void beats_face_activate(movement_settings_t *settings, void *context); bool beats_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void beats_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/complications/day_one_face.c b/movement/watch_faces/complications/day_one_face.c index 3b185d04..6cc26106 100644 --- a/movement/watch_faces/complications/day_one_face.c +++ b/movement/watch_faces/complications/day_one_face.c @@ -17,8 +17,9 @@ static void _day_one_face_update(day_one_state_t state) { watch_display_string(buf, 0); } -void day_one_face_setup(movement_settings_t *settings, void ** context_ptr) { +void day_one_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(day_one_state_t)); memset(*context_ptr, 0, sizeof(day_one_state_t)); diff --git a/movement/watch_faces/complications/day_one_face.h b/movement/watch_faces/complications/day_one_face.h index 06c7816e..3eb91195 100644 --- a/movement/watch_faces/complications/day_one_face.h +++ b/movement/watch_faces/complications/day_one_face.h @@ -15,7 +15,7 @@ typedef struct { bool birthday_changed; } day_one_state_t; -void day_one_face_setup(movement_settings_t *settings, void ** context_ptr); +void day_one_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void day_one_face_activate(movement_settings_t *settings, void *context); bool day_one_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void day_one_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/complications/pulsometer_face.c b/movement/watch_faces/complications/pulsometer_face.c index d54d8ddf..f1da9633 100644 --- a/movement/watch_faces/complications/pulsometer_face.c +++ b/movement/watch_faces/complications/pulsometer_face.c @@ -6,8 +6,9 @@ #define PULSOMETER_FACE_FREQUENCY_FACTOR (4ul) // refresh rate will be 2 to this power Hz (0 for 1 Hz, 2 for 4 Hz, etc.) #define PULSOMETER_FACE_FREQUENCY (1 << PULSOMETER_FACE_FREQUENCY_FACTOR) -void pulsometer_face_setup(movement_settings_t *settings, void ** context_ptr) { +void pulsometer_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(pulsometer_state_t)); } diff --git a/movement/watch_faces/complications/pulsometer_face.h b/movement/watch_faces/complications/pulsometer_face.h index cdb5b977..cb0b86bd 100644 --- a/movement/watch_faces/complications/pulsometer_face.h +++ b/movement/watch_faces/complications/pulsometer_face.h @@ -9,7 +9,7 @@ typedef struct { int16_t ticks; } pulsometer_state_t; -void pulsometer_face_setup(movement_settings_t *settings, void ** context_ptr); +void pulsometer_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void pulsometer_face_activate(movement_settings_t *settings, void *context); bool pulsometer_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void pulsometer_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/complications/stopwatch_face.c b/movement/watch_faces/complications/stopwatch_face.c index d1d1ee73..4a145abf 100644 --- a/movement/watch_faces/complications/stopwatch_face.c +++ b/movement/watch_faces/complications/stopwatch_face.c @@ -3,8 +3,9 @@ #include "stopwatch_face.h" #include "watch.h" -void stopwatch_face_setup(movement_settings_t *settings, void ** context_ptr) { +void stopwatch_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(stopwatch_state_t)); } diff --git a/movement/watch_faces/complications/stopwatch_face.h b/movement/watch_faces/complications/stopwatch_face.h index 537c01ce..ff0c1796 100644 --- a/movement/watch_faces/complications/stopwatch_face.h +++ b/movement/watch_faces/complications/stopwatch_face.h @@ -10,7 +10,7 @@ typedef struct { uint8_t hours; } stopwatch_state_t; -void stopwatch_face_setup(movement_settings_t *settings, void ** context_ptr); +void stopwatch_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void stopwatch_face_activate(movement_settings_t *settings, void *context); bool stopwatch_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void stopwatch_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/complications/totp_face.c b/movement/watch_faces/complications/totp_face.c index 4a34d7ad..468e6a8c 100644 --- a/movement/watch_faces/complications/totp_face.c +++ b/movement/watch_faces/complications/totp_face.c @@ -17,8 +17,9 @@ static uint8_t hmacKey[] = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0xde, 0xad, 0xbe static const uint32_t TIMESTEP = 30; -void totp_face_setup(movement_settings_t *settings, void ** context_ptr) { +void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(totp_state_t)); TOTP(hmacKey, sizeof(hmacKey), TIMESTEP); } diff --git a/movement/watch_faces/complications/totp_face.h b/movement/watch_faces/complications/totp_face.h index 0527627a..1e2c5c02 100644 --- a/movement/watch_faces/complications/totp_face.h +++ b/movement/watch_faces/complications/totp_face.h @@ -10,7 +10,7 @@ typedef struct { } totp_state_t; -void totp_face_setup(movement_settings_t *settings, void ** context_ptr); +void totp_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void totp_face_activate(movement_settings_t *settings, void *context); bool totp_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void totp_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/demos/character_set_face.c b/movement/watch_faces/demos/character_set_face.c index eabb133f..127c0fb3 100644 --- a/movement/watch_faces/demos/character_set_face.c +++ b/movement/watch_faces/demos/character_set_face.c @@ -3,8 +3,9 @@ #include "character_set_face.h" #include "watch.h" -void character_set_face_setup(movement_settings_t *settings, void ** context_ptr) { +void character_set_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(char)); } diff --git a/movement/watch_faces/demos/character_set_face.h b/movement/watch_faces/demos/character_set_face.h index b27a8359..0c7cb85c 100644 --- a/movement/watch_faces/demos/character_set_face.h +++ b/movement/watch_faces/demos/character_set_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void character_set_face_setup(movement_settings_t *settings, void ** context_ptr); +void character_set_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void character_set_face_activate(movement_settings_t *settings, void *context); bool character_set_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void character_set_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/demos/demo_face.c b/movement/watch_faces/demos/demo_face.c index 82256767..44a180ab 100644 --- a/movement/watch_faces/demos/demo_face.c +++ b/movement/watch_faces/demos/demo_face.c @@ -14,8 +14,9 @@ typedef enum { DEMO_FACE_NUM_FACES } demo_face_index_t; -void demo_face_setup(movement_settings_t *settings, void ** context_ptr) { +void demo_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(demo_face_index_t)); memset(*context_ptr, 0, sizeof(demo_face_index_t)); diff --git a/movement/watch_faces/demos/demo_face.h b/movement/watch_faces/demos/demo_face.h index b9e36ffc..1bc39c4f 100644 --- a/movement/watch_faces/demos/demo_face.h +++ b/movement/watch_faces/demos/demo_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void demo_face_setup(movement_settings_t *settings, void ** context_ptr); +void demo_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void demo_face_activate(movement_settings_t *settings, void *context); bool demo_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void demo_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/demos/lis2dh_logging_face.c b/movement/watch_faces/demos/lis2dh_logging_face.c index 9f5783fe..76892d07 100644 --- a/movement/watch_faces/demos/lis2dh_logging_face.c +++ b/movement/watch_faces/demos/lis2dh_logging_face.c @@ -86,8 +86,9 @@ static void _lis2dh_logging_face_log_data(lis2dh_logger_state_t *logger_state) { logger_state->z_interrupts_this_hour = 0; } -void lis2dh_logging_face_setup(movement_settings_t *settings, void ** context_ptr) { +void lis2dh_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(lis2dh_logger_state_t)); memset(*context_ptr, 0, sizeof(lis2dh_logger_state_t)); diff --git a/movement/watch_faces/demos/lis2dh_logging_face.h b/movement/watch_faces/demos/lis2dh_logging_face.h index b0faeca5..02b7ce9b 100644 --- a/movement/watch_faces/demos/lis2dh_logging_face.h +++ b/movement/watch_faces/demos/lis2dh_logging_face.h @@ -25,7 +25,7 @@ typedef struct { lis2dh_logger_data_point_t data[LIS2DH_LOGGING_NUM_DATA_POINTS]; } lis2dh_logger_state_t; -void lis2dh_logging_face_setup(movement_settings_t *settings, void ** context_ptr); +void lis2dh_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void lis2dh_logging_face_activate(movement_settings_t *settings, void *context); bool lis2dh_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void lis2dh_logging_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/demos/voltage_face.c b/movement/watch_faces/demos/voltage_face.c index fe43343f..a2b66854 100644 --- a/movement/watch_faces/demos/voltage_face.c +++ b/movement/watch_faces/demos/voltage_face.c @@ -11,8 +11,9 @@ static void _voltage_face_update_display(void) { watch_display_string(buf, 0); } -void voltage_face_setup(movement_settings_t *settings, void ** context_ptr) { +void voltage_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; (void) context_ptr; } diff --git a/movement/watch_faces/demos/voltage_face.h b/movement/watch_faces/demos/voltage_face.h index da580da5..530cf34f 100644 --- a/movement/watch_faces/demos/voltage_face.h +++ b/movement/watch_faces/demos/voltage_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void voltage_face_setup(movement_settings_t *settings, void ** context_ptr); +void voltage_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void voltage_face_activate(movement_settings_t *settings, void *context); bool voltage_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void voltage_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/settings/preferences_face.c b/movement/watch_faces/settings/preferences_face.c index ef65b1af..8cbe4c68 100644 --- a/movement/watch_faces/settings/preferences_face.c +++ b/movement/watch_faces/settings/preferences_face.c @@ -17,8 +17,9 @@ const char preferences_face_titles[PREFERENCES_FACE_NUM_PREFEFENCES][11] = { "LT red ", // Light: red component }; -void preferences_face_setup(movement_settings_t *settings, void ** context_ptr) { +void preferences_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(uint8_t)); } diff --git a/movement/watch_faces/settings/preferences_face.h b/movement/watch_faces/settings/preferences_face.h index af628ba3..54b4cff0 100644 --- a/movement/watch_faces/settings/preferences_face.h +++ b/movement/watch_faces/settings/preferences_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void preferences_face_setup(movement_settings_t *settings, void ** context_ptr); +void preferences_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void preferences_face_activate(movement_settings_t *settings, void *context); bool preferences_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void preferences_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/settings/set_time_face.c b/movement/watch_faces/settings/set_time_face.c index 0f5af312..a32efe9f 100644 --- a/movement/watch_faces/settings/set_time_face.c +++ b/movement/watch_faces/settings/set_time_face.c @@ -5,8 +5,9 @@ #define SET_TIME_FACE_NUM_SETTINGS (7) const char set_time_face_titles[SET_TIME_FACE_NUM_SETTINGS][3] = {"HR", "M1", "SE", "YR", "MO", "DA", "ZO"}; -void set_time_face_setup(movement_settings_t *settings, void ** context_ptr) { +void set_time_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) *context_ptr = malloc(sizeof(uint8_t)); } diff --git a/movement/watch_faces/settings/set_time_face.h b/movement/watch_faces/settings/set_time_face.h index 21fb1e44..d58c4618 100644 --- a/movement/watch_faces/settings/set_time_face.h +++ b/movement/watch_faces/settings/set_time_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void set_time_face_setup(movement_settings_t *settings, void ** context_ptr); +void set_time_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void set_time_face_activate(movement_settings_t *settings, void *context); bool set_time_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void set_time_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/thermistor/thermistor_logging_face.c b/movement/watch_faces/thermistor/thermistor_logging_face.c index 0d456785..094600c2 100644 --- a/movement/watch_faces/thermistor/thermistor_logging_face.c +++ b/movement/watch_faces/thermistor/thermistor_logging_face.c @@ -48,8 +48,9 @@ static void _thermistor_logging_face_update_display(thermistor_logger_state_t *l watch_display_string(buf, 0); } -void thermistor_logging_face_setup(movement_settings_t *settings, void ** context_ptr) { +void thermistor_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(thermistor_logger_state_t)); memset(*context_ptr, 0, sizeof(thermistor_logger_state_t)); diff --git a/movement/watch_faces/thermistor/thermistor_logging_face.h b/movement/watch_faces/thermistor/thermistor_logging_face.h index ece89396..03e7ff3c 100644 --- a/movement/watch_faces/thermistor/thermistor_logging_face.h +++ b/movement/watch_faces/thermistor/thermistor_logging_face.h @@ -18,7 +18,7 @@ typedef struct { thermistor_logger_data_point_t data[THERMISTOR_LOGGING_NUM_DATA_POINTS]; } thermistor_logger_state_t; -void thermistor_logging_face_setup(movement_settings_t *settings, void ** context_ptr); +void thermistor_logging_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void thermistor_logging_face_activate(movement_settings_t *settings, void *context); bool thermistor_logging_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void thermistor_logging_face_resign(movement_settings_t *settings, void *context); diff --git a/movement/watch_faces/thermistor/thermistor_readout_face.c b/movement/watch_faces/thermistor/thermistor_readout_face.c index 5478f07d..f55a4210 100644 --- a/movement/watch_faces/thermistor/thermistor_readout_face.c +++ b/movement/watch_faces/thermistor/thermistor_readout_face.c @@ -17,8 +17,9 @@ static void _thermistor_readout_face_update_display(bool in_fahrenheit) { thermistor_driver_disable(); } -void thermistor_readout_face_setup(movement_settings_t *settings, void ** context_ptr) { +void thermistor_readout_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; + (void) watch_face_index; (void) context_ptr; } diff --git a/movement/watch_faces/thermistor/thermistor_readout_face.h b/movement/watch_faces/thermistor/thermistor_readout_face.h index 71d15427..dc4f1b99 100644 --- a/movement/watch_faces/thermistor/thermistor_readout_face.h +++ b/movement/watch_faces/thermistor/thermistor_readout_face.h @@ -3,7 +3,7 @@ #include "movement.h" -void thermistor_readout_face_setup(movement_settings_t *settings, void ** context_ptr); +void thermistor_readout_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void thermistor_readout_face_activate(movement_settings_t *settings, void *context); bool thermistor_readout_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void thermistor_readout_face_resign(movement_settings_t *settings, void *context); -- cgit v1.2.3 From 1a4612f25972621b6c2f5f3b477f55b815f4dc84 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Mon, 20 Dec 2021 19:51:57 -0600 Subject: add documentation for watch face index --- movement/movement.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'movement') diff --git a/movement/movement.h b/movement/movement.h index 5431436b..edb1fabc 100644 --- a/movement/movement.h +++ b/movement/movement.h @@ -114,6 +114,9 @@ extern const char movement_valid_position_1_chars[]; * @param settings A pointer to the global Movement settings. You can use this to inform how you present your * display to the user (i.e. taking into account whether they have silenced the buttons, or if * they prefer 12 or 24-hour mode). You can also change these settings if you like. + * @param watch_face_index The index of this watch face in the global array of watch faces; 0 is the first face, + * 1 is the second, etc. You may stash this value in your context if you wish to reference + * it later; your watch face's index is set at launch and will not change. * @param context_ptr A pointer to a pointer; at first invocation, this value will be NULL, and you can set it * to any value you like. Subsequent invocations will pass in whatever value you previously * set. You may want to check if this is NULL and if so, allocate some space to store any -- cgit v1.2.3 From 6256e709bf0e29444f6d5383897bc77acd242529 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Tue, 21 Dec 2021 10:05:06 -0600 Subject: movement: add hourly signal to simple clock face --- movement/watch_faces/clock/simple_clock_face.c | 50 ++++++++++++++++++++++---- movement/watch_faces/clock/simple_clock_face.h | 13 ++++--- 2 files changed, 53 insertions(+), 10 deletions(-) (limited to 'movement') diff --git a/movement/watch_faces/clock/simple_clock_face.c b/movement/watch_faces/clock/simple_clock_face.c index 0b26812f..b80a3026 100644 --- a/movement/watch_faces/clock/simple_clock_face.c +++ b/movement/watch_faces/clock/simple_clock_face.c @@ -6,21 +6,31 @@ void simple_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { (void) settings; (void) watch_face_index; - // the only context we need is the timestamp of the previous tick. - if (*context_ptr == NULL) *context_ptr = malloc(sizeof(uint32_t)); + + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(simple_clock_state_t)); + simple_clock_state_t *state = (simple_clock_state_t *)*context_ptr; + state->signal_enabled = false; + state->watch_face_index = watch_face_index; + } } void simple_clock_face_activate(movement_settings_t *settings, void *context) { + simple_clock_state_t *state = (simple_clock_state_t *)context; + if (watch_tick_animation_is_running()) watch_stop_tick_animation(); if (settings->bit.clock_mode_24h) watch_set_indicator(WATCH_INDICATOR_24H); + if (state->signal_enabled) watch_set_indicator(WATCH_INDICATOR_SIGNAL); watch_set_colon(); + // this ensures that none of the timestamp fields will match, so we can re-render them all. - *((uint32_t *)context) = 0xFFFFFFFF; + state->previous_date_time = 0xFFFFFFFF; } bool simple_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + simple_clock_state_t *state = (simple_clock_state_t *)context; char buf[11]; uint8_t pos; @@ -31,8 +41,8 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting case EVENT_TICK: case EVENT_LOW_ENERGY_UPDATE: date_time = watch_rtc_get_date_time(); - previous_date_time = *((uint32_t *)context); - *((uint32_t *)context) = date_time.reg; + previous_date_time = state->previous_date_time; + state->previous_date_time = date_time.reg; if (date_time.reg >> 6 == previous_date_time >> 6 && event.event_type != EVENT_LOW_ENERGY_UPDATE) { // everything before seconds is the same, don't waste cycles setting those segments. @@ -70,7 +80,25 @@ bool simple_clock_face_loop(movement_event_t event, movement_settings_t *setting case EVENT_LIGHT_BUTTON_DOWN: movement_illuminate_led(); break; - case EVENT_ALARM_BUTTON_UP: + case EVENT_ALARM_LONG_PRESS: + state->signal_enabled = !state->signal_enabled; + if (state->signal_enabled) watch_set_indicator(WATCH_INDICATOR_SIGNAL); + else watch_clear_indicator(WATCH_INDICATOR_SIGNAL); + break; + case EVENT_BACKGROUND_TASK: + // uncomment this line to snap back to the clock face when the hour signal sounds: + // movement_move_to_face(state->watch_face_index); + if (watch_is_buzzer_or_led_enabled()) { + // if we are in the foreground, we can just beep. + movement_play_signal(); + } else { + // if we were in the background, we need to enable the buzzer peripheral first, + watch_enable_buzzer(); + // beep quickly (this call blocks for 275 ms), + movement_play_signal(); + // and then turn the buzzer peripheral off again. + watch_disable_buzzer(); + } break; default: break; @@ -83,3 +111,13 @@ void simple_clock_face_resign(movement_settings_t *settings, void *context) { (void) settings; (void) context; } + +bool simple_clock_face_wants_background_task(movement_settings_t *settings, void *context) { + (void) settings; + simple_clock_state_t *state = (simple_clock_state_t *)context; + if (!state->signal_enabled) return false; + + watch_date_time date_time = watch_rtc_get_date_time(); + + return date_time.unit.minute == 59; +} diff --git a/movement/watch_faces/clock/simple_clock_face.h b/movement/watch_faces/clock/simple_clock_face.h index a6cb6ac2..e2ad0ee8 100644 --- a/movement/watch_faces/clock/simple_clock_face.h +++ b/movement/watch_faces/clock/simple_clock_face.h @@ -3,19 +3,24 @@ #include "movement.h" +typedef struct { + uint32_t previous_date_time; + uint8_t watch_face_index; + bool signal_enabled; +} simple_clock_state_t; + void simple_clock_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); void simple_clock_face_activate(movement_settings_t *settings, void *context); bool simple_clock_face_loop(movement_event_t event, movement_settings_t *settings, void *context); void simple_clock_face_resign(movement_settings_t *settings, void *context); - -uint8_t simple_clock_face_get_weekday(uint16_t day, uint16_t month, uint16_t year); +bool simple_clock_face_wants_background_task(movement_settings_t *settings, void *context); static const watch_face_t simple_clock_face = { simple_clock_face_setup, simple_clock_face_activate, simple_clock_face_loop, simple_clock_face_resign, - NULL + simple_clock_face_wants_background_task }; -#endif // SIMPLE_CLOCK_FACE_H_ \ No newline at end of file +#endif // SIMPLE_CLOCK_FACE_H_ -- cgit v1.2.3 From 221e41f58cf671a71c3a174c8c8f8c4efd98e3c2 Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Tue, 21 Dec 2021 12:30:20 -0600 Subject: add 'hello there' face, demo for documentation --- movement/make/Makefile | 1 + movement/movement_config.h | 2 + movement/watch_faces/demos/hello_there_face.c | 56 +++++++++++++++++++++++++++ movement/watch_faces/demos/hello_there_face.h | 24 ++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 movement/watch_faces/demos/hello_there_face.c create mode 100644 movement/watch_faces/demos/hello_there_face.h (limited to 'movement') diff --git a/movement/make/Makefile b/movement/make/Makefile index b7a0e6e2..4910b102 100755 --- a/movement/make/Makefile +++ b/movement/make/Makefile @@ -40,6 +40,7 @@ SRCS += \ ../watch_faces/demos/voltage_face.c \ ../watch_faces/demos/lis2dh_logging_face.c \ ../watch_faces/demos/demo_face.c \ + ../watch_faces/demos/hello_there_face.c \ ../watch_faces/complications/beats_face.c \ ../watch_faces/complications/day_one_face.c \ ../watch_faces/complications/stopwatch_face.c \ diff --git a/movement/movement_config.h b/movement/movement_config.h index 6aeb0b83..047628ad 100644 --- a/movement/movement_config.h +++ b/movement/movement_config.h @@ -16,9 +16,11 @@ #include "totp_face.h" #include "lis2dh_logging_face.h" #include "demo_face.h" +#include "hello_there_face.h" const watch_face_t watch_faces[] = { simple_clock_face, + hello_there_face, preferences_face, set_time_face, }; diff --git a/movement/watch_faces/demos/hello_there_face.c b/movement/watch_faces/demos/hello_there_face.c new file mode 100644 index 00000000..e023b9d3 --- /dev/null +++ b/movement/watch_faces/demos/hello_there_face.c @@ -0,0 +1,56 @@ +#include +#include +#include "hello_there_face.h" +#include "watch.h" + +void hello_there_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + (void) settings; + (void) watch_face_index; + if (*context_ptr == NULL) { + *context_ptr = malloc(sizeof(hello_there_state_t)); + memset(*context_ptr, 0, sizeof(hello_there_state_t)); + } +} + +void hello_there_face_activate(movement_settings_t *settings, void *context) { + (void) settings; + hello_there_state_t *state = (hello_there_state_t *)context; + state->current_word = 0; + state->animating = true; +} + +bool hello_there_face_loop(movement_event_t event, movement_settings_t *settings, void *context) { + (void) settings; + hello_there_state_t *state = (hello_there_state_t *)context; + + switch (event.event_type) { + case EVENT_ACTIVATE: + case EVENT_TICK: + if (state->animating) { + if (state->current_word == 0) watch_display_string("Hello ", 4); + else watch_display_string(" there", 4); + state->current_word = (state->current_word + 1) % 2; + } + break; + case EVENT_MODE_BUTTON_UP: + movement_move_to_next_face(); + break; + case EVENT_LIGHT_BUTTON_UP: + movement_illuminate_led(); + break; + case EVENT_ALARM_BUTTON_UP: + state->animating = !state->animating; + break; + case EVENT_TIMEOUT: + movement_move_to_face(0); + default: + break; + } + + return true; +} + +void hello_there_face_resign(movement_settings_t *settings, void *context) { + (void) settings; + (void) context; +} diff --git a/movement/watch_faces/demos/hello_there_face.h b/movement/watch_faces/demos/hello_there_face.h new file mode 100644 index 00000000..0174b6f0 --- /dev/null +++ b/movement/watch_faces/demos/hello_there_face.h @@ -0,0 +1,24 @@ +#ifndef HELLO_THERE_FACE_H_ +#define HELLO_THERE_FACE_H_ + +#include "movement.h" + +typedef struct { + uint8_t current_word; + bool animating; +} hello_there_state_t; + +void hello_there_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr); +void hello_there_face_activate(movement_settings_t *settings, void *context); +bool hello_there_face_loop(movement_event_t event, movement_settings_t *settings, void *context); +void hello_there_face_resign(movement_settings_t *settings, void *context); + +static const watch_face_t hello_there_face = { + hello_there_face_setup, + hello_there_face_activate, + hello_there_face_loop, + hello_there_face_resign, + NULL +}; + +#endif // HELLO_THERE_FACE_H_ -- cgit v1.2.3 From 962837938221dd1b026755219da943609ffd059a Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Tue, 21 Dec 2021 12:58:05 -0600 Subject: add comments to 'hello there' face --- movement/movement_config.h | 1 - movement/watch_faces/demos/hello_there_face.c | 34 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'movement') diff --git a/movement/movement_config.h b/movement/movement_config.h index 047628ad..afb2902c 100644 --- a/movement/movement_config.h +++ b/movement/movement_config.h @@ -20,7 +20,6 @@ const watch_face_t watch_faces[] = { simple_clock_face, - hello_there_face, preferences_face, set_time_face, }; diff --git a/movement/watch_faces/demos/hello_there_face.c b/movement/watch_faces/demos/hello_there_face.c index e023b9d3..ad535533 100644 --- a/movement/watch_faces/demos/hello_there_face.c +++ b/movement/watch_faces/demos/hello_there_face.c @@ -4,18 +4,25 @@ #include "watch.h" void hello_there_face_setup(movement_settings_t *settings, uint8_t watch_face_index, void ** context_ptr) { + // These next two lines just silence the compiler warnings associated with unused parameters. + // We have no use for the settings or the watch_face_index, so we make that explicit here. (void) settings; (void) watch_face_index; + // At boot, context_ptr will be NULL indicating that we don't have anyplace to store our context. if (*context_ptr == NULL) { + // in this case, we allocate an area of memory sufficient to store the stuff we need to track. *context_ptr = malloc(sizeof(hello_there_state_t)); - memset(*context_ptr, 0, sizeof(hello_there_state_t)); } } void hello_there_face_activate(movement_settings_t *settings, void *context) { + // same as above: silence the warning, we don't need to check the settings. (void) settings; + // we do however need to set some things in our context. Here we cast it to the correct type... hello_there_state_t *state = (hello_there_state_t *)context; + // ...and set the initial state of our watch face. We start out displaying the word 'Hello', state->current_word = 0; + // and animate by default. state->animating = true; } @@ -26,22 +33,45 @@ bool hello_there_face_loop(movement_event_t event, movement_settings_t *settings switch (event.event_type) { case EVENT_ACTIVATE: case EVENT_TICK: + // on activate and tick, if we are animating, if (state->animating) { + // we display the current word, if (state->current_word == 0) watch_display_string("Hello ", 4); else watch_display_string(" there", 4); + // and increment it so that it will update on the next tick. state->current_word = (state->current_word + 1) % 2; } break; case EVENT_MODE_BUTTON_UP: + // when the user presses 'mode', we tell movement to move to the next watch face. + // movement will call our resign function, clear the screen, and transfer control + // to the next watch face in the list. movement_move_to_next_face(); break; case EVENT_LIGHT_BUTTON_UP: + // when the user presses 'light', we illuminate the LED. We could override this if + // our UI needed an additional button for input, consuming the light button press + // but not illuminating the LED. movement_illuminate_led(); break; case EVENT_ALARM_BUTTON_UP: + // when the user presses 'alarm', we toggle the state of the animation. If animating, + // we stop; if stopped, we resume. state->animating = !state->animating; break; + case EVENT_LOW_ENERGY_UPDATE: + // This low energy mode update occurs once a minute, if the watch face is in the + // foreground when Movement enters low energy mode. We have the option of supporting + // this mode, but since our watch face animates once a second, the "Hello there" face + // isn't very useful in this mode. So we choose not to support it. (continued below) + break; case EVENT_TIMEOUT: + // ... Instead, we respond to the timeout event. This event happens after a configurable + // interval on screen (1-30 minutes). The watch will give us this event as a chance to + // resign control if we want to, and in this case, we do. + // This function will return the watch to the first screen (usually a simple clock), + // and it will do it long before the watch enters low energy mode. This ensures we + // won't be on screen, and thus opts us out of getting the EVENT_LOW_ENERGY_UPDATE above. movement_move_to_face(0); default: break; @@ -51,6 +81,8 @@ bool hello_there_face_loop(movement_event_t event, movement_settings_t *settings } void hello_there_face_resign(movement_settings_t *settings, void *context) { + // our watch face, like most watch faces, has nothing special to do when resigning. + // watch faces that enable a peripheral or interact with a sensor may want to turn it off here. (void) settings; (void) context; } -- cgit v1.2.3 From 311cfdb5f45cab25053d7a188a2eb30e2c5e781b Mon Sep 17 00:00:00 2001 From: Joey Castillo Date: Wed, 22 Dec 2021 10:02:48 -0600 Subject: rearrange hello face, documentation reasons --- movement/watch_faces/demos/hello_there_face.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'movement') diff --git a/movement/watch_faces/demos/hello_there_face.c b/movement/watch_faces/demos/hello_there_face.c index ad535533..fa7ea54e 100644 --- a/movement/watch_faces/demos/hello_there_face.c +++ b/movement/watch_faces/demos/hello_there_face.c @@ -42,18 +42,18 @@ bool hello_there_face_loop(movement_event_t event, movement_settings_t *settings state->current_word = (state->current_word + 1) % 2; } break; - case EVENT_MODE_BUTTON_UP: - // when the user presses 'mode', we tell movement to move to the next watch face. - // movement will call our resign function, clear the screen, and transfer control - // to the next watch face in the list. - movement_move_to_next_face(); - break; case EVENT_LIGHT_BUTTON_UP: // when the user presses 'light', we illuminate the LED. We could override this if // our UI needed an additional button for input, consuming the light button press // but not illuminating the LED. movement_illuminate_led(); break; + case EVENT_MODE_BUTTON_UP: + // when the user presses 'mode', we tell movement to move to the next watch face. + // movement will call our resign function, clear the screen, and transfer control + // to the next watch face in the list. + movement_move_to_next_face(); + break; case EVENT_ALARM_BUTTON_UP: // when the user presses 'alarm', we toggle the state of the animation. If animating, // we stop; if stopped, we resume. -- cgit v1.2.3