From 89eb99b80f4445798eea39d1a294c070d82e0f6c Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Wed, 17 May 2023 17:55:13 +0100 Subject: [PATCH] Move time update logic from display module to time manager --- components/display/display.c | 27 +++----------------- components/time/CMakeLists.txt | 2 +- components/time/time_manager.c | 45 ++++++++++++++++++++++++++++++++++ components/time/time_manager.h | 7 ++++++ main/main.c | 2 +- 5 files changed, 57 insertions(+), 26 deletions(-) diff --git a/components/display/display.c b/components/display/display.c index eafd34a..1016b22 100644 --- a/components/display/display.c +++ b/components/display/display.c @@ -16,7 +16,6 @@ #define TAG "Display" #define DRIVER_TASK_PERIOD_US 4000UL -#define TIME_UPDATE_PERIOD_US 1000000UL #define CLAMP(x, lim) ((x) > (lim) ? (lim) : (x)) @@ -52,11 +51,9 @@ static void show_time(unsigned hour, unsigned minute) show_digit(DISPLAY_DIGIT_4, minute % 10); } -static void update_time(void *arg) +static void update_time(const Time *time) { - (void)arg; - const Time time = get_time(); - show_time(time.hour, time.minute); + show_time(time->hour, time->minute); } void display_init() @@ -83,23 +80,5 @@ void display_init() FATAL(); } - esp_timer_handle_t update_timer; - const esp_timer_create_args_t update_timer_config = { - .callback = &update_time, - .arg = NULL, - .name = "display driver task", - }; - error = esp_timer_create(&update_timer_config, &update_timer); - if (error != ESP_OK) { - ESP_LOGE(TAG, "Error creating timer for driver task: %04x", error); - FATAL(); - } - - error = esp_timer_start_periodic(update_timer, TIME_UPDATE_PERIOD_US); - if (error != ESP_OK) { - ESP_LOGE(TAG, "Error starting timer for driver task: %04x", error); - FATAL(); - } - - update_time(NULL); + add_time_callback(&update_time); } diff --git a/components/time/CMakeLists.txt b/components/time/CMakeLists.txt index 48e5ec5..9b8272a 100644 --- a/components/time/CMakeLists.txt +++ b/components/time/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( SRCS "time_manager.c" INCLUDE_DIRS "." - REQUIRES console_wrapper lwip nvs_flash settings + REQUIRES console_wrapper esp_timer fatal lwip nvs_flash settings ) diff --git a/components/time/time_manager.c b/components/time/time_manager.c index c257942..1024661 100644 --- a/components/time/time_manager.c +++ b/components/time/time_manager.c @@ -10,6 +10,8 @@ #include "esp_log.h" #include "esp_sntp.h" +#include "esp_timer.h" +#include "fatal.h" #include "freertos/FreeRTOS.h" #include "nvs_flash.h" #include @@ -22,6 +24,12 @@ #define TM_YEAR_OFFSET 1900 #define TM_MONTH_OFFSET 1 +#define UPDATE_PERIOD_US 1000000UL +#define MAX_CALLBACKS 8 + +static TimeCallback callbacks[MAX_CALLBACKS]; +static unsigned callback_count; + static void handle_timezone_update(const char *timezone) { setenv("TZ", timezone, 1); @@ -85,6 +93,13 @@ static int store_time(void) return error == ESP_OK ? 0 : 1; } +static void run_callbacks(void *arg) +{ + const Time time = get_time(); + for (unsigned i = 0; i < callback_count; ++i) + callbacks[i](&time); +} + static int time_command_func(int argc, char **argv) { if (argc == 1) { @@ -177,6 +192,8 @@ static void time_saver_func(void *arg) void time_manager_init(void) { + callback_count = 0; + char timezone[SETTINGS_MAX_VALUE_SIZE]; (void)settings_get_timezone(timezone, SETTINGS_MAX_VALUE_SIZE); handle_timezone_update(timezone); @@ -225,6 +242,34 @@ void time_manager_init(void) (void)xTaskCreate( &time_saver_func, "time saver", CONFIG_DEFAULT_TASK_STACK, NULL, 1, NULL); + + // Create and start timer + esp_timer_handle_t update_timer; + const esp_timer_create_args_t update_timer_config = { + .callback = &run_callbacks, + .arg = NULL, + .name = "time updates", + }; + error = esp_timer_create(&update_timer_config, &update_timer); + if (error != ESP_OK) { + ESP_LOGE(TAG, "Error creating update timer: %04x", error); + FATAL(); + } + error = esp_timer_start_periodic(update_timer, UPDATE_PERIOD_US); + if (error != ESP_OK) { + ESP_LOGE(TAG, "Error starting update timer: %04x", error); + FATAL(); + } +} + +void add_time_callback(TimeCallback callback) +{ + if (callback_count >= MAX_CALLBACKS) { + ESP_LOGE(TAG, "Max number of time callbacks exceeded"); + return; + } + callbacks[callback_count] = callback; + ++callback_count; } Time get_time(void) diff --git a/components/time/time_manager.h b/components/time/time_manager.h index 305b544..bbe5865 100644 --- a/components/time/time_manager.h +++ b/components/time/time_manager.h @@ -27,11 +27,18 @@ typedef enum { WEEK_DAY_SUNDAY, } WeekDay; +typedef void (*TimeCallback)(const Time *time); + /** * Initialize the time module. */ void time_manager_init(void); +/** + * Add a callback to be regularly invoked with time updates. + */ +void add_time_callback(TimeCallback callback); + /** * Get the current time. */ diff --git a/main/main.c b/main/main.c index 957bc5d..a3fd129 100644 --- a/main/main.c +++ b/main/main.c @@ -15,9 +15,9 @@ void app_main(void) { console_init(); settings_init(); - display_init(); wifi_init(); time_manager_init(); + display_init(); sound_init(); buttons_init(); }