diff options
Diffstat (limited to 'movement')
-rw-r--r-- | movement/movement.c | 36 | ||||
-rw-r--r-- | movement/movement.h | 9 |
2 files changed, 45 insertions, 0 deletions
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 <stdio.h> #include <stdbool.h> +#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); |