Skip to content

Commit 7b3215d

Browse files
committed
Add epoch get/set methods.
Also added a one second delay in the begin() method. This is because the clock reading appears to be off until the first tick has elapsed.
1 parent 9590892 commit 7b3215d

File tree

2 files changed

+96
-10
lines changed

2 files changed

+96
-10
lines changed

src/RTCZero.cpp

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919

2020
#include "RTCZero.h"
2121

22+
#define EPOCH_TIME_OFF 946684800 // This is 2000-jan-01 00:00:00 in epoch time
23+
#define SECONDS_PER_DAY 86400L
24+
25+
static const uint8_t daysInMonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
26+
2227
static bool __time24 = false;
2328

2429
voidFuncPtr RTC_callBack = NULL;
@@ -74,6 +79,9 @@ void RTCZero::begin(bool timeRep)
7479

7580
RTCenable();
7681
RTCresetRemove();
82+
83+
// The clock does not seem to sync until the first tick
84+
delay(1000);
7785
}
7886

7987
void RTC_Handler(void)
@@ -298,6 +306,75 @@ void RTCZero::setAlarmDate(uint8_t day, uint8_t month, uint8_t year)
298306
setAlarmYear(year);
299307
}
300308

309+
uint32_t RTCZero::getEpoch()
310+
{
311+
return getY2kEpoch() + EPOCH_TIME_OFF;
312+
}
313+
314+
uint32_t RTCZero::getY2kEpoch()
315+
{
316+
uint16_t days = RTC->MODE2.CLOCK.bit.DAY;
317+
uint8_t months = RTC->MODE2.CLOCK.bit.MONTH;
318+
uint16_t years = RTC->MODE2.CLOCK.bit.YEAR;
319+
320+
for (uint8_t i = 1; i < months; ++i) {
321+
days += daysInMonth[i - 1];
322+
}
323+
324+
if ((months > 2) && (years % 4 == 0)) {
325+
++days;
326+
}
327+
328+
days += 365 * years + (years + 3) / 4 - 1;
329+
330+
return ((days * 24 + RTC->MODE2.CLOCK.bit.HOUR) * 60 +
331+
RTC->MODE2.CLOCK.bit.MINUTE) * 60 + RTC->MODE2.CLOCK.bit.SECOND;
332+
}
333+
334+
void RTCZero::setEpoch(uint32_t ts)
335+
{
336+
setY2kEpoch(ts - EPOCH_TIME_OFF);
337+
}
338+
339+
void RTCZero::setY2kEpoch(uint32_t ts)
340+
{
341+
RTC->MODE2.CLOCK.bit.SECOND = ts % 60;
342+
ts /= 60;
343+
RTC->MODE2.CLOCK.bit.MINUTE = ts % 60;
344+
ts /= 60;
345+
RTC->MODE2.CLOCK.bit.HOUR = ts % 24;
346+
347+
uint16_t days = ts / 24;
348+
uint8_t months;
349+
uint8_t years;
350+
351+
uint8_t leap;
352+
353+
// Calculate years
354+
for (years = 0; ; ++years) {
355+
leap = years % 4 == 0;
356+
if (days < 365 + leap)
357+
break;
358+
days -= 365 + leap;
359+
}
360+
361+
// Calculate months
362+
for (months = 1; ; ++months) {
363+
uint8_t daysPerMonth = daysInMonth[months - 1];
364+
if (leap && months == 2)
365+
++daysPerMonth;
366+
if (days < daysPerMonth)
367+
break;
368+
days -= daysPerMonth;
369+
}
370+
371+
RTC->MODE2.CLOCK.bit.YEAR = years;
372+
RTC->MODE2.CLOCK.bit.MONTH = months;
373+
RTC->MODE2.CLOCK.bit.DAY = days + 1;
374+
while (RTCisSyncing())
375+
;
376+
}
377+
301378
/*
302379
* Private Utility Functions
303380
*/
@@ -345,5 +422,4 @@ void RTCZero::RTCresetRemove()
345422
RTC->MODE2.CTRL.reg &= ~RTC_MODE2_CTRL_SWRST; // software reset remove
346423
while (RTCisSyncing())
347424
;
348-
}
349-
425+
}

src/RTCZero.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1818
*/
1919

20-
#pragma once
20+
#ifndef RTC_ZERO_H
21+
#define RTC_ZERO_H
2122

2223
#define H24 1
2324
#define H12 0
@@ -31,13 +32,13 @@ class RTCZero {
3132

3233
enum Alarm_Match: uint8_t // Should we have this enum or just use the identifiers from /component/rtc.h ?
3334
{
34-
MATCH_OFF = RTC_MODE2_MASK_SEL_OFF_Val,
35-
MATCH_SS = RTC_MODE2_MASK_SEL_SS_Val,
36-
MATCH_MMSS = RTC_MODE2_MASK_SEL_MMSS_Val,
37-
MATCH_HHMMSS = RTC_MODE2_MASK_SEL_HHMMSS_Val,
38-
MATCH_DHHMMSS = RTC_MODE2_MASK_SEL_DDHHMMSS_Val,
39-
MATCH_MMDDHHMMSS = RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val,
40-
MATCH_YYMMDDHHMMSS = RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val
35+
MATCH_OFF = RTC_MODE2_MASK_SEL_OFF_Val, // Never
36+
MATCH_SS = RTC_MODE2_MASK_SEL_SS_Val, // Every Minute
37+
MATCH_MMSS = RTC_MODE2_MASK_SEL_MMSS_Val, // Every Hour
38+
MATCH_HHMMSS = RTC_MODE2_MASK_SEL_HHMMSS_Val, // Every Day
39+
MATCH_DHHMMSS = RTC_MODE2_MASK_SEL_DDHHMMSS_Val, // Every Month
40+
MATCH_MMDDHHMMSS = RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val, // Every Year
41+
MATCH_YYMMDDHHMMSS = RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val // Once, on a specific date and a specific time
4142
};
4243

4344
RTCZero() {};
@@ -89,6 +90,13 @@ class RTCZero {
8990
void setAlarmYear(uint8_t year);
9091
void setAlarmDate(uint8_t day, uint8_t month, uint8_t year);
9192

93+
/* Epoch Functions */
94+
95+
uint32_t getEpoch();
96+
uint32_t getY2kEpoch();
97+
void setEpoch(uint32_t ts);
98+
void setY2kEpoch(uint32_t ts);
99+
92100
private:
93101
void config32kOSC(void);
94102
bool RTCisSyncing(void);
@@ -97,3 +105,5 @@ class RTCZero {
97105
void RTCreset();
98106
void RTCresetRemove();
99107
};
108+
109+
#endif // RTC_ZERO_H

0 commit comments

Comments
 (0)