1
1
#include " components/datetime/DateTimeController.h"
2
2
#include < libraries/log/nrf_log.h>
3
3
#include < systemtask/SystemTask.h>
4
+ #include < nrf_rtc.h>
4
5
5
6
using namespace Pinetime ::Controllers;
6
7
@@ -12,11 +13,16 @@ namespace {
12
13
}
13
14
14
15
DateTime::DateTime (Controllers::Settings& settingsController) : settingsController {settingsController} {
16
+ mutex = xSemaphoreCreateMutex ();
17
+ ASSERT (mutex != nullptr );
18
+ xSemaphoreGive (mutex);
15
19
}
16
20
17
21
void DateTime::SetCurrentTime (std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t) {
22
+ xSemaphoreTake (mutex, portMAX_DELAY);
18
23
this ->currentDateTime = t;
19
24
UpdateTime (previousSystickCounter); // Update internal state without updating the time
25
+ xSemaphoreGive (mutex);
20
26
}
21
27
22
28
void DateTime::SetTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
@@ -35,7 +41,9 @@ void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
35
41
NRF_LOG_INFO (" %d %d %d " , day, month, year);
36
42
NRF_LOG_INFO (" %d %d %d " , hour, minute, second);
37
43
44
+ xSemaphoreTake (mutex, portMAX_DELAY);
38
45
UpdateTime (previousSystickCounter);
46
+ xSemaphoreGive (mutex);
39
47
40
48
systemTask->PushMessage (System::Messages::OnNewTime);
41
49
}
@@ -45,29 +53,23 @@ void DateTime::SetTimeZone(int8_t timezone, int8_t dst) {
45
53
dstOffset = dst;
46
54
}
47
55
48
- void DateTime::UpdateTime (uint32_t systickCounter) {
56
+ uint32_t DateTime::GetTickFromPreviousSystickCounter (uint32_t systickCounter) const {
49
57
// Handle systick counter overflow
50
58
uint32_t systickDelta = 0 ;
51
59
if (systickCounter < previousSystickCounter) {
52
- systickDelta = 0xffffff - previousSystickCounter;
60
+ systickDelta = static_cast < uint32_t >(portNRF_RTC_MAXTICKS) - previousSystickCounter;
53
61
systickDelta += systickCounter + 1 ;
54
62
} else {
55
63
systickDelta = systickCounter - previousSystickCounter;
56
64
}
65
+ return systickDelta;
66
+ }
57
67
58
- /*
59
- * 1000 ms = 1024 ticks
60
- */
61
- auto correctedDelta = systickDelta / 1024 ;
62
- auto rest = systickDelta % 1024 ;
63
- if (systickCounter >= rest) {
64
- previousSystickCounter = systickCounter - rest;
65
- } else {
66
- previousSystickCounter = 0xffffff - (rest - systickCounter);
67
- }
68
-
69
- currentDateTime += std::chrono::seconds (correctedDelta);
70
- uptime += std::chrono::seconds (correctedDelta);
68
+ void DateTime::UpdateTime () {
69
+ xSemaphoreTake (mutex, portMAX_DELAY);
70
+ uint32_t systick_counter = nrf_rtc_counter_get (portNRF_RTC_REG);
71
+ UpdateTime (systick_counter);
72
+ xSemaphoreGive (mutex);
71
73
72
74
std::time_t currentTime = std::chrono::system_clock::to_time_t (currentDateTime);
73
75
localTime = *std::localtime (¤tTime);
@@ -103,6 +105,23 @@ void DateTime::UpdateTime(uint32_t systickCounter) {
103
105
}
104
106
}
105
107
108
+ void DateTime::UpdateTime (uint32_t systickCounter) {
109
+ auto systickDelta = GetTickFromPreviousSystickCounter (systickCounter);
110
+ auto correctedDelta = systickDelta / configTICK_RATE_HZ;
111
+
112
+ /*
113
+ * 1000 ms = 1024 ticks
114
+ */
115
+ auto rest = systickDelta % configTICK_RATE_HZ;
116
+ if (systickCounter >= rest) {
117
+ previousSystickCounter = systickCounter - rest;
118
+ } else {
119
+ previousSystickCounter = static_cast <uint32_t >(portNRF_RTC_MAXTICKS) - (rest - systickCounter);
120
+ }
121
+ currentDateTime += std::chrono::seconds (correctedDelta);
122
+ uptime += std::chrono::seconds (correctedDelta);
123
+ }
124
+
106
125
const char * DateTime::MonthShortToString () const {
107
126
return MonthsString[static_cast <uint8_t >(Month ())];
108
127
}
@@ -146,3 +165,18 @@ std::string DateTime::FormattedTime() {
146
165
}
147
166
return std::string (buff);
148
167
}
168
+
169
+ std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> DateTime::CurrentDateTime () const {
170
+ xSemaphoreTake (mutex, portMAX_DELAY);
171
+ uint32_t systick_counter = nrf_rtc_counter_get (portNRF_RTC_REG);
172
+ auto correctedDelta = GetTickFromPreviousSystickCounter (systick_counter) / configTICK_RATE_HZ;
173
+ auto result = currentDateTime + std::chrono::seconds (correctedDelta);
174
+ ;
175
+ xSemaphoreGive (mutex);
176
+
177
+ return result;
178
+ }
179
+
180
+ std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> DateTime::UTCDateTime () const {
181
+ return CurrentDateTime () - std::chrono::seconds ((tzOffset + dstOffset) * 15 * 60 );
182
+ }
0 commit comments