19
19
20
20
#include " RTCZero.h"
21
21
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
+
22
27
static bool __time24 = false ;
23
28
24
29
voidFuncPtr RTC_callBack = NULL ;
@@ -74,6 +79,9 @@ void RTCZero::begin(bool timeRep)
74
79
75
80
RTCenable ();
76
81
RTCresetRemove ();
82
+
83
+ // The clock does not seem to sync until the first tick
84
+ delay (1000 );
77
85
}
78
86
79
87
void RTC_Handler (void )
@@ -298,6 +306,75 @@ void RTCZero::setAlarmDate(uint8_t day, uint8_t month, uint8_t year)
298
306
setAlarmYear (year);
299
307
}
300
308
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
+
301
378
/*
302
379
* Private Utility Functions
303
380
*/
@@ -345,5 +422,4 @@ void RTCZero::RTCresetRemove()
345
422
RTC->MODE2 .CTRL .reg &= ~RTC_MODE2_CTRL_SWRST; // software reset remove
346
423
while (RTCisSyncing ())
347
424
;
348
- }
349
-
425
+ }
0 commit comments