Use timer interrupt to update time

This commit is contained in:
Djuri Baars 2023-11-06 18:38:25 +01:00
parent 94c2a7e43b
commit 415aa3a606
2 changed files with 47 additions and 28 deletions

View file

@ -1,44 +1,59 @@
#include "minute.hpp" #include "minute.hpp"
TaskHandle_t minuteTaskHandle = NULL; TaskHandle_t minuteTaskHandle = NULL;
// Define a type for the event callback // Define a type for the event callback
std::vector<EventCallback> minuteEventCallbacks; // Define a vector to hold multiple event callbacks std::vector<EventCallback> minuteEventCallbacks; // Define a vector to hold multiple event callbacks
bool eventTriggered = false; // Initialize the event triggered flag to false bool eventTriggered = false; // Initialize the event triggered flag to false
const int usPerMinute = 60 * 1000000;
void minuteTask(void * parameter) { void minuteTask(void *parameter)
while(1) { {
#ifdef IS_3C // wait 5 minutes in case of a 3 color screen otherwise it keeps refreshing
if(rtc.getMinute() % 5 == 0 && !eventTriggered) { esp_timer_handle_t minuteTimer;
eventTriggered = true; const esp_timer_create_args_t minuteTimerConfig = {
for(auto &callback : minuteEventCallbacks) { // Loop through all the event callbacks and call them .callback = &minuteTimerISR,
callback(); .name = "minute_timer"};
}
esp_timer_create(&minuteTimerConfig, &minuteTimer);
time_t currentTime;
struct tm timeinfo;
time(&currentTime);
localtime_r(&currentTime, &timeinfo);
uint32_t secondsUntilNextMinute = 60 - timeinfo.tm_sec;
if (secondsUntilNextMinute > 0)
vTaskDelay(pdMS_TO_TICKS((secondsUntilNextMinute * 1000)));
esp_timer_start_periodic(minuteTimer, usPerMinute);
while (1)
{
for (auto &callback : minuteEventCallbacks)
{
callback();
} }
if(rtc.getMinute() % 5 != 0 && eventTriggered) { // Reset the event triggered flag if the second is not 0
eventTriggered = false; ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
} }
vTaskDelay(pdMS_TO_TICKS(1000)); // Sleep for 1000 milliseconds to avoid busy waiting }
#else
if(rtc.getSecond() == 0 && !eventTriggered) { void IRAM_ATTR minuteTimerISR(void *arg)
eventTriggered = true; {
for(auto &callback : minuteEventCallbacks) { // Loop through all the event callbacks and call them BaseType_t xHigherPriorityTaskWoken = pdFALSE;
callback(); vTaskNotifyGiveFromISR(minuteTaskHandle, &xHigherPriorityTaskWoken);
} if (xHigherPriorityTaskWoken == pdTRUE)
} {
if(rtc.getSecond() != 0) { // Reset the event triggered flag if the second is not 0 portYIELD_FROM_ISR();
eventTriggered = false;
}
vTaskDelay(pdMS_TO_TICKS(1000)); // Sleep for 1000 milliseconds to avoid busy waiting
#endif
} }
} }
void setupMinuteEvent() void setupMinuteEvent()
{ {
xTaskCreate(minuteTask, "MinuteTask", 4096, NULL, 1, &minuteTaskHandle); // Create the FreeRTOS task xTaskCreate(minuteTask, "MinuteTask", 4096, NULL, 1, &minuteTaskHandle); // Create the FreeRTOS task
} }
void registerNewMinuteCallback(const EventCallback cb) void registerNewMinuteCallback(const EventCallback cb)
{ {
minuteEventCallbacks.push_back(cb); minuteEventCallbacks.push_back(cb);
} }

View file

@ -6,9 +6,13 @@
#include <freertos/task.h> #include <freertos/task.h>
#include <vector> #include <vector>
#include "shared.hpp" #include "shared.hpp"
#include <esp_timer.h>
#include <time.h>
extern TaskHandle_t minuteTaskHandle; extern TaskHandle_t minuteTaskHandle;
void minuteTask(void *pvParameters); void minuteTask(void *pvParameters);
void setupMinuteEvent(); void setupMinuteEvent();
void IRAM_ATTR minuteTimerISR(void* arg);
void registerNewMinuteCallback(const EventCallback cb); void registerNewMinuteCallback(const EventCallback cb);