1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_rtc.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14 #define SECONDS_IN_A_DAY (86400U)
15 #define SECONDS_IN_A_HOUR (3600U)
16 #define SECONDS_IN_A_MINUTE (60U)
17 #define DAYS_IN_A_YEAR (365U)
18 #define YEAR_RANGE_START (1970U)
19 #define YEAR_RANGE_END (2099U)
20
21 /*******************************************************************************
22 * Prototypes
23 ******************************************************************************/
24 /*!
25 * @brief Checks whether the date and time passed in is valid
26 *
27 * @param datetime Pointer to structure where the date and time details are stored
28 *
29 * @return Returns false if the date & time details are out of range; true if in range
30 */
31 static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime);
32
33 /*!
34 * @brief Converts time data from datetime to seconds
35 *
36 * @param datetime Pointer to datetime structure where the date and time details are stored
37 *
38 * @return The result of the conversion in seconds
39 */
40 static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime);
41
42 /*!
43 * @brief Converts time data from seconds to a datetime structure
44 *
45 * @param seconds Seconds value that needs to be converted to datetime format
46 * @param datetime Pointer to the datetime structure where the result of the conversion is stored
47 */
48 static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime);
49
50 /*******************************************************************************
51 * Code
52 ******************************************************************************/
RTC_CheckDatetimeFormat(const rtc_datetime_t * datetime)53 static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime)
54 {
55 assert(datetime);
56
57 /* Table of days in a month for a non leap year. First entry in the table is not used,
58 * valid months start from 1
59 */
60 uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};
61
62 /* Check year, month, hour, minute, seconds */
63 if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) ||
64 (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U))
65 {
66 /* If not correct then error*/
67 return false;
68 }
69
70 /* Adjust the days in February for a leap year */
71 if ((((datetime->year & 3U) == 0) && (datetime->year % 100 != 0)) || (datetime->year % 400 == 0))
72 {
73 daysPerMonth[2] = 29U;
74 }
75
76 /* Check the validity of the day */
77 if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U))
78 {
79 return false;
80 }
81
82 return true;
83 }
84
RTC_ConvertDatetimeToSeconds(const rtc_datetime_t * datetime)85 static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime)
86 {
87 assert(datetime);
88
89 /* Number of days from begin of the non Leap-year*/
90 /* Number of days from begin of the non Leap-year*/
91 uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U};
92 uint32_t seconds;
93
94 /* Compute number of days from 1970 till given year*/
95 seconds = (datetime->year - 1970U) * DAYS_IN_A_YEAR;
96 /* Add leap year days */
97 seconds += ((datetime->year / 4) - (1970U / 4));
98 /* Add number of days till given month*/
99 seconds += monthDays[datetime->month];
100 /* Add days in given month. We subtract the current day as it is
101 * represented in the hours, minutes and seconds field*/
102 seconds += (datetime->day - 1);
103 /* For leap year if month less than or equal to Febraury, decrement day counter*/
104 if ((!(datetime->year & 3U)) && (datetime->month <= 2U))
105 {
106 seconds--;
107 }
108
109 seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) +
110 (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second;
111
112 return seconds;
113 }
114
RTC_ConvertSecondsToDatetime(uint32_t seconds,rtc_datetime_t * datetime)115 static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime)
116 {
117 assert(datetime);
118
119 uint32_t x;
120 uint32_t secondsRemaining, days;
121 uint16_t daysInYear;
122 /* Table of days in a month for a non leap year. First entry in the table is not used,
123 * valid months start from 1
124 */
125 uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};
126
127 /* Start with the seconds value that is passed in to be converted to date time format */
128 secondsRemaining = seconds;
129
130 /* Calcuate the number of days, we add 1 for the current day which is represented in the
131 * hours and seconds field
132 */
133 days = secondsRemaining / SECONDS_IN_A_DAY + 1;
134
135 /* Update seconds left*/
136 secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY;
137
138 /* Calculate the datetime hour, minute and second fields */
139 datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR;
140 secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR;
141 datetime->minute = secondsRemaining / 60U;
142 datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE;
143
144 /* Calculate year */
145 daysInYear = DAYS_IN_A_YEAR;
146 datetime->year = YEAR_RANGE_START;
147 while (days > daysInYear)
148 {
149 /* Decrease day count by a year and increment year by 1 */
150 days -= daysInYear;
151 datetime->year++;
152
153 /* Adjust the number of days for a leap year */
154 if (datetime->year & 3U)
155 {
156 daysInYear = DAYS_IN_A_YEAR;
157 }
158 else
159 {
160 daysInYear = DAYS_IN_A_YEAR + 1;
161 }
162 }
163
164 /* Adjust the days in February for a leap year */
165 if (!(datetime->year & 3U))
166 {
167 daysPerMonth[2] = 29U;
168 }
169
170 for (x = 1U; x <= 12U; x++)
171 {
172 if (days <= daysPerMonth[x])
173 {
174 datetime->month = x;
175 break;
176 }
177 else
178 {
179 days -= daysPerMonth[x];
180 }
181 }
182
183 datetime->day = days;
184 }
185
RTC_Init(RTC_Type * base,const rtc_config_t * config)186 void RTC_Init(RTC_Type *base, const rtc_config_t *config)
187 {
188 assert(config);
189
190 uint32_t reg;
191
192 #if defined(RTC_CLOCKS)
193 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
194 CLOCK_EnableClock(kCLOCK_Rtc0);
195 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
196 #endif /* RTC_CLOCKS */
197
198 /* Issue a software reset if timer is invalid */
199 if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag)
200 {
201 RTC_Reset(RTC);
202 }
203
204 reg = base->CR;
205 /* Setup the update mode and supervisor access mode */
206 reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK);
207 reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess);
208 #if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION
209 /* Setup the wakeup pin select */
210 reg &= ~(RTC_CR_WPS_MASK);
211 reg |= RTC_CR_WPS(config->wakeupSelect);
212 #endif /* FSL_FEATURE_RTC_HAS_WAKEUP_PIN */
213 base->CR = reg;
214
215 /* Configure the RTC time compensation register */
216 base->TCR = (RTC_TCR_CIR(config->compensationInterval) | RTC_TCR_TCR(config->compensationTime));
217
218 #if defined(FSL_FEATURE_RTC_HAS_TSIC) && FSL_FEATURE_RTC_HAS_TSIC
219 /* Configure RTC timer seconds interrupt to be generated once per second */
220 base->IER &= ~(RTC_IER_TSIC_MASK | RTC_IER_TSIE_MASK);
221 #endif
222 }
223
RTC_GetDefaultConfig(rtc_config_t * config)224 void RTC_GetDefaultConfig(rtc_config_t *config)
225 {
226 assert(config);
227
228 /* Wakeup pin will assert if the RTC interrupt asserts or if the wakeup pin is turned on */
229 config->wakeupSelect = false;
230 /* Registers cannot be written when locked */
231 config->updateMode = false;
232 /* Non-supervisor mode write accesses are not supported and will generate a bus error */
233 config->supervisorAccess = false;
234 /* Compensation interval used by the crystal compensation logic */
235 config->compensationInterval = 0;
236 /* Compensation time used by the crystal compensation logic */
237 config->compensationTime = 0;
238 }
239
RTC_SetDatetime(RTC_Type * base,const rtc_datetime_t * datetime)240 status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime)
241 {
242 assert(datetime);
243
244 /* Return error if the time provided is not valid */
245 if (!(RTC_CheckDatetimeFormat(datetime)))
246 {
247 return kStatus_InvalidArgument;
248 }
249
250 /* Set time in seconds */
251 base->TSR = RTC_ConvertDatetimeToSeconds(datetime);
252
253 return kStatus_Success;
254 }
255
RTC_GetDatetime(RTC_Type * base,rtc_datetime_t * datetime)256 void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime)
257 {
258 assert(datetime);
259
260 uint32_t seconds = 0;
261
262 seconds = base->TSR;
263 RTC_ConvertSecondsToDatetime(seconds, datetime);
264 }
265
RTC_SetAlarm(RTC_Type * base,const rtc_datetime_t * alarmTime)266 status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime)
267 {
268 assert(alarmTime);
269
270 uint32_t alarmSeconds = 0;
271 uint32_t currSeconds = 0;
272
273 /* Return error if the alarm time provided is not valid */
274 if (!(RTC_CheckDatetimeFormat(alarmTime)))
275 {
276 return kStatus_InvalidArgument;
277 }
278
279 alarmSeconds = RTC_ConvertDatetimeToSeconds(alarmTime);
280
281 /* Get the current time */
282 currSeconds = base->TSR;
283
284 /* Return error if the alarm time has passed */
285 if (alarmSeconds < currSeconds)
286 {
287 return kStatus_Fail;
288 }
289
290 /* Set alarm in seconds*/
291 base->TAR = alarmSeconds;
292
293 return kStatus_Success;
294 }
295
RTC_GetAlarm(RTC_Type * base,rtc_datetime_t * datetime)296 void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime)
297 {
298 assert(datetime);
299
300 uint32_t alarmSeconds = 0;
301
302 /* Get alarm in seconds */
303 alarmSeconds = base->TAR;
304
305 RTC_ConvertSecondsToDatetime(alarmSeconds, datetime);
306 }
307
RTC_EnableInterrupts(RTC_Type * base,uint32_t mask)308 void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask)
309 {
310 uint32_t tmp32 = 0U;
311
312 /* RTC_IER */
313 if (kRTC_TimeInvalidInterruptEnable == (kRTC_TimeInvalidInterruptEnable & mask))
314 {
315 tmp32 |= RTC_IER_TIIE_MASK;
316 }
317 if (kRTC_TimeOverflowInterruptEnable == (kRTC_TimeOverflowInterruptEnable & mask))
318 {
319 tmp32 |= RTC_IER_TOIE_MASK;
320 }
321 if (kRTC_AlarmInterruptEnable == (kRTC_AlarmInterruptEnable & mask))
322 {
323 tmp32 |= RTC_IER_TAIE_MASK;
324 }
325 if (kRTC_SecondsInterruptEnable == (kRTC_SecondsInterruptEnable & mask))
326 {
327 tmp32 |= RTC_IER_TSIE_MASK;
328 }
329 #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
330 if (kRTC_MonotonicOverflowInterruptEnable == (kRTC_MonotonicOverflowInterruptEnable & mask))
331 {
332 tmp32 |= RTC_IER_MOIE_MASK;
333 }
334 #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
335 base->IER |= tmp32;
336
337 #if (defined(FSL_FEATURE_RTC_HAS_TIR) && FSL_FEATURE_RTC_HAS_TIR)
338 tmp32 = 0U;
339
340 /* RTC_TIR */
341 if (kRTC_TestModeInterruptEnable == (kRTC_TestModeInterruptEnable & mask))
342 {
343 tmp32 |= RTC_TIR_TMIE_MASK;
344 }
345 if (kRTC_FlashSecurityInterruptEnable == (kRTC_FlashSecurityInterruptEnable & mask))
346 {
347 tmp32 |= RTC_TIR_FSIE_MASK;
348 }
349 #if (defined(FSL_FEATURE_RTC_HAS_TIR_TPIE) && FSL_FEATURE_RTC_HAS_TIR_TPIE)
350 if (kRTC_TamperPinInterruptEnable == (kRTC_TamperPinInterruptEnable & mask))
351 {
352 tmp32 |= RTC_TIR_TPIE_MASK;
353 }
354 #endif /* FSL_FEATURE_RTC_HAS_TIR_TPIE */
355 #if (defined(FSL_FEATURE_RTC_HAS_TIR_SIE) && FSL_FEATURE_RTC_HAS_TIR_SIE)
356 if (kRTC_SecurityModuleInterruptEnable == (kRTC_SecurityModuleInterruptEnable & mask))
357 {
358 tmp32 |= RTC_TIR_SIE_MASK;
359 }
360 #endif /* FSL_FEATURE_RTC_HAS_TIR_SIE */
361 #if (defined(FSL_FEATURE_RTC_HAS_TIR_LCIE) && FSL_FEATURE_RTC_HAS_TIR_LCIE)
362 if (kRTC_LossOfClockInterruptEnable == (kRTC_LossOfClockInterruptEnable & mask))
363 {
364 tmp32 |= RTC_TIR_LCIE_MASK;
365 }
366 #endif /* FSL_FEATURE_RTC_HAS_TIR_LCIE */
367 base->TIR |= tmp32;
368 #endif /* FSL_FEATURE_RTC_HAS_TIR */
369 }
370
RTC_DisableInterrupts(RTC_Type * base,uint32_t mask)371 void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask)
372 {
373 uint32_t tmp32 = 0U;
374
375 /* RTC_IER */
376 if (kRTC_TimeInvalidInterruptEnable == (kRTC_TimeInvalidInterruptEnable & mask))
377 {
378 tmp32 |= RTC_IER_TIIE_MASK;
379 }
380 if (kRTC_TimeOverflowInterruptEnable == (kRTC_TimeOverflowInterruptEnable & mask))
381 {
382 tmp32 |= RTC_IER_TOIE_MASK;
383 }
384 if (kRTC_AlarmInterruptEnable == (kRTC_AlarmInterruptEnable & mask))
385 {
386 tmp32 |= RTC_IER_TAIE_MASK;
387 }
388 if (kRTC_SecondsInterruptEnable == (kRTC_SecondsInterruptEnable & mask))
389 {
390 tmp32 |= RTC_IER_TSIE_MASK;
391 }
392 #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
393 if (kRTC_MonotonicOverflowInterruptEnable == (kRTC_MonotonicOverflowInterruptEnable & mask))
394 {
395 tmp32 |= RTC_IER_MOIE_MASK;
396 }
397 #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
398 base->IER &= (uint32_t)(~tmp32);
399
400 #if (defined(FSL_FEATURE_RTC_HAS_TIR) && FSL_FEATURE_RTC_HAS_TIR)
401 tmp32 = 0U;
402
403 /* RTC_TIR */
404 if (kRTC_TestModeInterruptEnable == (kRTC_TestModeInterruptEnable & mask))
405 {
406 tmp32 |= RTC_TIR_TMIE_MASK;
407 }
408 if (kRTC_FlashSecurityInterruptEnable == (kRTC_FlashSecurityInterruptEnable & mask))
409 {
410 tmp32 |= RTC_TIR_FSIE_MASK;
411 }
412 #if (defined(FSL_FEATURE_RTC_HAS_TIR_TPIE) && FSL_FEATURE_RTC_HAS_TIR_TPIE)
413 if (kRTC_TamperPinInterruptEnable == (kRTC_TamperPinInterruptEnable & mask))
414 {
415 tmp32 |= RTC_TIR_TPIE_MASK;
416 }
417 #endif /* FSL_FEATURE_RTC_HAS_TIR_TPIE */
418 #if (defined(FSL_FEATURE_RTC_HAS_TIR_SIE) && FSL_FEATURE_RTC_HAS_TIR_SIE)
419 if (kRTC_SecurityModuleInterruptEnable == (kRTC_SecurityModuleInterruptEnable & mask))
420 {
421 tmp32 |= RTC_TIR_SIE_MASK;
422 }
423 #endif /* FSL_FEATURE_RTC_HAS_TIR_SIE */
424 #if (defined(FSL_FEATURE_RTC_HAS_TIR_LCIE) && FSL_FEATURE_RTC_HAS_TIR_LCIE)
425 if (kRTC_LossOfClockInterruptEnable == (kRTC_LossOfClockInterruptEnable & mask))
426 {
427 tmp32 |= RTC_TIR_LCIE_MASK;
428 }
429 #endif /* FSL_FEATURE_RTC_HAS_TIR_LCIE */
430 base->TIR &= (uint32_t)(~tmp32);
431 #endif /* FSL_FEATURE_RTC_HAS_TIR */
432 }
433
RTC_GetEnabledInterrupts(RTC_Type * base)434 uint32_t RTC_GetEnabledInterrupts(RTC_Type *base)
435 {
436 uint32_t tmp32 = 0U;
437
438 /* RTC_IER */
439 if (RTC_IER_TIIE_MASK == (RTC_IER_TIIE_MASK & base->IER))
440 {
441 tmp32 |= kRTC_TimeInvalidInterruptEnable;
442 }
443 if (RTC_IER_TOIE_MASK == (RTC_IER_TOIE_MASK & base->IER))
444 {
445 tmp32 |= kRTC_TimeOverflowInterruptEnable;
446 }
447 if (RTC_IER_TAIE_MASK == (RTC_IER_TAIE_MASK & base->IER))
448 {
449 tmp32 |= kRTC_AlarmInterruptEnable;
450 }
451 if (RTC_IER_TSIE_MASK == (RTC_IER_TSIE_MASK & base->IER))
452 {
453 tmp32 |= kRTC_SecondsInterruptEnable;
454 }
455 #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
456 if (RTC_IER_MOIE_MASK == (RTC_IER_MOIE_MASK & base->IER))
457 {
458 tmp32 |= kRTC_MonotonicOverflowInterruptEnable;
459 }
460 #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
461
462 #if (defined(FSL_FEATURE_RTC_HAS_TIR) && FSL_FEATURE_RTC_HAS_TIR)
463 /* RTC_TIR */
464 if (RTC_TIR_TMIE_MASK == (RTC_TIR_TMIE_MASK & base->TIR))
465 {
466 tmp32 |= kRTC_TestModeInterruptEnable;
467 }
468 if (RTC_TIR_FSIE_MASK == (RTC_TIR_FSIE_MASK & base->TIR))
469 {
470 tmp32 |= kRTC_FlashSecurityInterruptEnable;
471 }
472 #if (defined(FSL_FEATURE_RTC_HAS_TIR_TPIE) && FSL_FEATURE_RTC_HAS_TIR_TPIE)
473 if (RTC_TIR_TPIE_MASK == (RTC_TIR_TPIE_MASK & base->TIR))
474 {
475 tmp32 |= kRTC_TamperPinInterruptEnable;
476 }
477 #endif /* FSL_FEATURE_RTC_HAS_TIR_TPIE */
478 #if (defined(FSL_FEATURE_RTC_HAS_TIR_SIE) && FSL_FEATURE_RTC_HAS_TIR_SIE)
479 if (RTC_TIR_SIE_MASK == (RTC_TIR_SIE_MASK & base->TIR))
480 {
481 tmp32 |= kRTC_SecurityModuleInterruptEnable;
482 }
483 #endif /* FSL_FEATURE_RTC_HAS_TIR_SIE */
484 #if (defined(FSL_FEATURE_RTC_HAS_TIR_LCIE) && FSL_FEATURE_RTC_HAS_TIR_LCIE)
485 if (RTC_TIR_LCIE_MASK == (RTC_TIR_LCIE_MASK & base->TIR))
486 {
487 tmp32 |= kRTC_LossOfClockInterruptEnable;
488 }
489 #endif /* FSL_FEATURE_RTC_HAS_TIR_LCIE */
490 #endif /* FSL_FEATURE_RTC_HAS_TIR */
491
492 return tmp32;
493 }
494
RTC_GetStatusFlags(RTC_Type * base)495 uint32_t RTC_GetStatusFlags(RTC_Type *base)
496 {
497 uint32_t tmp32 = 0U;
498
499 /* RTC_SR */
500 if (RTC_SR_TIF_MASK == (RTC_SR_TIF_MASK & base->SR))
501 {
502 tmp32 |= kRTC_TimeInvalidFlag;
503 }
504 if (RTC_SR_TOF_MASK == (RTC_SR_TOF_MASK & base->SR))
505 {
506 tmp32 |= kRTC_TimeOverflowFlag;
507 }
508 if (RTC_SR_TAF_MASK == (RTC_SR_TAF_MASK & base->SR))
509 {
510 tmp32 |= kRTC_AlarmFlag;
511 }
512 #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
513 if (RTC_SR_MOF_MASK == (RTC_SR_MOF_MASK & base->SR))
514 {
515 tmp32 |= kRTC_MonotonicOverflowFlag;
516 }
517 #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
518 #if (defined(FSL_FEATURE_RTC_HAS_SR_TIDF) && FSL_FEATURE_RTC_HAS_SR_TIDF)
519 if (RTC_SR_TIDF_MASK == (RTC_SR_TIDF_MASK & base->SR))
520 {
521 tmp32 |= kRTC_TamperInterruptDetectFlag;
522 }
523 #endif /* FSL_FEATURE_RTC_HAS_SR_TIDF */
524
525 #if (defined(FSL_FEATURE_RTC_HAS_TDR) && FSL_FEATURE_RTC_HAS_TDR)
526 /* RTC_TDR */
527 if (RTC_TDR_TMF_MASK == (RTC_TDR_TMF_MASK & base->TDR))
528 {
529 tmp32 |= kRTC_TestModeFlag;
530 }
531 if (RTC_TDR_FSF_MASK == (RTC_TDR_FSF_MASK & base->TDR))
532 {
533 tmp32 |= kRTC_FlashSecurityFlag;
534 }
535 #if (defined(FSL_FEATURE_RTC_HAS_TDR_TPF) && FSL_FEATURE_RTC_HAS_TDR_TPF)
536 if (RTC_TDR_TPF_MASK == (RTC_TDR_TPF_MASK & base->TDR))
537 {
538 tmp32 |= kRTC_TamperPinFlag;
539 }
540 #endif /* FSL_FEATURE_RTC_HAS_TDR_TPF */
541 #if (defined(FSL_FEATURE_RTC_HAS_TDR_STF) && FSL_FEATURE_RTC_HAS_TDR_STF)
542 if (RTC_TDR_STF_MASK == (RTC_TDR_STF_MASK & base->TDR))
543 {
544 tmp32 |= kRTC_SecurityTamperFlag;
545 }
546 #endif /* FSL_FEATURE_RTC_HAS_TDR_STF */
547 #if (defined(FSL_FEATURE_RTC_HAS_TDR_LCTF) && FSL_FEATURE_RTC_HAS_TDR_LCTF)
548 if (RTC_TDR_LCTF_MASK == (RTC_TDR_LCTF_MASK & base->TDR))
549 {
550 tmp32 |= kRTC_LossOfClockTamperFlag;
551 }
552 #endif /* FSL_FEATURE_RTC_HAS_TDR_LCTF */
553 #endif /* FSL_FEATURE_RTC_HAS_TDR */
554
555 return tmp32;
556 }
557
RTC_ClearStatusFlags(RTC_Type * base,uint32_t mask)558 void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask)
559 {
560 /* The alarm flag is cleared by writing to the TAR register */
561 if (mask & kRTC_AlarmFlag)
562 {
563 base->TAR = 0U;
564 }
565
566 /* The timer overflow flag is cleared by initializing the TSR register.
567 * The time counter should be disabled for this write to be successful
568 */
569 if (mask & kRTC_TimeOverflowFlag)
570 {
571 base->TSR = 1U;
572 }
573
574 /* The timer overflow flag is cleared by initializing the TSR register.
575 * The time counter should be disabled for this write to be successful
576 */
577 if (mask & kRTC_TimeInvalidFlag)
578 {
579 base->TSR = 1U;
580 }
581
582 #if (defined(FSL_FEATURE_RTC_HAS_TDR) && FSL_FEATURE_RTC_HAS_TDR)
583 /* To clear, write logic one to this flag after exiting from all test modes */
584 if (kRTC_TestModeFlag == (kRTC_TestModeFlag & mask))
585 {
586 base->TDR = RTC_TDR_TMF_MASK;
587 }
588 /* To clear, write logic one to this flag after flash security is enabled */
589 if (kRTC_FlashSecurityFlag == (kRTC_FlashSecurityFlag & mask))
590 {
591 base->TDR = RTC_TDR_FSF_MASK;
592 }
593 #if (defined(FSL_FEATURE_RTC_HAS_TDR_TPF) && FSL_FEATURE_RTC_HAS_TDR_TPF)
594 /* To clear, write logic one to the corresponding flag after that tamper pin negates */
595 if (kRTC_TamperPinFlag == (kRTC_TamperPinFlag & mask))
596 {
597 base->TDR = RTC_TDR_TPF_MASK;
598 }
599 #endif /* FSL_FEATURE_RTC_HAS_TDR_TPF */
600 #if (defined(FSL_FEATURE_RTC_HAS_TDR_STF) && FSL_FEATURE_RTC_HAS_TDR_STF)
601 /* To clear, write logic one to this flag after security module has negated its tamper detect */
602 if (kRTC_SecurityTamperFlag == (kRTC_SecurityTamperFlag & mask))
603 {
604 base->TDR = RTC_TDR_STF_MASK;
605 }
606 #endif /* FSL_FEATURE_RTC_HAS_TDR_STF */
607 #if (defined(FSL_FEATURE_RTC_HAS_TDR_LCTF) && FSL_FEATURE_RTC_HAS_TDR_LCTF)
608 /* To clear, write logic one to this flag after loss of clock negates */
609 if (kRTC_LossOfClockTamperFlag == (kRTC_LossOfClockTamperFlag & mask))
610 {
611 base->TDR = RTC_TDR_LCTF_MASK;
612 }
613 #endif /* FSL_FEATURE_RTC_HAS_TDR_LCTF */
614 #endif /* FSL_FEATURE_RTC_HAS_TDR */
615 }
616
617 #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
618
RTC_GetMonotonicCounter(RTC_Type * base,uint64_t * counter)619 void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter)
620 {
621 assert(counter);
622
623 *counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR));
624 }
625
RTC_SetMonotonicCounter(RTC_Type * base,uint64_t counter)626 void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter)
627 {
628 /* Prepare to initialize the register with the new value written */
629 base->MER &= ~RTC_MER_MCE_MASK;
630
631 base->MCHR = (uint32_t)((counter) >> 32);
632 base->MCLR = (uint32_t)(counter);
633 }
634
RTC_IncrementMonotonicCounter(RTC_Type * base)635 status_t RTC_IncrementMonotonicCounter(RTC_Type *base)
636 {
637 if (base->SR & (RTC_SR_MOF_MASK | RTC_SR_TIF_MASK))
638 {
639 return kStatus_Fail;
640 }
641
642 /* Prepare to switch to increment mode */
643 base->MER |= RTC_MER_MCE_MASK;
644 /* Write anything so the counter increments*/
645 base->MCLR = 1U;
646
647 return kStatus_Success;
648 }
649
650 #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
651