Skip to content

Commit e3c3999

Browse files
tshcherbanfpistm
andcommitted
feat: avoid usage of gmtime and mktime
Replace calls within programRtcWakeUp() function with a custom timeshift calculation to reduce flash size. Signed-off-by: tshcherban <[email protected]> Co-Authored-By: Frederic Pillon <[email protected]>
1 parent ef798e3 commit e3c3999

File tree

2 files changed

+102
-15
lines changed

2 files changed

+102
-15
lines changed

src/STM32LowPower.cpp

Lines changed: 100 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ void STM32LowPower::enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *
181181
*/
182182
void STM32LowPower::programRtcWakeUp(uint32_t ms, LP_Mode lp_mode)
183183
{
184-
uint32_t epoc;
185-
uint32_t sec;
186184
STM32RTC &rtc = STM32RTC::getInstance();
187185
STM32RTC::Source_Clock clkSrc = rtc.getClockSource();
188186

@@ -207,21 +205,108 @@ void STM32LowPower::programRtcWakeUp(uint32_t ms, LP_Mode lp_mode)
207205
}
208206
rtc.configForLowPower(clkSrc);
209207

208+
setAlarmTime(ms, rtc);
209+
}
210+
211+
static bool isLeapYear(uint8_t year2k)
212+
{
213+
int year = year2k + 2000;
214+
215+
// if year not divisible by 4 - not a leap year
216+
// else if year divisible by 4 and not by 100 - a leap year
217+
// else if year divisible by 400 - a leap year
218+
return (year % 4 != 0) ? false : (year % 100 != 0) ? true : year % 400 == 0;
219+
}
220+
221+
void STM32LowPower::setAlarmTime(uint32_t ms, STM32RTC &rtc)
222+
{
210223
if (ms != 0) {
211-
// Convert millisecond to second
212-
sec = ms / 1000;
213-
214-
uint32_t epoc_ms;
215-
ms = ms % 1000;
216-
epoc = rtc.getEpoch(&epoc_ms);
217-
218-
//Update epoch_ms - might need to add a second to epoch
219-
epoc_ms += ms;
220-
if (epoc_ms >= 1000) {
221-
sec ++;
222-
epoc_ms -= 1000;
224+
uint16_t subSecondsToAdd = ms % 1000;
225+
226+
ms = ms / 1000;
227+
uint8_t daysToAdd = ms / 86400;
228+
uint8_t hoursToAdd = (ms - daysToAdd * 86400) / 3600;
229+
uint8_t minutesToAdd = (ms - daysToAdd * 86400 - hoursToAdd * 3600) / 60;
230+
uint8_t secondsToAdd = (ms - daysToAdd * 86400 - hoursToAdd * 3600 - minutesToAdd * 60);
231+
232+
uint8_t hrCurrent, minCurrent, secCurrent;
233+
uint32_t subSecondsCurrent;
234+
STM32RTC::AM_PM period;
235+
rtc.getTime(&hrCurrent, &minCurrent, &secCurrent, &subSecondsCurrent, &period);
236+
237+
uint8_t weekDay, currentDay, currentMonth, currentYear;
238+
rtc.getDate(&weekDay, &currentDay, &currentMonth, &currentYear);
239+
240+
uint32_t ss = subSecondsCurrent + subSecondsToAdd;
241+
if (ss >= 1000) {
242+
ss -= 1000;
243+
secondsToAdd++;
244+
}
245+
246+
if (secondsToAdd >= 60) {
247+
secondsToAdd = 0;
248+
minutesToAdd++;
223249
}
250+
uint8_t s = secCurrent + secondsToAdd;
251+
if (s >= 60) {
252+
s -= 60;
253+
minutesToAdd++;
254+
}
255+
256+
if (minutesToAdd >= 60) {
257+
minutesToAdd -= 60;
258+
hoursToAdd++;
259+
}
260+
uint8_t m = minCurrent + minutesToAdd;
261+
if (m >= 60) {
262+
m -= 60;
263+
hoursToAdd++;
264+
}
265+
266+
if (hoursToAdd >= 24) {
267+
hoursToAdd -= 24;
268+
daysToAdd++;
269+
}
270+
uint8_t h = hrCurrent + hoursToAdd;
271+
if (rtc._format == STM32RTC::Hour_Format::HOUR_12) {
272+
if (h >= 24) {
273+
h -= 24;
274+
daysToAdd++;
275+
} else if (h >= 12) {
276+
if (period == STM32RTC::AM_PM::AM) {
277+
period = STM32RTC::AM_PM::PM;
278+
} else {
279+
period = STM32RTC::AM_PM::AM;
280+
daysToAdd++;
281+
}
282+
283+
if (h > 12) {
284+
h -= 12;
285+
}
286+
}
287+
} else if (h >= 24) {
288+
h -= 24;
289+
daysToAdd++;
290+
}
291+
292+
// numbers of days in each month (february is calculated based on leap year)
293+
static uint8_t daysInMonths[] = {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
294+
uint8_t endDay;
295+
if (currentMonth == 2) {
296+
endDay = isLeapYear(currentYear) ? 29 : 28;
297+
} else {
298+
endDay = daysInMonths[currentMonth];
299+
}
300+
301+
uint8_t d = currentDay + daysToAdd;
302+
if (d > endDay) {
303+
d -= endDay;
304+
}
305+
306+
// month-year overflow isn't handled because its not supported by RTC's alarm
224307

225-
rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_DHHMMSS, epoc_ms);
308+
rtc.setAlarmTime(h, m, s, ss, period);
309+
rtc.setAlarmDay(d);
310+
rtc.enableAlarm(STM32RTC::Alarm_Match::MATCH_DHHMMSS);
226311
}
227312
}

src/STM32LowPower.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ class STM32LowPower {
9797
serial_t *_serial; // Serial for wakeup from deep sleep
9898
bool _rtc_wakeup; // Is RTC wakeup?
9999
void programRtcWakeUp(uint32_t ms, LP_Mode lp_mode);
100+
void setAlarmTime(uint32_t ms, STM32RTC &rtc);
101+
100102
};
101103

102104
extern STM32LowPower LowPower;

0 commit comments

Comments
 (0)