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 <date/date.h>
#include <libraries/log/nrf_log.h>
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<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
#include <cstdint>
#include <chrono>
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<std::chrono::system_clock, std::chrono::milliseconds> currentDateTime;
};
}
}

View File

@ -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<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];
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;
}
}

View File

@ -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<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)());
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<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() {
@ -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<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) {