fsl_rtc.c 22 KB

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