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.
This commit is contained in:
JF 2020-01-18 13:56:25 +01:00
parent 8daa830ee0
commit b34ff32f76
5 changed files with 110 additions and 59 deletions

View File

@ -1,16 +1,56 @@
#include "DateTimeController.h" #include "DateTimeController.h"
#include <date/date.h>
#include <libraries/log/nrf_log.h>
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
void DateTime::UpdateTime(uint16_t year, Months month, uint8_t day, Days dayOfWeek, uint8_t hour, uint8_t minute, void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute,
uint8_t second) { uint8_t second, uint32_t systickCounter) {
this->year = year;
this->month = month; currentDateTime = {};
this->dayOfWeek = dayOfWeek; currentDateTime += date::years( year-1970);
this->day = day; currentDateTime += date::days( day - 1);
this->hour = hour; currentDateTime += date::months( month - 1);
this->minute = minute;
this->second = second; 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<date::days>(currentDateTime);
auto time = date::make_time(currentDateTime-dp);
auto yearMonthDay = date::year_month_day(dp);
year = (int)yearMonthDay.year();
month = static_cast<Months>((unsigned)yearMonthDay.month());
day = (unsigned)yearMonthDay.day();
dayOfWeek = static_cast<Days>(date::weekday(yearMonthDay).iso_encoding());
hour = time.hours().count();
minute = time.minutes().count();
second = time.seconds().count();
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <chrono>
namespace Pinetime { namespace Pinetime {
namespace Controllers { namespace Controllers {
@ -9,7 +10,8 @@ namespace Pinetime {
enum class Days : uint8_t {Unknown, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}; 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}; 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; } uint16_t Year() const { return year; }
Months Month() const { return month; } Months Month() const { return month; }
uint8_t Day() const { return day; } uint8_t Day() const { return day; }
@ -25,6 +27,10 @@ namespace Pinetime {
uint8_t hour = 0; uint8_t hour = 0;
uint8_t minute = 0; uint8_t minute = 0;
uint8_t second = 0; uint8_t second = 0;
uint32_t previousSystickCounter = 0;
std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> currentDateTime;
}; };
} }
} }

View File

@ -151,16 +151,6 @@ void DisplayApp::Refresh() {
state = States::Running; state = States::Running;
break; break;
case Messages::UpdateDateTime: 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; break;
case Messages::UpdateBleConnection: case Messages::UpdateBleConnection:
bleConnectionUpdated = true; bleConnectionUpdated = true;
@ -177,17 +167,6 @@ void DisplayApp::Refresh() {
} }
void DisplayApp::RunningState() { 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) { if (batteryLevelUpdated) {
char batteryChar[11]; char batteryChar[11];
uint16_t newBatteryValue = batteryController.PercentRemaining(); uint16_t newBatteryValue = batteryController.PercentRemaining();
@ -205,27 +184,11 @@ void DisplayApp::RunningState() {
gfx->DrawString(10, 0, color, "BLE", &smallFont, false); 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<date::days>(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]; char minutesChar[3];
sprintf(minutesChar, "%02d", mm); sprintf(minutesChar, "%02d", dateTimeController.Minutes());
char hoursChar[3]; char hoursChar[3];
sprintf(hoursChar, "%02d", hh); sprintf(hoursChar, "%02d", dateTimeController.Hours());
uint8_t x = 7; uint8_t x = 7;
if (hoursChar[0] != currentChar[0]) { if (hoursChar[0] != currentChar[0]) {
@ -251,13 +214,21 @@ void DisplayApp::RunningState() {
currentChar[3] = minutesChar[1]; 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); gfx->FillRectangle(0,180, 240, 15, 0x0000);
char dateStr[22]; 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); gfx->DrawString(10, 180, 0xffff, dateStr, &smallFont, false);
currentYmd = ymd; currentYear = y;
currentMonth = m;
currentDayOfWeek = wd;
currentDay = d;
} }
} }

View File

@ -43,8 +43,10 @@ namespace Pinetime {
static const char* DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek); static const char* DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek);
char currentChar[4]; char currentChar[4];
uint32_t deltaSeconds = 0; uint16_t currentYear = 1970;
date::year_month_day currentYmd; 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; States state = States::Running;
void RunningState(); void RunningState();
@ -65,8 +67,6 @@ namespace Pinetime {
Pinetime::Drivers::Cst816S touchPanel; Pinetime::Drivers::Cst816S touchPanel;
void OnTouchEvent(); void OnTouchEvent();
uint32_t previousSystickCounter = 0;
std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> currentDateTime;
}; };
} }
} }

View File

@ -37,6 +37,9 @@ void ble_manager_set_ble_connection_callback(void (*connection)());
void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); void ble_manager_set_ble_disconnection_callback(void (*disconnection)());
static constexpr uint8_t pinButton = 13; static constexpr uint8_t pinButton = 13;
static constexpr uint8_t pinTouchIrq = 28; 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) { void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
if(pin == pinTouchIrq) { 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) { void DebounceTimerCallback(TimerHandle_t xTimer) {
xTimerStop(xTimer, 0); xTimerStop(xTimer, 0);
if(isSleeping) { if(isSleeping) {
SystemTask_PushMessage(SystemTaskMessages::GoToRunning);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning);
isSleeping = false; isSleeping = false;
batteryController.Update(); batteryController.Update();
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel);
} }
else { else {
SystemTask_PushMessage(SystemTaskMessages::GoToSleep);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
isSleeping = true; 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 *) { void SystemTask(void *) {
APP_GPIOTE_INIT(2); APP_GPIOTE_INIT(2);
bool erase_bonds=false; bool erase_bonds=false;
@ -97,7 +113,24 @@ void SystemTask(void *) {
pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup; pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup;
nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); 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<SystemTaskMessages >(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() { 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 hour = currentTime->exact_time_256.day_date_time.date_time.hours;
auto minute = currentTime->exact_time_256.day_date_time.date_time.minutes; auto minute = currentTime->exact_time_256.day_date_time.date_time.minutes;
auto second = currentTime->exact_time_256.day_date_time.date_time.seconds; auto second = currentTime->exact_time_256.day_date_time.date_time.seconds;
dateTimeController.UpdateTime(year, static_cast<Pinetime::Controllers::DateTime::Months >(month), day, static_cast<Pinetime::Controllers::DateTime::Days>(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) { int main(void) {