26
26
27
27
voidFuncPtr RTC_callBack = NULL ;
28
28
29
- void RTCZero::begin ()
29
+ RTCZero::RTCZero ()
30
+ {
31
+ _configured = false ;
32
+ }
33
+
34
+ void RTCZero::begin (bool resetTime)
30
35
{
31
36
uint16_t tmp_reg = 0 ;
32
37
33
38
PM->APBAMASK .reg |= PM_APBAMASK_RTC; // turn on digital interface clock
34
39
config32kOSC ();
35
40
41
+ // If the RTC is in clock mode and the reset was
42
+ // not due to POR or BOD, preserve the clock time
43
+ // POR causes a reset anyway, BOD behaviour is?
44
+ bool validTime = false ;
45
+ RTC_MODE2_CLOCK_Type oldTime;
46
+
47
+ if ((!resetTime) && (PM->RCAUSE .reg & (PM_RCAUSE_SYST | PM_RCAUSE_WDT | PM_RCAUSE_EXT))) {
48
+ if (RTC->MODE2 .CTRL .reg & RTC_MODE2_CTRL_MODE_CLOCK) {
49
+ validTime = true ;
50
+ oldTime.reg = RTC->MODE2 .CLOCK .reg ;
51
+ }
52
+ }
53
+
36
54
// Setup clock GCLK2 with OSC32K divided by 32
37
55
GCLK->GENDIV .reg = GCLK_GENDIV_ID (2 )|GCLK_GENDIV_DIV (4 );
38
56
while (GCLK->STATUS .reg & GCLK_STATUS_SYNCBUSY)
@@ -72,6 +90,15 @@ void RTCZero::begin()
72
90
73
91
RTCenable ();
74
92
RTCresetRemove ();
93
+
94
+ // If desired and valid, restore the time value
95
+ if ((!resetTime) && (validTime)) {
96
+ RTC->MODE2 .CLOCK .reg = oldTime.reg ;
97
+ while (RTCisSyncing ())
98
+ ;
99
+ }
100
+
101
+ _configured = true ;
75
102
}
76
103
77
104
void RTC_Handler (void )
@@ -85,16 +112,20 @@ void RTC_Handler(void)
85
112
86
113
void RTCZero::enableAlarm (Alarm_Match match)
87
114
{
88
- RTC->MODE2 .Mode2Alarm [0 ].MASK .bit .SEL = match;
89
- while (RTCisSyncing ())
90
- ;
115
+ if (_configured) {
116
+ RTC->MODE2 .Mode2Alarm [0 ].MASK .bit .SEL = match;
117
+ while (RTCisSyncing ())
118
+ ;
119
+ }
91
120
}
92
121
93
122
void RTCZero::disableAlarm ()
94
123
{
95
- RTC->MODE2 .Mode2Alarm [0 ].MASK .bit .SEL = 0x00 ;
96
- while (RTCisSyncing ())
97
- ;
124
+ if (_configured) {
125
+ RTC->MODE2 .Mode2Alarm [0 ].MASK .bit .SEL = 0x00 ;
126
+ while (RTCisSyncing ())
127
+ ;
128
+ }
98
129
}
99
130
100
131
void RTCZero::attachInterrupt (voidFuncPtr callback)
@@ -121,31 +152,37 @@ void RTCZero::standbyMode()
121
152
122
153
uint8_t RTCZero::getSeconds ()
123
154
{
155
+ RTCreadRequest ();
124
156
return RTC->MODE2 .CLOCK .bit .SECOND ;
125
157
}
126
158
127
159
uint8_t RTCZero::getMinutes ()
128
160
{
161
+ RTCreadRequest ();
129
162
return RTC->MODE2 .CLOCK .bit .MINUTE ;
130
163
}
131
164
132
165
uint8_t RTCZero::getHours ()
133
166
{
167
+ RTCreadRequest ();
134
168
return RTC->MODE2 .CLOCK .bit .HOUR ;
135
169
}
136
170
137
171
uint8_t RTCZero::getDay ()
138
172
{
173
+ RTCreadRequest ();
139
174
return RTC->MODE2 .CLOCK .bit .DAY ;
140
175
}
141
176
142
177
uint8_t RTCZero::getMonth ()
143
178
{
179
+ RTCreadRequest ();
144
180
return RTC->MODE2 .CLOCK .bit .MONTH ;
145
181
}
146
182
147
183
uint8_t RTCZero::getYear ()
148
184
{
185
+ RTCreadRequest ();
149
186
return RTC->MODE2 .CLOCK .bit .YEAR ;
150
187
}
151
188
@@ -185,129 +222,165 @@ uint8_t RTCZero::getAlarmYear()
185
222
186
223
void RTCZero::setSeconds (uint8_t seconds)
187
224
{
188
- RTC->MODE2 .CLOCK .bit .SECOND = seconds;
189
- while (RTCisSyncing ())
190
- ;
225
+ if (_configured) {
226
+ RTC->MODE2 .CLOCK .bit .SECOND = seconds;
227
+ while (RTCisSyncing ())
228
+ ;
229
+ }
191
230
}
192
231
193
232
void RTCZero::setMinutes (uint8_t minutes)
194
233
{
195
- RTC->MODE2 .CLOCK .bit .MINUTE = minutes;
196
- while (RTCisSyncing ())
197
- ;
234
+ if (_configured) {
235
+ RTC->MODE2 .CLOCK .bit .MINUTE = minutes;
236
+ while (RTCisSyncing ())
237
+ ;
238
+ }
198
239
}
199
240
200
241
void RTCZero::setHours (uint8_t hours)
201
242
{
202
- RTC->MODE2 .CLOCK .bit .HOUR = hours;
203
- while (RTCisSyncing ())
204
- ;
243
+ if (_configured) {
244
+ RTC->MODE2 .CLOCK .bit .HOUR = hours;
245
+ while (RTCisSyncing ())
246
+ ;
247
+ }
205
248
}
206
249
207
250
void RTCZero::setTime (uint8_t hours, uint8_t minutes, uint8_t seconds)
208
251
{
209
- setSeconds (seconds);
210
- setMinutes (minutes);
211
- setHours (hours);
252
+ if (_configured) {
253
+ setSeconds (seconds);
254
+ setMinutes (minutes);
255
+ setHours (hours);
256
+ }
212
257
}
213
258
214
259
void RTCZero::setDay (uint8_t day)
215
260
{
216
- RTC->MODE2 .CLOCK .bit .DAY = day;
217
- while (RTCisSyncing ())
218
- ;
261
+ if (_configured) {
262
+ RTC->MODE2 .CLOCK .bit .DAY = day;
263
+ while (RTCisSyncing ())
264
+ ;
265
+ }
219
266
}
220
267
221
268
void RTCZero::setMonth (uint8_t month)
222
269
{
223
- RTC->MODE2 .CLOCK .bit .MONTH = month;
224
- while (RTCisSyncing ())
225
- ;
270
+ if (_configured) {
271
+ RTC->MODE2 .CLOCK .bit .MONTH = month;
272
+ while (RTCisSyncing ())
273
+ ;
274
+ }
226
275
}
227
276
228
277
void RTCZero::setYear (uint8_t year)
229
278
{
230
- RTC->MODE2 .CLOCK .bit .YEAR = year;
231
- while (RTCisSyncing ())
232
- ;
279
+ if (_configured) {
280
+ RTC->MODE2 .CLOCK .bit .YEAR = year;
281
+ while (RTCisSyncing ())
282
+ ;
283
+ }
233
284
}
234
285
235
286
void RTCZero::setDate (uint8_t day, uint8_t month, uint8_t year)
236
287
{
237
- setDay (day);
238
- setMonth (month);
239
- setYear (year);
288
+ if (_configured) {
289
+ setDay (day);
290
+ setMonth (month);
291
+ setYear (year);
292
+ }
240
293
}
241
294
242
295
void RTCZero::setAlarmSeconds (uint8_t seconds)
243
296
{
244
- RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .SECOND = seconds;
245
- while (RTCisSyncing ())
246
- ;
297
+ if (_configured) {
298
+ RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .SECOND = seconds;
299
+ while (RTCisSyncing ())
300
+ ;
301
+ }
247
302
}
248
303
249
304
void RTCZero::setAlarmMinutes (uint8_t minutes)
250
305
{
251
- RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .MINUTE = minutes;
252
- while (RTCisSyncing ())
253
- ;
306
+ if (_configured) {
307
+ RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .MINUTE = minutes;
308
+ while (RTCisSyncing ())
309
+ ;
310
+ }
254
311
}
255
312
256
313
void RTCZero::setAlarmHours (uint8_t hours)
257
314
{
258
- RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .HOUR = hours;
259
- while (RTCisSyncing ())
260
- ;
315
+ if (_configured) {
316
+ RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .HOUR = hours;
317
+ while (RTCisSyncing ())
318
+ ;
319
+ }
261
320
}
262
321
263
322
void RTCZero::setAlarmTime (uint8_t hours, uint8_t minutes, uint8_t seconds)
264
323
{
265
- setAlarmSeconds (seconds);
266
- setAlarmMinutes (minutes);
267
- setAlarmHours (hours);
324
+ if (_configured) {
325
+ setAlarmSeconds (seconds);
326
+ setAlarmMinutes (minutes);
327
+ setAlarmHours (hours);
328
+ }
268
329
}
269
330
270
331
void RTCZero::setAlarmDay (uint8_t day)
271
332
{
272
- RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .DAY = day;
273
- while (RTCisSyncing ())
274
- ;
333
+ if (_configured) {
334
+ RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .DAY = day;
335
+ while (RTCisSyncing ())
336
+ ;
337
+ }
275
338
}
276
339
277
340
void RTCZero::setAlarmMonth (uint8_t month)
278
341
{
279
- RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .MONTH = month;
280
- while (RTCisSyncing ())
281
- ;
342
+ if (_configured) {
343
+ RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .MONTH = month;
344
+ while (RTCisSyncing ())
345
+ ;
346
+ }
282
347
}
283
348
284
349
void RTCZero::setAlarmYear (uint8_t year)
285
350
{
286
- RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .YEAR = year;
287
- while (RTCisSyncing ())
288
- ;
351
+ if (_configured) {
352
+ RTC->MODE2 .Mode2Alarm [0 ].ALARM .bit .YEAR = year;
353
+ while (RTCisSyncing ())
354
+ ;
355
+ }
289
356
}
290
357
291
358
void RTCZero::setAlarmDate (uint8_t day, uint8_t month, uint8_t year)
292
359
{
293
- setAlarmDay (day);
294
- setAlarmMonth (month);
295
- setAlarmYear (year);
360
+ if (_configured) {
361
+ setAlarmDay (day);
362
+ setAlarmMonth (month);
363
+ setAlarmYear (year);
364
+ }
296
365
}
297
366
298
367
uint32_t RTCZero::getEpoch ()
299
368
{
369
+ RTCreadRequest ();
370
+ RTC_MODE2_CLOCK_Type clockTime;
371
+ clockTime.reg = RTC->MODE2 .CLOCK .reg ;
372
+
300
373
struct tm tm;
301
374
302
375
tm.tm_isdst = -1 ;
303
376
tm.tm_yday = 0 ;
304
377
tm.tm_wday = 0 ;
305
- tm.tm_year = getYear () + EPOCH_TIME_YEAR_OFF;
306
- tm.tm_mon = getMonth () - 1 ;
307
- tm.tm_mday = getDay () ;
308
- tm.tm_hour = getHours () ;
309
- tm.tm_min = getMinutes () ;
310
- tm.tm_sec = getSeconds () ;
378
+ tm.tm_year = clockTime. bit . YEAR + EPOCH_TIME_YEAR_OFF;
379
+ tm.tm_mon = clockTime. bit . MONTH - 1 ;
380
+ tm.tm_mday = clockTime. bit . DAY ;
381
+ tm.tm_hour = clockTime. bit . HOUR ;
382
+ tm.tm_min = clockTime. bit . MINUTE ;
383
+ tm.tm_sec = clockTime. bit . SECOND ;
311
384
312
385
return mktime (&tm);
313
386
}
@@ -319,27 +392,31 @@ uint32_t RTCZero::getY2kEpoch()
319
392
320
393
void RTCZero::setEpoch (uint32_t ts)
321
394
{
322
- if (ts < EPOCH_TIME_OFF) {
323
- ts = EPOCH_TIME_OFF;
324
- }
395
+ if (_configured) {
396
+ if (ts < EPOCH_TIME_OFF) {
397
+ ts = EPOCH_TIME_OFF;
398
+ }
325
399
326
- time_t t = ts;
327
- struct tm * tmp = gmtime (&t);
400
+ time_t t = ts;
401
+ struct tm * tmp = gmtime (&t);
328
402
329
- RTC->MODE2 .CLOCK .bit .YEAR = tmp->tm_year - EPOCH_TIME_YEAR_OFF;
330
- RTC->MODE2 .CLOCK .bit .MONTH = tmp->tm_mon + 1 ;
331
- RTC->MODE2 .CLOCK .bit .DAY = tmp->tm_mday ;
332
- RTC->MODE2 .CLOCK .bit .HOUR = tmp->tm_hour ;
333
- RTC->MODE2 .CLOCK .bit .MINUTE = tmp->tm_min ;
334
- RTC->MODE2 .CLOCK .bit .SECOND = tmp->tm_sec ;
403
+ RTC->MODE2 .CLOCK .bit .YEAR = tmp->tm_year - EPOCH_TIME_YEAR_OFF;
404
+ RTC->MODE2 .CLOCK .bit .MONTH = tmp->tm_mon + 1 ;
405
+ RTC->MODE2 .CLOCK .bit .DAY = tmp->tm_mday ;
406
+ RTC->MODE2 .CLOCK .bit .HOUR = tmp->tm_hour ;
407
+ RTC->MODE2 .CLOCK .bit .MINUTE = tmp->tm_min ;
408
+ RTC->MODE2 .CLOCK .bit .SECOND = tmp->tm_sec ;
335
409
336
- while (RTCisSyncing ())
337
- ;
410
+ while (RTCisSyncing ())
411
+ ;
412
+ }
338
413
}
339
414
340
415
void RTCZero::setY2kEpoch (uint32_t ts)
341
416
{
342
- setEpoch (ts + EPOCH_TIME_OFF);
417
+ if (_configured) {
418
+ setEpoch (ts + EPOCH_TIME_OFF);
419
+ }
343
420
}
344
421
345
422
/*
@@ -357,8 +434,17 @@ void RTCZero::config32kOSC()
357
434
SYSCTRL_XOSC32K_ENABLE;
358
435
}
359
436
437
+ /* Synchronise the CLOCK register for reading*/
438
+ inline void RTCZero::RTCreadRequest () {
439
+ if (_configured) {
440
+ RTC->MODE2 .READREQ .reg = RTC_READREQ_RREQ;
441
+ while (RTCisSyncing ())
442
+ ;
443
+ }
444
+ }
445
+
360
446
/* Wait for sync in write operations */
361
- bool RTCZero::RTCisSyncing ()
447
+ inline bool RTCZero::RTCisSyncing ()
362
448
{
363
449
return (RTC->MODE2 .STATUS .bit .SYNCBUSY );
364
450
}
0 commit comments