fsl_rtc.c 22 KB

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