From 27ab799e858ff98e66c4d163dc7a2da869e678e8 Mon Sep 17 00:00:00 2001 From: Konrad Rieck Date: Fri, 8 Mar 2024 14:50:32 +0100 Subject: [PATCH] Fixed bugs and improved watchface - A background task is only scheduled if the alarm option is activated. If the option is enabled, an alarm sounds when the next deadline is reached. If the option is disabled, no alarm sounds and the watch can enter low energy sleep. - Fixed tick frequency error. During running mode, the clock ticks at 1Hz. This is set in the init function `_running_init` and thus ensures that we do not run too fast when returning from the setting mode. - Minor corrections to comments and indentations. --- .../watch_faces/complication/deadline_face.c | 63 +++++++++++++------ .../watch_faces/complication/deadline_face.h | 2 +- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/movement/watch_faces/complication/deadline_face.c b/movement/watch_faces/complication/deadline_face.c index c6b074d5..32679403 100644 --- a/movement/watch_faces/complication/deadline_face.c +++ b/movement/watch_faces/complication/deadline_face.c @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Konrad Rieck + * Copyright (c) 2023-2024 Konrad Rieck * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -65,6 +65,12 @@ * * - A *long press* on the *alarm button* activates settings mode and * enables configuring the currently selected deadline. + * + * - A *long press* on the *light button* activates a deadline alarm. The + * bell icon is displayed, and the alarm will ring upon reaching any of + * the deadlines set. It is important to note that the watch will not + * enter low-energy sleep mode while the alarm is enabled. + * * * ## Settings Mode * @@ -101,24 +107,24 @@ const char settings_titles[SETTINGS_NUM][3] = { "YR", "MO", "DA", "HR", "M1" }; /* Local functions */ -static void _running_init(movement_settings_t *settings, deadline_state_t * state); +static void _running_init(movement_settings_t *settings, deadline_state_t *state); static bool _running_loop(movement_event_t event, movement_settings_t *settings, void *context); -static void _running_display(movement_event_t event, movement_settings_t *settings, deadline_state_t * state); -static void _setting_init(movement_settings_t *settings, deadline_state_t * state); +static void _running_display(movement_event_t event, movement_settings_t *settings, deadline_state_t *state); +static void _setting_init(movement_settings_t *settings, deadline_state_t *state); static bool _setting_loop(movement_event_t event, movement_settings_t *settings, void *context); -static void _setting_display(movement_event_t event, movement_settings_t *settings, deadline_state_t * state, watch_date_time date); +static void _setting_display(movement_event_t event, movement_settings_t *settings, deadline_state_t *state, watch_date_time date); /* Utility functions */ -static void _increment_date(movement_settings_t *settings, deadline_state_t * state, watch_date_time date_time); +static void _increment_date(movement_settings_t *settings, deadline_state_t *state, watch_date_time date_time); static inline int32_t _get_tz_offset(movement_settings_t *settings); -static inline void _change_tick_freq(uint8_t freq, deadline_state_t * state); +static inline void _change_tick_freq(uint8_t freq, deadline_state_t *state); static inline bool _is_leap(int16_t y); static inline int _days_in_month(int16_t mpnth, int16_t y); static inline unsigned int _mod(int a, int b); static inline void _beep_button(movement_settings_t *settings); static inline void _beep_enable(movement_settings_t *settings); static inline void _beep_disable(movement_settings_t *settings); -static inline void _reset_deadline(movement_settings_t *settings, deadline_state_t * state); +static inline void _reset_deadline(movement_settings_t *settings, deadline_state_t *state); /* Check for leap year */ static inline bool _is_leap(int16_t y) @@ -147,7 +153,7 @@ static inline int _days_in_month(int16_t month, int16_t year) } } -/* Calculate time zone offset */ +/* Return time zone offset */ static inline int32_t _get_tz_offset(movement_settings_t *settings) { return movement_timezone_offsets[settings->bit.time_zone] * 60; @@ -156,7 +162,7 @@ static inline int32_t _get_tz_offset(movement_settings_t *settings) /* Beep for a button press*/ static inline void _beep_button(movement_settings_t *settings) { - // play a beep as confirmation for a button press (if applicable) + // Play a beep as confirmation for a button press (if applicable) if (!settings->bit.button_should_sound) return; @@ -289,7 +295,7 @@ static void _running_display(movement_event_t event, movement_settings_t *settin (void) event; (void) settings; - /* seconds, minutes, hours, days, months, years */ + /* Seconds, minutes, hours, days, months, years */ int16_t unit[] = { 0, 0, 0, 0, 0, 0 }; uint8_t i, range[] = { 60, 60, 24, 30, 12, 0 }; char buf[16]; @@ -370,6 +376,9 @@ static void _running_init(movement_settings_t *settings, deadline_state_t *state watch_clear_indicator(WATCH_INDICATOR_24H); watch_clear_indicator(WATCH_INDICATOR_PM); watch_set_colon(); + + /* Ensure 1Hz updates only */ + _change_tick_freq(1, state); } /* Loop of running mode */ @@ -397,15 +406,21 @@ static bool _running_loop(movement_event_t event, movement_settings_t *settings, case EVENT_LIGHT_LONG_PRESS: _beep_button(settings); state->alarm_enabled = !state->alarm_enabled; + if (state->alarm_enabled) { + _schedule_alarm(settings, state); + } else { + movement_cancel_background_task(); + } _running_display(event, settings, state); break; case EVENT_TIMEOUT: movement_move_to_face(0); break; case EVENT_BACKGROUND_TASK: - if (state->alarm_enabled) + if (state->alarm_enabled) { movement_play_alarm(); - _schedule_alarm(settings, state); + _schedule_alarm(settings, state); + } break; case EVENT_LOW_ENERGY_UPDATE: break; @@ -465,13 +480,15 @@ static void _setting_display(movement_event_t event, movement_settings_t *settin /* Init setting mode */ static void _setting_init(movement_settings_t *settings, deadline_state_t *state) { - _change_tick_freq(1, state); state->current_page = 0; /* Init fresh deadline to next day */ if (state->deadlines[state->current_index] == 0) { _reset_deadline(settings, state); } + + /* Ensure 1Hz updates only */ + _change_tick_freq(1, state); } /* Loop of setting mode */ @@ -517,20 +534,30 @@ static bool _setting_loop(movement_event_t event, movement_settings_t *settings, break; case EVENT_TIMEOUT: _beep_button(settings); - _schedule_alarm(settings, state); _change_tick_freq(1, state); + + /* Update alarm as deadlines may have changed */ + if (state->alarm_enabled) { + _schedule_alarm(settings, state); + } movement_move_to_face(0); break; case EVENT_MODE_BUTTON_UP: _beep_disable(settings); - _schedule_alarm(settings, state); _running_init(settings, state); + _running_display(event, settings, state); + + /* Update alarm as deadlines may have changed */ + if (state->alarm_enabled) { + _schedule_alarm(settings, state); + } state->mode = DEADLINE_FACE_RUNNING; break; case EVENT_BACKGROUND_TASK: - if (state->alarm_enabled) + if (state->alarm_enabled) { movement_play_alarm(); - _schedule_alarm(settings, state); + _schedule_alarm(settings, state); + } break; default: return movement_default_loop_handler(event, settings); diff --git a/movement/watch_faces/complication/deadline_face.h b/movement/watch_faces/complication/deadline_face.h index 3b554b63..9f175b06 100644 --- a/movement/watch_faces/complication/deadline_face.h +++ b/movement/watch_faces/complication/deadline_face.h @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2023 Konrad Rieck + * Copyright (c) 2023-2024 Konrad Rieck * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the