Continuous time updates

This commit is contained in:
mark9064 2023-12-28 20:56:37 +00:00 committed by JF
parent 9e406c70f9
commit a449b272f7
6 changed files with 43 additions and 26 deletions

View file

@ -80,7 +80,7 @@ int WeatherCallback(uint16_t /*connHandle*/, uint16_t /*attrHandle*/, struct ble
return static_cast<Pinetime::Controllers::SimpleWeatherService*>(arg)->OnCommand(ctxt); return static_cast<Pinetime::Controllers::SimpleWeatherService*>(arg)->OnCommand(ctxt);
} }
SimpleWeatherService::SimpleWeatherService(const DateTime& dateTimeController) : dateTimeController(dateTimeController) { SimpleWeatherService::SimpleWeatherService(DateTime& dateTimeController) : dateTimeController(dateTimeController) {
} }
void SimpleWeatherService::Init() { void SimpleWeatherService::Init() {

View file

@ -40,7 +40,7 @@ namespace Pinetime {
class SimpleWeatherService { class SimpleWeatherService {
public: public:
explicit SimpleWeatherService(const DateTime& dateTimeController); explicit SimpleWeatherService(DateTime& dateTimeController);
void Init(); void Init();
@ -140,7 +140,7 @@ namespace Pinetime {
uint16_t eventHandle {}; uint16_t eventHandle {};
const Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Controllers::DateTime& dateTimeController;
std::optional<CurrentWeather> currentWeather; std::optional<CurrentWeather> currentWeather;
std::optional<Forecast> forecast; std::optional<Forecast> forecast;

View file

@ -1,6 +1,7 @@
#include "components/datetime/DateTimeController.h" #include "components/datetime/DateTimeController.h"
#include <libraries/log/nrf_log.h> #include <libraries/log/nrf_log.h>
#include <systemtask/SystemTask.h> #include <systemtask/SystemTask.h>
#include <hal/nrf_rtc.h>
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
@ -12,11 +13,16 @@ namespace {
} }
DateTime::DateTime(Controllers::Settings& settingsController) : settingsController {settingsController} { DateTime::DateTime(Controllers::Settings& settingsController) : settingsController {settingsController} {
mutex = xSemaphoreCreateMutex();
ASSERT(mutex != nullptr);
xSemaphoreGive(mutex);
} }
void DateTime::SetCurrentTime(std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t) { void DateTime::SetCurrentTime(std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t) {
xSemaphoreTake(mutex, portMAX_DELAY);
this->currentDateTime = t; this->currentDateTime = t;
UpdateTime(previousSystickCounter); // Update internal state without updating the time UpdateTime(previousSystickCounter, true); // Update internal state without updating the time
xSemaphoreGive(mutex);
} }
void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
@ -29,13 +35,15 @@ void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
/* .tm_year = */ year - 1900, /* .tm_year = */ year - 1900,
}; };
tm.tm_isdst = -1; // Use DST value from local time zone
currentDateTime = std::chrono::system_clock::from_time_t(std::mktime(&tm));
NRF_LOG_INFO("%d %d %d ", day, month, year); NRF_LOG_INFO("%d %d %d ", day, month, year);
NRF_LOG_INFO("%d %d %d ", hour, minute, second); NRF_LOG_INFO("%d %d %d ", hour, minute, second);
UpdateTime(previousSystickCounter); tm.tm_isdst = -1; // Use DST value from local time zone
xSemaphoreTake(mutex, portMAX_DELAY);
currentDateTime = std::chrono::system_clock::from_time_t(std::mktime(&tm));
UpdateTime(previousSystickCounter, true);
xSemaphoreGive(mutex);
systemTask->PushMessage(System::Messages::OnNewTime); systemTask->PushMessage(System::Messages::OnNewTime);
} }
@ -45,25 +53,34 @@ void DateTime::SetTimeZone(int8_t timezone, int8_t dst) {
dstOffset = dst; dstOffset = dst;
} }
void DateTime::UpdateTime(uint32_t systickCounter) { std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> DateTime::CurrentDateTime() {
xSemaphoreTake(mutex, portMAX_DELAY);
UpdateTime(nrf_rtc_counter_get(portNRF_RTC_REG), false);
xSemaphoreGive(mutex);
return currentDateTime;
}
void DateTime::UpdateTime(uint32_t systickCounter, bool forceUpdate) {
// Handle systick counter overflow // Handle systick counter overflow
uint32_t systickDelta = 0; uint32_t systickDelta = 0;
if (systickCounter < previousSystickCounter) { if (systickCounter < previousSystickCounter) {
systickDelta = 0xffffff - previousSystickCounter; systickDelta = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - previousSystickCounter;
systickDelta += systickCounter + 1; systickDelta += systickCounter + 1;
} else { } else {
systickDelta = systickCounter - previousSystickCounter; systickDelta = systickCounter - previousSystickCounter;
} }
/* auto correctedDelta = systickDelta / configTICK_RATE_HZ;
* 1000 ms = 1024 ticks // If a second hasn't passed, there is nothing to do
*/ // If the time has been changed, set forceUpdate to trigger internal state updates
auto correctedDelta = systickDelta / 1024; if (correctedDelta == 0 && !forceUpdate) {
auto rest = systickDelta % 1024; return;
}
auto rest = systickDelta % configTICK_RATE_HZ;
if (systickCounter >= rest) { if (systickCounter >= rest) {
previousSystickCounter = systickCounter - rest; previousSystickCounter = systickCounter - rest;
} else { } else {
previousSystickCounter = 0xffffff - (rest - systickCounter); previousSystickCounter = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - (rest - systickCounter - 1);
} }
currentDateTime += std::chrono::seconds(correctedDelta); currentDateTime += std::chrono::seconds(correctedDelta);

View file

@ -5,6 +5,8 @@
#include <ctime> #include <ctime>
#include <string> #include <string>
#include "components/settings/Settings.h" #include "components/settings/Settings.h"
#include <FreeRTOS.h>
#include <semphr.h>
namespace Pinetime { namespace Pinetime {
namespace System { namespace System {
@ -45,8 +47,6 @@ namespace Pinetime {
*/ */
void SetTimeZone(int8_t timezone, int8_t dst); void SetTimeZone(int8_t timezone, int8_t dst);
void UpdateTime(uint32_t systickCounter);
uint16_t Year() const { uint16_t Year() const {
return 1900 + localTime.tm_year; return 1900 + localTime.tm_year;
} }
@ -124,12 +124,10 @@ namespace Pinetime {
static const char* MonthShortToStringLow(Months month); static const char* MonthShortToStringLow(Months month);
static const char* DayOfWeekShortToStringLow(Days day); static const char* DayOfWeekShortToStringLow(Days day);
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime() const { std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime();
return currentDateTime;
}
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> UTCDateTime() const { std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> UTCDateTime() {
return currentDateTime - std::chrono::seconds((tzOffset + dstOffset) * 15 * 60); return CurrentDateTime() - std::chrono::seconds((tzOffset + dstOffset) * 15 * 60);
} }
std::chrono::seconds Uptime() const { std::chrono::seconds Uptime() const {
@ -141,10 +139,14 @@ namespace Pinetime {
std::string FormattedTime(); std::string FormattedTime();
private: private:
void UpdateTime(uint32_t systickCounter, bool forceUpdate);
std::tm localTime; std::tm localTime;
int8_t tzOffset = 0; int8_t tzOffset = 0;
int8_t dstOffset = 0; int8_t dstOffset = 0;
SemaphoreHandle_t mutex = nullptr;
uint32_t previousSystickCounter = 0; uint32_t previousSystickCounter = 0;
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> currentDateTime; std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> currentDateTime;
std::chrono::seconds uptime {0}; std::chrono::seconds uptime {0};

View file

@ -75,7 +75,7 @@ namespace Pinetime {
BatteryIcon batteryIcon; BatteryIcon batteryIcon;
const Controllers::DateTime& dateTimeController; Controllers::DateTime& dateTimeController;
const Controllers::Battery& batteryController; const Controllers::Battery& batteryController;
const Controllers::Ble& bleController; const Controllers::Ble& bleController;
Controllers::NotificationManager& notificationManager; Controllers::NotificationManager& notificationManager;

View file

@ -410,8 +410,6 @@ void SystemTask::Work() {
} }
monitor.Process(); monitor.Process();
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
dateTimeController.UpdateTime(systick_counter);
NoInit_BackUpTime = dateTimeController.CurrentDateTime(); NoInit_BackUpTime = dateTimeController.CurrentDateTime();
if (nrf_gpio_pin_read(PinMap::Button) == 0) { if (nrf_gpio_pin_read(PinMap::Button) == 0) {
watchdog.Reload(); watchdog.Reload();