Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continuous time update - Alternative implementation to #2041 #2054

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 49 additions & 15 deletions src/components/datetime/DateTimeController.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "components/datetime/DateTimeController.h"
#include <libraries/log/nrf_log.h>
#include <systemtask/SystemTask.h>
#include <nrf_rtc.h>

using namespace Pinetime::Controllers;

Expand All @@ -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
xSemaphoreGive(mutex);
}

void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
Expand All @@ -35,7 +41,9 @@ void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
NRF_LOG_INFO("%d %d %d ", day, month, year);
NRF_LOG_INFO("%d %d %d ", hour, minute, second);

xSemaphoreTake(mutex, portMAX_DELAY);
UpdateTime(previousSystickCounter);
xSemaphoreGive(mutex);

systemTask->PushMessage(System::Messages::OnNewTime);
}
Expand All @@ -45,29 +53,23 @@ void DateTime::SetTimeZone(int8_t timezone, int8_t dst) {
dstOffset = dst;
}

void DateTime::UpdateTime(uint32_t systickCounter) {
uint32_t DateTime::GetTickFromPreviousSystickCounter(uint32_t systickCounter) const {
// 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;
}
return systickDelta;
}

/*
* 1000 ms = 1024 ticks
*/
auto correctedDelta = systickDelta / 1024;
auto rest = systickDelta % 1024;
if (systickCounter >= rest) {
previousSystickCounter = systickCounter - rest;
} else {
previousSystickCounter = 0xffffff - (rest - systickCounter);
}

currentDateTime += std::chrono::seconds(correctedDelta);
uptime += std::chrono::seconds(correctedDelta);
void DateTime::UpdateTime() {
xSemaphoreTake(mutex, portMAX_DELAY);
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
UpdateTime(systick_counter);
xSemaphoreGive(mutex);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably extend the critical section to include updating localTime


std::time_t currentTime = std::chrono::system_clock::to_time_t(currentDateTime);
localTime = *std::localtime(&currentTime);
Expand Down Expand Up @@ -103,6 +105,23 @@ void DateTime::UpdateTime(uint32_t systickCounter) {
}
}

void DateTime::UpdateTime(uint32_t systickCounter) {
auto systickDelta = GetTickFromPreviousSystickCounter(systickCounter);
auto correctedDelta = systickDelta / configTICK_RATE_HZ;

/*
* 1000 ms = 1024 ticks
*/
auto rest = systickDelta % configTICK_RATE_HZ;
if (systickCounter >= rest) {
previousSystickCounter = systickCounter - rest;
} else {
previousSystickCounter = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - (rest - systickCounter);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
previousSystickCounter = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - (rest - systickCounter);
previousSystickCounter = static_cast<uint32_t>(portNRF_RTC_MAXTICKS) - (rest - systickCounter - 1);

previousSystickCounter should semantically be systickCounter - rest
Suppose rest = 1, sysTickCounter = 0
previousSystickCounter should be portNRF_RTC_MAXTICKS but instead is portNRF_RTC_MAXTICKS - 1

}
currentDateTime += std::chrono::seconds(correctedDelta);
uptime += std::chrono::seconds(correctedDelta);
}

const char* DateTime::MonthShortToString() const {
return MonthsString[static_cast<uint8_t>(Month())];
}
Expand Down Expand Up @@ -146,3 +165,18 @@ std::string DateTime::FormattedTime() {
}
return std::string(buff);
}

std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> DateTime::CurrentDateTime() const {
xSemaphoreTake(mutex, portMAX_DELAY);
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
auto correctedDelta = GetTickFromPreviousSystickCounter(systick_counter) / configTICK_RATE_HZ;
auto result = currentDateTime + std::chrono::seconds(correctedDelta);
;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting typo?

Suggested change
;

xSemaphoreGive(mutex);

return result;
}

std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> DateTime::UTCDateTime() const {
return CurrentDateTime() - std::chrono::seconds((tzOffset + dstOffset) * 15 * 60);
}
16 changes: 9 additions & 7 deletions src/components/datetime/DateTimeController.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <chrono>
#include <ctime>
#include <string>
#include <FreeRTOS.h>
#include <semphr.h>
#include "components/settings/Settings.h"

namespace Pinetime {
Expand Down Expand Up @@ -45,7 +47,7 @@ namespace Pinetime {
*/
void SetTimeZone(int8_t timezone, int8_t dst);

void UpdateTime(uint32_t systickCounter);
void UpdateTime();

uint16_t Year() const {
return 1900 + localTime.tm_year;
Expand Down Expand Up @@ -124,13 +126,9 @@ 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() const;

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() const;

std::chrono::seconds Uptime() const {
return uptime;
Expand All @@ -141,6 +139,9 @@ namespace Pinetime {
std::string FormattedTime();

private:
uint32_t GetTickFromPreviousSystickCounter(uint32_t systickCounter) const;
void UpdateTime(uint32_t systickCounter);

std::tm localTime;
int8_t tzOffset = 0;
int8_t dstOffset = 0;
Expand All @@ -154,6 +155,7 @@ namespace Pinetime {
bool isHalfHourAlreadyNotified = true;
System::SystemTask* systemTask = nullptr;
Controllers::Settings& settingsController;
SemaphoreHandle_t mutex = nullptr;
};
}
}
4 changes: 1 addition & 3 deletions src/systemtask/SystemTask.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "systemtask/SystemTask.h"
#include <hal/nrf_rtc.h>
#include <libraries/gpiote/app_gpiote.h>
#include <libraries/log/nrf_log.h>
#include "BootloaderVersion.h"
Expand Down Expand Up @@ -410,8 +409,7 @@ void SystemTask::Work() {
}

monitor.Process();
uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);
dateTimeController.UpdateTime(systick_counter);
dateTimeController.UpdateTime();
NoInit_BackUpTime = dateTimeController.CurrentDateTime();
if (nrf_gpio_pin_read(PinMap::Button) == 0) {
watchdog.Reload();
Expand Down
Loading