From b34ff32f76f355866c3bd267dcc687c0d1958d29 Mon Sep 17 00:00:00 2001 From: JF Date: Sat, 18 Jan 2020 13:56:25 +0100 Subject: [PATCH] DateTimeController is now updated in the system task. It runs every 1s in Running mode, and every 1h in sleep mode. This should allow to keep the watch on time for more than 4 hours. --- .../DateTime/DateTimeController.cpp | 58 ++++++++++++++++--- src/Components/DateTime/DateTimeController.h | 8 ++- src/DisplayApp/DisplayApp.cpp | 55 +++++------------- src/DisplayApp/DisplayApp.h | 8 +-- src/main.cpp | 40 ++++++++++++- 5 files changed, 110 insertions(+), 59 deletions(-) diff --git a/src/Components/DateTime/DateTimeController.cpp b/src/Components/DateTime/DateTimeController.cpp index 1c15642e..cd512705 100644 --- a/src/Components/DateTime/DateTimeController.cpp +++ b/src/Components/DateTime/DateTimeController.cpp @@ -1,16 +1,56 @@ #include "DateTimeController.h" +#include +#include using namespace Pinetime::Controllers; -void DateTime::UpdateTime(uint16_t year, Months month, uint8_t day, Days dayOfWeek, uint8_t hour, uint8_t minute, - uint8_t second) { - this->year = year; - this->month = month; - this->dayOfWeek = dayOfWeek; - this->day = day; - this->hour = hour; - this->minute = minute; - this->second = second; +void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, + uint8_t second, uint32_t systickCounter) { + + currentDateTime = {}; + currentDateTime += date::years( year-1970); + currentDateTime += date::days( day - 1); + currentDateTime += date::months( month - 1); + + currentDateTime += std::chrono::hours(hour); + currentDateTime += std::chrono::minutes (minute); + currentDateTime += std::chrono::seconds (second); + + currentDateTime -= std::chrono::hours(3); // TODO WHYYYY? + NRF_LOG_INFO("%d %d %d ", day, month, year); + NRF_LOG_INFO("%d %d %d ", hour, minute, second); + previousSystickCounter = systickCounter; + UpdateTime(systickCounter); + NRF_LOG_INFO("* %d %d %d ", this->hour, this->minute, this->second); + NRF_LOG_INFO("* %d %d %d ", this->day, this->month, this->year); + + +} + +void DateTime::UpdateTime(uint32_t systickCounter) { + uint32_t systickDelta = 0; + if(systickCounter < previousSystickCounter) { + systickDelta = 0xffffff - previousSystickCounter; + systickDelta += systickCounter + 1; + } else { + systickDelta = systickCounter - previousSystickCounter; + } + + previousSystickCounter = systickCounter; + currentDateTime += std::chrono::milliseconds(systickDelta); + + auto dp = date::floor(currentDateTime); + auto time = date::make_time(currentDateTime-dp); + auto yearMonthDay = date::year_month_day(dp); + + year = (int)yearMonthDay.year(); + month = static_cast((unsigned)yearMonthDay.month()); + day = (unsigned)yearMonthDay.day(); + dayOfWeek = static_cast(date::weekday(yearMonthDay).iso_encoding()); + + hour = time.hours().count(); + minute = time.minutes().count(); + second = time.seconds().count(); } diff --git a/src/Components/DateTime/DateTimeController.h b/src/Components/DateTime/DateTimeController.h index edbb46c7..632fafe6 100644 --- a/src/Components/DateTime/DateTimeController.h +++ b/src/Components/DateTime/DateTimeController.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace Pinetime { namespace Controllers { @@ -9,7 +10,8 @@ namespace Pinetime { enum class Days : uint8_t {Unknown, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}; enum class Months : uint8_t {Unknown, January, February, March, April, May, June, July, August, September, October, November, December}; - void UpdateTime(uint16_t year, Months month, uint8_t day, Days dayOfWeek, uint8_t hour, uint8_t minute, uint8_t second); + void SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, uint8_t second, uint32_t systickCounter); + void UpdateTime(uint32_t systickCounter); uint16_t Year() const { return year; } Months Month() const { return month; } uint8_t Day() const { return day; } @@ -25,6 +27,10 @@ namespace Pinetime { uint8_t hour = 0; uint8_t minute = 0; uint8_t second = 0; + + uint32_t previousSystickCounter = 0; + std::chrono::time_point currentDateTime; + }; } } \ No newline at end of file diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 13661609..fe7e68dc 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -151,16 +151,6 @@ void DisplayApp::Refresh() { state = States::Running; break; case Messages::UpdateDateTime: - currentDateTime = {}; - currentDateTime += date::years( dateTimeController.Year()-1970); - currentDateTime += date::days( dateTimeController.Day() - 1); - currentDateTime += date::months( (int)dateTimeController.Month() - 1); - - currentDateTime += std::chrono::hours(dateTimeController.Hours()); - currentDateTime += std::chrono::minutes (dateTimeController.Minutes()); - currentDateTime += std::chrono::seconds (dateTimeController.Seconds()); - - currentDateTime -= std::chrono::hours(3); // TODO WHYYYY? break; case Messages::UpdateBleConnection: bleConnectionUpdated = true; @@ -177,17 +167,6 @@ void DisplayApp::Refresh() { } void DisplayApp::RunningState() { - uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); - uint32_t systickDelta = 0; - if(systick_counter < previousSystickCounter) { - systickDelta = 0xffffff - previousSystickCounter; - systickDelta += systick_counter + 1; - } else { - systickDelta = systick_counter - previousSystickCounter; - } - - previousSystickCounter = systick_counter; - if (batteryLevelUpdated) { char batteryChar[11]; uint16_t newBatteryValue = batteryController.PercentRemaining(); @@ -205,27 +184,11 @@ void DisplayApp::RunningState() { gfx->DrawString(10, 0, color, "BLE", &smallFont, false); } - // TODO date/time management should be done in module DateTimeController - currentDateTime += std::chrono::milliseconds(systickDelta); - - auto dp = date::floor(currentDateTime); - auto time = date::make_time(currentDateTime-dp); - auto ymd = date::year_month_day(dp); - - auto year = (int)ymd.year(); - auto month = (unsigned)ymd.month(); - auto day = (unsigned)ymd.day(); - auto weekday = date::weekday(ymd); - - auto hh = time.hours().count(); - auto mm = time.minutes().count(); - auto ss = time.seconds().count(); - char minutesChar[3]; - sprintf(minutesChar, "%02d", mm); + sprintf(minutesChar, "%02d", dateTimeController.Minutes()); char hoursChar[3]; - sprintf(hoursChar, "%02d", hh); + sprintf(hoursChar, "%02d", dateTimeController.Hours()); uint8_t x = 7; if (hoursChar[0] != currentChar[0]) { @@ -251,13 +214,21 @@ void DisplayApp::RunningState() { currentChar[3] = minutesChar[1]; } - if (ymd != currentYmd) { + auto y = dateTimeController.Year(); + auto m = dateTimeController.Month(); + auto wd = dateTimeController.DayOfWeek(); + auto d = dateTimeController.Day(); + + if ((y != currentYear) || (m != currentMonth) || (wd != currentDayOfWeek) || (d != currentDay)) { gfx->FillRectangle(0,180, 240, 15, 0x0000); char dateStr[22]; - sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(Pinetime::Controllers::DateTime::Days(weekday.iso_encoding())), day, MonthToString((Pinetime::Controllers::DateTime::Months )month), year); + sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(wd), d, MonthToString(m), y); gfx->DrawString(10, 180, 0xffff, dateStr, &smallFont, false); - currentYmd = ymd; + currentYear = y; + currentMonth = m; + currentDayOfWeek = wd; + currentDay = d; } } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 7e717ff8..8e92c7bb 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -43,8 +43,10 @@ namespace Pinetime { static const char* DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek); char currentChar[4]; - uint32_t deltaSeconds = 0; - date::year_month_day currentYmd; + uint16_t currentYear = 1970; + Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; + Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; + uint8_t currentDay = 0; States state = States::Running; void RunningState(); @@ -65,8 +67,6 @@ namespace Pinetime { Pinetime::Drivers::Cst816S touchPanel; void OnTouchEvent(); - uint32_t previousSystickCounter = 0; - std::chrono::time_point currentDateTime; }; } } diff --git a/src/main.cpp b/src/main.cpp index ac6f3fcc..593e01ed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,6 +37,9 @@ void ble_manager_set_ble_connection_callback(void (*connection)()); void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinButton = 13; static constexpr uint8_t pinTouchIrq = 28; +QueueHandle_t systemTaksMsgQueue; +enum class SystemTaskMessages {GoToSleep, GoToRunning}; +void SystemTask_PushMessage(SystemTaskMessages message); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if(pin == pinTouchIrq) { @@ -52,17 +55,30 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action void DebounceTimerCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); if(isSleeping) { + SystemTask_PushMessage(SystemTaskMessages::GoToRunning); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); isSleeping = false; batteryController.Update(); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); } else { + SystemTask_PushMessage(SystemTaskMessages::GoToSleep); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); isSleeping = true; } } +void SystemTask_PushMessage(SystemTaskMessages message) { + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(systemTaksMsgQueue, &message, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + /* Actual macro used here is port specific. */ + // TODO : should I do something here? + } +} + +// TODO The whole SystemTask should go in its own class void SystemTask(void *) { APP_GPIOTE_INIT(2); bool erase_bonds=false; @@ -97,7 +113,24 @@ void SystemTask(void *) { pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup; nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); - vTaskSuspend(nullptr); + + systemTaksMsgQueue = xQueueCreate(10, 1); + bool systemTaskSleeping = false; + + while(true) { + uint8_t msg; + + if (xQueueReceive(systemTaksMsgQueue, &msg, systemTaskSleeping?3600000 : 1000)) { + SystemTaskMessages message = static_cast(msg); + switch(message) { + case SystemTaskMessages::GoToRunning: systemTaskSleeping = false; break; + case SystemTaskMessages::GoToSleep: systemTaskSleeping = true; break; + default: break; + } + } + uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); + dateTimeController.UpdateTime(systick_counter); + } } void OnBleConnection() { @@ -118,8 +151,9 @@ void OnNewTime(current_time_char_t* currentTime) { auto hour = currentTime->exact_time_256.day_date_time.date_time.hours; auto minute = currentTime->exact_time_256.day_date_time.date_time.minutes; auto second = currentTime->exact_time_256.day_date_time.date_time.seconds; - dateTimeController.UpdateTime(year, static_cast(month), day, static_cast(dayOfWeek), hour, minute, second); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime); + + dateTimeController.SetTime(year, month, day, + dayOfWeek, hour, minute, second, nrf_rtc_counter_get(portNRF_RTC_REG)); } int main(void) {