aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authormark9064 <30447455+mark9064@users.noreply.github.com>2023-12-28 20:56:37 +0000
committerJF <JF002@users.noreply.github.com>2024-06-09 18:34:07 +0200
commita449b272f77ea43733be4b3449f6ef57e6d09a02 (patch)
tree1fadb72dbe5b37198c1fe617c8d283ae5ff46675 /src/components
parent9e406c70f95c2db93bbf84965c210ee274da1dd2 (diff)
Continuous time updates
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ble/SimpleWeatherService.cpp2
-rw-r--r--src/components/ble/SimpleWeatherService.h4
-rw-r--r--src/components/datetime/DateTimeController.cpp43
-rw-r--r--src/components/datetime/DateTimeController.h16
4 files changed, 42 insertions, 23 deletions
diff --git a/src/components/ble/SimpleWeatherService.cpp b/src/components/ble/SimpleWeatherService.cpp
index 146152f8..504cad14 100644
--- a/src/components/ble/SimpleWeatherService.cpp
+++ b/src/components/ble/SimpleWeatherService.cpp
@@ -80,7 +80,7 @@ int WeatherCallback(uint16_t /*connHandle*/, uint16_t /*attrHandle*/, struct ble
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() {
diff --git a/src/components/ble/SimpleWeatherService.h b/src/components/ble/SimpleWeatherService.h
index 4bbefcfc..03d2f6ff 100644
--- a/src/components/ble/SimpleWeatherService.h
+++ b/src/components/ble/SimpleWeatherService.h
@@ -40,7 +40,7 @@ namespace Pinetime {
class SimpleWeatherService {
public:
- explicit SimpleWeatherService(const DateTime& dateTimeController);
+ explicit SimpleWeatherService(DateTime& dateTimeController);
void Init();
@@ -140,7 +140,7 @@ namespace Pinetime {
uint16_t eventHandle {};
- const Pinetime::Controllers::DateTime& dateTimeController;
+ Pinetime::Controllers::DateTime& dateTimeController;
std::optional<CurrentWeather> currentWeather;
std::optional<Forecast> forecast;
diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp
index f0ccb5e5..39bba15f 100644
--- a/src/components/datetime/DateTimeController.cpp
+++ b/src/components/datetime/DateTimeController.cpp
@@ -1,6 +1,7 @@
#include "components/datetime/DateTimeController.h"
#include <libraries/log/nrf_log.h>
#include <systemtask/SystemTask.h>
+#include <hal/nrf_rtc.h>
using namespace Pinetime::Controllers;
@@ -12,11 +13,16 @@ namespace {
}
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) {
+ xSemaphoreTake(mutex, portMAX_DELAY);
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) {
@@ -29,13 +35,15 @@ void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
/* .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 ", 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);
}
@@ -45,25 +53,34 @@ void DateTime::SetTimeZone(int8_t timezone, int8_t 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
uint32_t systickDelta = 0;
if (systickCounter < previousSystickCounter) {
- systickDelta = 0xffffff - previousSystickCounter;
+ systickDelta = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - previousSystickCounter;
systickDelta += systickCounter + 1;
} else {
systickDelta = systickCounter - previousSystickCounter;
}
- /*
- * 1000 ms = 1024 ticks
- */
- auto correctedDelta = systickDelta / 1024;
- auto rest = systickDelta % 1024;
+ auto correctedDelta = systickDelta / configTICK_RATE_HZ;
+ // If a second hasn't passed, there is nothing to do
+ // If the time has been changed, set forceUpdate to trigger internal state updates
+ if (correctedDelta == 0 && !forceUpdate) {
+ return;
+ }
+ auto rest = systickDelta % configTICK_RATE_HZ;
if (systickCounter >= rest) {
previousSystickCounter = systickCounter - rest;
} else {
- previousSystickCounter = 0xffffff - (rest - systickCounter);
+ previousSystickCounter = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - (rest - systickCounter - 1);
}
currentDateTime += std::chrono::seconds(correctedDelta);
diff --git a/src/components/datetime/DateTimeController.h b/src/components/datetime/DateTimeController.h
index f719df7d..5a453f20 100644
--- a/src/components/datetime/DateTimeController.h
+++ b/src/components/datetime/DateTimeController.h
@@ -5,6 +5,8 @@
#include <ctime>
#include <string>
#include "components/settings/Settings.h"
+#include <FreeRTOS.h>
+#include <semphr.h>
namespace Pinetime {
namespace System {
@@ -45,8 +47,6 @@ namespace Pinetime {
*/
void SetTimeZone(int8_t timezone, int8_t dst);
- void UpdateTime(uint32_t systickCounter);
-
uint16_t Year() const {
return 1900 + localTime.tm_year;
}
@@ -124,12 +124,10 @@ namespace Pinetime {
static const char* MonthShortToStringLow(Months month);
static const char* DayOfWeekShortToStringLow(Days day);
- std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime() const {
- return currentDateTime;
- }
+ std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime();
- std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> UTCDateTime() const {
- return currentDateTime - std::chrono::seconds((tzOffset + dstOffset) * 15 * 60);
+ std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> UTCDateTime() {
+ return CurrentDateTime() - std::chrono::seconds((tzOffset + dstOffset) * 15 * 60);
}
std::chrono::seconds Uptime() const {
@@ -141,10 +139,14 @@ namespace Pinetime {
std::string FormattedTime();
private:
+ void UpdateTime(uint32_t systickCounter, bool forceUpdate);
+
std::tm localTime;
int8_t tzOffset = 0;
int8_t dstOffset = 0;
+ SemaphoreHandle_t mutex = nullptr;
+
uint32_t previousSystickCounter = 0;
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> currentDateTime;
std::chrono::seconds uptime {0};