Skip to content

Commit bd4d27f

Browse files
committed
Merge pull request #8 from GabrielNotman/master
Several Fixes and Additions
2 parents d7b62aa + 0e25863 commit bd4d27f

File tree

2 files changed

+167
-78
lines changed

2 files changed

+167
-78
lines changed

src/RTCZero.cpp

Lines changed: 162 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,31 @@
2626

2727
voidFuncPtr RTC_callBack = NULL;
2828

29-
void RTCZero::begin()
29+
RTCZero::RTCZero()
30+
{
31+
_configured = false;
32+
}
33+
34+
void RTCZero::begin(bool resetTime)
3035
{
3136
uint16_t tmp_reg = 0;
3237

3338
PM->APBAMASK.reg |= PM_APBAMASK_RTC; // turn on digital interface clock
3439
config32kOSC();
3540

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+
3654
// Setup clock GCLK2 with OSC32K divided by 32
3755
GCLK->GENDIV.reg = GCLK_GENDIV_ID(2)|GCLK_GENDIV_DIV(4);
3856
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY)
@@ -72,6 +90,15 @@ void RTCZero::begin()
7290

7391
RTCenable();
7492
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;
75102
}
76103

77104
void RTC_Handler(void)
@@ -85,16 +112,20 @@ void RTC_Handler(void)
85112

86113
void RTCZero::enableAlarm(Alarm_Match match)
87114
{
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+
}
91120
}
92121

93122
void RTCZero::disableAlarm()
94123
{
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+
}
98129
}
99130

100131
void RTCZero::attachInterrupt(voidFuncPtr callback)
@@ -121,31 +152,37 @@ void RTCZero::standbyMode()
121152

122153
uint8_t RTCZero::getSeconds()
123154
{
155+
RTCreadRequest();
124156
return RTC->MODE2.CLOCK.bit.SECOND;
125157
}
126158

127159
uint8_t RTCZero::getMinutes()
128160
{
161+
RTCreadRequest();
129162
return RTC->MODE2.CLOCK.bit.MINUTE;
130163
}
131164

132165
uint8_t RTCZero::getHours()
133166
{
167+
RTCreadRequest();
134168
return RTC->MODE2.CLOCK.bit.HOUR;
135169
}
136170

137171
uint8_t RTCZero::getDay()
138172
{
173+
RTCreadRequest();
139174
return RTC->MODE2.CLOCK.bit.DAY;
140175
}
141176

142177
uint8_t RTCZero::getMonth()
143178
{
179+
RTCreadRequest();
144180
return RTC->MODE2.CLOCK.bit.MONTH;
145181
}
146182

147183
uint8_t RTCZero::getYear()
148184
{
185+
RTCreadRequest();
149186
return RTC->MODE2.CLOCK.bit.YEAR;
150187
}
151188

@@ -185,129 +222,165 @@ uint8_t RTCZero::getAlarmYear()
185222

186223
void RTCZero::setSeconds(uint8_t seconds)
187224
{
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+
}
191230
}
192231

193232
void RTCZero::setMinutes(uint8_t minutes)
194233
{
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+
}
198239
}
199240

200241
void RTCZero::setHours(uint8_t hours)
201242
{
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+
}
205248
}
206249

207250
void RTCZero::setTime(uint8_t hours, uint8_t minutes, uint8_t seconds)
208251
{
209-
setSeconds(seconds);
210-
setMinutes(minutes);
211-
setHours(hours);
252+
if (_configured) {
253+
setSeconds(seconds);
254+
setMinutes(minutes);
255+
setHours(hours);
256+
}
212257
}
213258

214259
void RTCZero::setDay(uint8_t day)
215260
{
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+
}
219266
}
220267

221268
void RTCZero::setMonth(uint8_t month)
222269
{
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+
}
226275
}
227276

228277
void RTCZero::setYear(uint8_t year)
229278
{
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+
}
233284
}
234285

235286
void RTCZero::setDate(uint8_t day, uint8_t month, uint8_t year)
236287
{
237-
setDay(day);
238-
setMonth(month);
239-
setYear(year);
288+
if (_configured) {
289+
setDay(day);
290+
setMonth(month);
291+
setYear(year);
292+
}
240293
}
241294

242295
void RTCZero::setAlarmSeconds(uint8_t seconds)
243296
{
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+
}
247302
}
248303

249304
void RTCZero::setAlarmMinutes(uint8_t minutes)
250305
{
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+
}
254311
}
255312

256313
void RTCZero::setAlarmHours(uint8_t hours)
257314
{
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+
}
261320
}
262321

263322
void RTCZero::setAlarmTime(uint8_t hours, uint8_t minutes, uint8_t seconds)
264323
{
265-
setAlarmSeconds(seconds);
266-
setAlarmMinutes(minutes);
267-
setAlarmHours(hours);
324+
if (_configured) {
325+
setAlarmSeconds(seconds);
326+
setAlarmMinutes(minutes);
327+
setAlarmHours(hours);
328+
}
268329
}
269330

270331
void RTCZero::setAlarmDay(uint8_t day)
271332
{
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+
}
275338
}
276339

277340
void RTCZero::setAlarmMonth(uint8_t month)
278341
{
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+
}
282347
}
283348

284349
void RTCZero::setAlarmYear(uint8_t year)
285350
{
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+
}
289356
}
290357

291358
void RTCZero::setAlarmDate(uint8_t day, uint8_t month, uint8_t year)
292359
{
293-
setAlarmDay(day);
294-
setAlarmMonth(month);
295-
setAlarmYear(year);
360+
if (_configured) {
361+
setAlarmDay(day);
362+
setAlarmMonth(month);
363+
setAlarmYear(year);
364+
}
296365
}
297366

298367
uint32_t RTCZero::getEpoch()
299368
{
369+
RTCreadRequest();
370+
RTC_MODE2_CLOCK_Type clockTime;
371+
clockTime.reg = RTC->MODE2.CLOCK.reg;
372+
300373
struct tm tm;
301374

302375
tm.tm_isdst = -1;
303376
tm.tm_yday = 0;
304377
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;
311384

312385
return mktime(&tm);
313386
}
@@ -319,27 +392,31 @@ uint32_t RTCZero::getY2kEpoch()
319392

320393
void RTCZero::setEpoch(uint32_t ts)
321394
{
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+
}
325399

326-
time_t t = ts;
327-
struct tm* tmp = gmtime(&t);
400+
time_t t = ts;
401+
struct tm* tmp = gmtime(&t);
328402

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;
335409

336-
while (RTCisSyncing())
337-
;
410+
while (RTCisSyncing())
411+
;
412+
}
338413
}
339414

340415
void RTCZero::setY2kEpoch(uint32_t ts)
341416
{
342-
setEpoch(ts + EPOCH_TIME_OFF);
417+
if (_configured) {
418+
setEpoch(ts + EPOCH_TIME_OFF);
419+
}
343420
}
344421

345422
/*
@@ -357,8 +434,17 @@ void RTCZero::config32kOSC()
357434
SYSCTRL_XOSC32K_ENABLE;
358435
}
359436

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+
360446
/* Wait for sync in write operations */
361-
bool RTCZero::RTCisSyncing()
447+
inline bool RTCZero::RTCisSyncing()
362448
{
363449
return (RTC->MODE2.STATUS.bit.SYNCBUSY);
364450
}

0 commit comments

Comments
 (0)