Skip to content

Commit 1910b9c

Browse files
committed
added support for GMT timezones
1 parent 60fd091 commit 1910b9c

File tree

3 files changed

+44
-17
lines changed

3 files changed

+44
-17
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The main screen takes the longest to draw. This is caused by the amount of pixel
1616
* support to change the RTC calibration values in the settings
1717
* support for setting the time
1818
* 60 seconds screen timeout
19+
* Support for timezones
1920

2021
### Images
2122
Photos<br>
@@ -38,7 +39,6 @@ More pictures can be found [here](./img/)
3839
* add support for more than 32 profiles (needs a rework if more profiles are required. The profiles are copied to ram and there is not enough for more at the moment. If we leave them in flash we can store a lot more)
3940
* support for reading the profile locations from the linkerscript instead of hardcoded
4041
* rework the calibration and time settings screens
41-
* setting to set timezone for epoch time calculation
4242

4343
### Compiling
4444
TOTP uses [klib](https://github.com/itzandroidtab/klib). This repo can be cloned in the klib project folder. See [build.yml](./.github/workflows/build.yml) for more info on compiling this project.

storage.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ namespace storage {
115115

116116
// write in 1024 byte chunks
117117
for (uint32_t i = 0; i < ((max_entries * sizeof(entry)) / 1024); i++) {
118-
std::span<const uint8_t> p = {
118+
const std::span<const uint8_t> p = {
119119
(reinterpret_cast<const uint8_t*>(entries.data()) + i * 1024), 1024
120120
};
121121

ui/time.hpp

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ namespace menu {
1212
using screen_base = screen<FrameBuffer>;
1313

1414
enum class steps: uint8_t {
15-
year = 0,
15+
timezone = 0,
16+
year,
1617
month,
1718
day,
1819
hour,
@@ -27,6 +28,7 @@ namespace menu {
2728

2829
// rtc data
2930
struct dateinfo {
31+
int8_t timezone;
3032
uint16_t year;
3133
uint8_t month;
3234
uint8_t day;
@@ -44,6 +46,9 @@ namespace menu {
4446
void next(int32_t value) {
4547
// store the value
4648
switch (current) {
49+
case steps::timezone:
50+
date.timezone = static_cast<int8_t>(value);
51+
break;
4752
case steps::year:
4853
date.year = static_cast<uint16_t>(value);
4954
break;
@@ -62,12 +67,18 @@ namespace menu {
6267
case steps::second:
6368
date.second = static_cast<uint8_t>(value);
6469

70+
// store the timezone in the rtc registers
71+
RtcPeriph::port->GPREG4 = (
72+
(RtcPeriph::port->GPREG4 & (~0x1f)) |
73+
static_cast<uint8_t>(date.timezone + 12)
74+
);
75+
6576
// we are done. Update the RTC time
6677
Rtc::set(klib::io::rtc::datetime_to_epoch(
6778
date.year, date.month,
6879
date.day, date.hour,
6980
date.minute, date.second
70-
));
81+
) - klib::time::s(date.timezone * (60 * 60)));
7182

7283
// go back one screen to the setings menu
7384
screen_base::buffer.back();
@@ -85,37 +96,53 @@ namespace menu {
8596
}
8697

8798
void cancel() {
88-
// reset and go back to the previous screen
89-
current = steps::year;
99+
if (current == steps::timezone) {
100+
// go back to the menu
101+
screen_base::buffer.back();
102+
103+
return;
104+
}
90105

91-
// go back
92-
screen_base::buffer.back();
106+
// go back one screen
107+
current = static_cast<steps>(static_cast<uint32_t>(current) - 1);
93108
}
94109

95110
void change_screen(const steps current) {
111+
// get the current time with the timezone compensation
112+
const auto t = klib::io::rtc::epoch_to_datetime(
113+
Rtc::get() + klib::time::s(date.timezone * (60 * 60))
114+
);
115+
96116
// get what state we are in
97117
switch (current) {
118+
case steps::timezone:
119+
popup.configure(
120+
"GMT", (RtcPeriph::port->GPREG4 & 0x1f) - 12,
121+
-12, 14, [&](int32_t value){next(value);},
122+
[&](){cancel();}
123+
);
124+
break;
98125
case steps::year:
99126
popup.configure(
100-
"Year", RtcPeriph::port->YEAR,
127+
"Year", t.year,
101128
2020, 2099, [&](int32_t value){next(value);},
102129
[&](){cancel();}
103130
);
104131
break;
105132
case steps::month:
106133
popup.configure(
107-
"Month", RtcPeriph::port->MONTH,
134+
"Month", t.month,
108135
1, 12, [&](int32_t value){next(value);},
109136
[&](){cancel();}
110137
);
111138
break;
112139
case steps::day:
113140
{
114141
// check for a leap year
115-
const bool is_leap_year_month = (date.year & 0b11) == 0 && (date.month == 1);
142+
const bool is_leap_year_month = (date.year & 0b11) == 0 && (date.month == 2);
116143

117144
popup.configure(
118-
"Day", RtcPeriph::port->DOM,
145+
"Day", t.day,
119146
0, klib::io::rtc::month_days[date.month] + is_leap_year_month,
120147
[&](int32_t value){next(value);},
121148
[&](){cancel();}
@@ -124,21 +151,21 @@ namespace menu {
124151
break;
125152
case steps::hour:
126153
popup.configure(
127-
"Hour", RtcPeriph::port->HRS,
154+
"Hour", t.hours,
128155
0, 23, [&](int32_t value){next(value);},
129156
[&](){cancel();}
130157
);
131158
break;
132159
case steps::minute:
133160
popup.configure(
134-
"Minute", RtcPeriph::port->MIN,
161+
"Minute", t.minutes,
135162
0, 59, [&](int32_t value){next(value);},
136163
[&](){cancel();}
137164
);
138165
break;
139166
case steps::second:
140167
popup.configure(
141-
"Second", RtcPeriph::port->SEC,
168+
"Second", t.seconds,
142169
0, 59, [&](int32_t value){next(value);},
143170
[&](){cancel();}
144171
);
@@ -150,12 +177,12 @@ namespace menu {
150177

151178
public:
152179
time(numeric_popup<FrameBuffer>& popup):
153-
current(steps::year), date{}, popup(popup)
180+
current(steps::timezone), date{}, popup(popup)
154181
{}
155182

156183
virtual void main(const klib::time::us delta, const input::buttons& buttons) override {
157184
// check for the first entry
158-
if (current == steps::year) {
185+
if (current == steps::timezone) {
159186
// show the first screen
160187
change_screen(current);
161188
}

0 commit comments

Comments
 (0)