1 /**************************************************************************//**
2  * @file     rtc.c
3  * @version  V3.00
4  * @brief    Real Time Clock(RTC) driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 #include "NuMicro.h"
10 
11 
12 /** @cond HIDDEN_SYMBOLS */
13 /*---------------------------------------------------------------------------------------------------------*/
14 /* Global file scope (static) variables                                                                    */
15 /*---------------------------------------------------------------------------------------------------------*/
16 static volatile uint32_t g_u32hiYear, g_u32loYear, g_u32hiMonth, g_u32loMonth, g_u32hiDay, g_u32loDay;
17 static volatile uint32_t g_u32hiHour, g_u32loHour, g_u32hiMin, g_u32loMin, g_u32hiSec, g_u32loSec;
18 
19 /** @endcond HIDDEN_SYMBOLS */
20 
21 
22 /** @addtogroup Standard_Driver Standard Driver
23   @{
24 */
25 
26 /** @addtogroup RTC_Driver RTC Driver
27   @{
28 */
29 
30 /** @addtogroup RTC_EXPORTED_FUNCTIONS RTC Exported Functions
31   @{
32 */
33 
34 /**
35   * @brief      Initialize RTC module and start counting
36   *
37   * @param[in]  sPt     Specify the time property and current date and time. It includes:           \n
38   *                     u32Year: Year value, range between 2000 ~ 2099.                             \n
39   *                     u32Month: Month value, range between 1 ~ 12.                                \n
40   *                     u32Day: Day value, range between 1 ~ 31.                                    \n
41   *                     u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
42   *                                                     RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
43   *                                                     RTC_SATURDAY]                               \n
44   *                     u32Hour: Hour value, range between 0 ~ 23.                                  \n
45   *                     u32Minute: Minute value, range between 0 ~ 59.                              \n
46   *                     u32Second: Second value, range between 0 ~ 59.                              \n
47   *                     u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24]                                 \n
48   *                     u8AmPm: [RTC_AM / RTC_PM]                                                   \n
49   *
50   * @return     None
51   *
52   * @details    This function is used to: \n
53   *                 1. Write initial key to let RTC start count.  \n
54   *                 2. Input parameter indicates start date/time. \n
55   *                 3. User has to make sure that parameters of RTC date/time are reasonable. \n
56   *                 4. Enable frequency dynamic compensation function. \n
57   * @note       Null pointer for using default starting date/time.
58   */
RTC_Open(S_RTC_TIME_DATA_T * sPt)59 void RTC_Open(S_RTC_TIME_DATA_T *sPt)
60 {
61     RTC->INIT = RTC_INIT_KEY;
62 
63     if(RTC->INIT != RTC_INIT_ACTIVE_Msk)
64     {
65         RTC->INIT = RTC_INIT_KEY;
66         while(RTC->INIT != RTC_INIT_ACTIVE_Msk) {}
67     }
68 
69     if(sPt != 0)
70     {
71         /* Enable frequency dynamic compensation function */
72         RTC->CLKFMT |= RTC_CLKFMT_DCOMPEN_Msk;
73 
74         /* Set RTC date and time */
75         RTC_SetDateAndTime(sPt);
76     }
77 }
78 
79 /**
80   * @brief      Disable RTC Clock
81   *
82   * @param      None
83   *
84   * @return     None
85   *
86   * @details    This API will disable RTC peripheral clock.
87   */
RTC_Close(void)88 void RTC_Close(void)
89 {
90     if((__PC()&NS_OFFSET) != NS_OFFSET)
91     {
92         /* Only available in Secure code */
93         CLK->APBCLK0 &= ~CLK_APBCLK0_RTCCKEN_Msk;
94     }
95 }
96 
97 /**
98   * @brief      Set 32K Frequency Compensation Data
99   *
100   * @param[in]  i32FrequencyX10000  Specify the RTC clock X10000, ex: 327736512 means 32773.6512.
101   *
102   * @return     None
103   *
104   * @details    This API is used to compensate the 32 kHz frequency by current LXT frequency for RTC application.
105   */
RTC_32KCalibration(int32_t i32FrequencyX10000)106 void RTC_32KCalibration(int32_t i32FrequencyX10000)
107 {
108     int32_t i32RegInt, i32RegFra;
109 
110     /* Compute integer and fraction for RTC FCR register */
111     i32RegInt = (i32FrequencyX10000 / 10000) - RTC_FCR_REFERENCE;
112     i32RegFra = ((((i32FrequencyX10000 % 10000)) * 64) + 5000) / 10000;
113 
114     if(i32RegFra >= 0x40)
115     {
116         i32RegFra = 0x0;
117         i32RegInt++;
118     }
119 
120     /* Judge Integer part is reasonable */
121     if((i32RegInt >= 0) && (i32RegInt <= 31))
122     {
123         while((RTC->FREQADJ & RTC_FREQADJ_FCRBUSY_Msk) == RTC_FREQADJ_FCRBUSY_Msk) {}
124         RTC->FREQADJ = (uint32_t)((i32RegInt << 8) | i32RegFra);
125         while((RTC->FREQADJ & RTC_FREQADJ_FCRBUSY_Msk) == RTC_FREQADJ_FCRBUSY_Msk) {}
126     }
127 }
128 
129 /**
130   * @brief      Get Current RTC Date and Time
131   *
132   * @param[out] sPt     The returned pointer is specified the current RTC value. It includes: \n
133   *                     u32Year: Year value                                                   \n
134   *                     u32Month: Month value                                                 \n
135   *                     u32Day: Day value                                                     \n
136   *                     u32DayOfWeek: Day of week                                             \n
137   *                     u32Hour: Hour value                                                   \n
138   *                     u32Minute: Minute value                                               \n
139   *                     u32Second: Second value                                               \n
140   *                     u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24]                           \n
141   *                     u8AmPm: [RTC_AM / RTC_PM]                                             \n
142   *
143   * @return     None
144   *
145   * @details    This API is used to get the current RTC date and time value.
146   */
RTC_GetDateAndTime(S_RTC_TIME_DATA_T * sPt)147 void RTC_GetDateAndTime(S_RTC_TIME_DATA_T *sPt)
148 {
149     uint32_t u32Tmp;
150 
151     sPt->u32TimeScale = RTC->CLKFMT & RTC_CLKFMT_24HEN_Msk;     /* 12/24-hour */
152     sPt->u32DayOfWeek = RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk; /* Day of the week */
153 
154     /* Get [Date digit] data */
155     g_u32hiYear  = (RTC->CAL & RTC_CAL_TENYEAR_Msk) >> RTC_CAL_TENYEAR_Pos;
156     g_u32loYear  = (RTC->CAL & RTC_CAL_YEAR_Msk) >> RTC_CAL_YEAR_Pos;
157     g_u32hiMonth = (RTC->CAL & RTC_CAL_TENMON_Msk) >> RTC_CAL_TENMON_Pos;
158     g_u32loMonth = (RTC->CAL & RTC_CAL_MON_Msk) >> RTC_CAL_MON_Pos;
159     g_u32hiDay   = (RTC->CAL & RTC_CAL_TENDAY_Msk) >> RTC_CAL_TENDAY_Pos;
160     g_u32loDay   = (RTC->CAL & RTC_CAL_DAY_Msk) >> RTC_CAL_DAY_Pos;
161 
162     /* Get [Time digit] data */
163     g_u32hiHour = (RTC->TIME & RTC_TIME_TENHR_Msk) >> RTC_TIME_TENHR_Pos;
164     g_u32loHour = (RTC->TIME & RTC_TIME_HR_Msk) >> RTC_TIME_HR_Pos;
165     g_u32hiMin  = (RTC->TIME & RTC_TIME_TENMIN_Msk) >> RTC_TIME_TENMIN_Pos;
166     g_u32loMin  = (RTC->TIME & RTC_TIME_MIN_Msk) >> RTC_TIME_MIN_Pos;
167     g_u32hiSec  = (RTC->TIME & RTC_TIME_TENSEC_Msk) >> RTC_TIME_TENSEC_Pos;
168     g_u32loSec  = (RTC->TIME & RTC_TIME_SEC_Msk) >> RTC_TIME_SEC_Pos;
169 
170     /* Compute to 20XX year */
171     u32Tmp  = (g_u32hiYear * 10UL);
172     u32Tmp += g_u32loYear;
173     sPt->u32Year = u32Tmp + (uint32_t)RTC_YEAR2000;
174 
175     /* Compute 0~12 month */
176     u32Tmp = (g_u32hiMonth * 10UL);
177     sPt->u32Month = u32Tmp + g_u32loMonth;
178 
179     /* Compute 0~31 day */
180     u32Tmp = (g_u32hiDay * 10UL);
181     sPt->u32Day = u32Tmp + g_u32loDay;
182 
183     /* Compute 12/24 hour */
184     if(sPt->u32TimeScale == (uint32_t)RTC_CLOCK_12)
185     {
186         u32Tmp  = (g_u32hiHour * 10UL);
187         u32Tmp += g_u32loHour;
188         sPt->u32Hour = u32Tmp;          /* AM: 1~12. PM: 21~32. */
189 
190         if(sPt->u32Hour >= 21UL)
191         {
192             sPt->u32AmPm  = (uint32_t)RTC_PM;
193             sPt->u32Hour -= 20UL;
194         }
195         else
196         {
197             sPt->u32AmPm = (uint32_t)RTC_AM;
198         }
199 
200         u32Tmp  = (g_u32hiMin  * 10UL);
201         u32Tmp += g_u32loMin;
202         sPt->u32Minute = u32Tmp;
203 
204         u32Tmp  = (g_u32hiSec  * 10UL);
205         u32Tmp += g_u32loSec;
206         sPt->u32Second = u32Tmp;
207     }
208     else
209     {
210         u32Tmp  = (g_u32hiHour * 10UL);
211         u32Tmp += g_u32loHour;
212         sPt->u32Hour = u32Tmp;
213 
214         u32Tmp  = (g_u32hiMin * 10UL);
215         u32Tmp +=  g_u32loMin;
216         sPt->u32Minute = u32Tmp;
217 
218         u32Tmp  = (g_u32hiSec * 10UL);
219         u32Tmp += g_u32loSec;
220         sPt->u32Second = u32Tmp;
221     }
222 }
223 
224 /**
225   * @brief      Get RTC Alarm Date and Time
226   *
227   * @param[out] sPt     The returned pointer is specified the RTC alarm value. It includes: \n
228   *                     u32Year: Year value                                                 \n
229   *                     u32Month: Month value                                               \n
230   *                     u32Day: Day value                                                   \n
231   *                     u32DayOfWeek: Day of week                                           \n
232   *                     u32Hour: Hour value                                                 \n
233   *                     u32Minute: Minute value                                             \n
234   *                     u32Second: Second value                                             \n
235   *                     u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24]                         \n
236   *                     u8AmPm: [RTC_AM / RTC_PM]                                           \n
237   *
238   * @return     None
239   *
240   * @details    This API is used to get the RTC alarm date and time setting.
241   */
RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T * sPt)242 void RTC_GetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt)
243 {
244     uint32_t u32Tmp;
245 
246     sPt->u32TimeScale = RTC->CLKFMT & RTC_CLKFMT_24HEN_Msk;     /* 12/24-hour */
247     sPt->u32DayOfWeek = RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk; /* Day of the week */
248 
249     /* Get alarm [Date digit] data */
250     g_u32hiYear  = (RTC->CALM & RTC_CALM_TENYEAR_Msk) >> RTC_CALM_TENYEAR_Pos;
251     g_u32loYear  = (RTC->CALM & RTC_CALM_YEAR_Msk) >> RTC_CALM_YEAR_Pos;
252     g_u32hiMonth = (RTC->CALM & RTC_CALM_TENMON_Msk) >> RTC_CALM_TENMON_Pos;
253     g_u32loMonth = (RTC->CALM & RTC_CALM_MON_Msk) >> RTC_CALM_MON_Pos;
254     g_u32hiDay   = (RTC->CALM & RTC_CALM_TENDAY_Msk) >> RTC_CALM_TENDAY_Pos;
255     g_u32loDay   = (RTC->CALM & RTC_CALM_DAY_Msk) >> RTC_CALM_DAY_Pos;
256 
257     /* Get alarm [Time digit] data */
258     g_u32hiHour = (RTC->TALM & RTC_TALM_TENHR_Msk) >> RTC_TALM_TENHR_Pos;
259     g_u32loHour = (RTC->TALM & RTC_TALM_HR_Msk) >> RTC_TALM_HR_Pos;
260     g_u32hiMin  = (RTC->TALM & RTC_TALM_TENMIN_Msk) >> RTC_TALM_TENMIN_Pos;
261     g_u32loMin  = (RTC->TALM & RTC_TALM_MIN_Msk) >> RTC_TALM_MIN_Pos;
262     g_u32hiSec  = (RTC->TALM & RTC_TALM_TENSEC_Msk) >> RTC_TALM_TENSEC_Pos;
263     g_u32loSec  = (RTC->TALM & RTC_TALM_SEC_Msk) >> RTC_TALM_SEC_Pos;
264 
265     /* Compute to 20XX year */
266     u32Tmp  = (g_u32hiYear * 10UL);
267     u32Tmp += g_u32loYear;
268     sPt->u32Year = u32Tmp + (uint32_t)RTC_YEAR2000;
269 
270     /* Compute 0~12 month */
271     u32Tmp = (g_u32hiMonth * 10UL);
272     sPt->u32Month = u32Tmp + g_u32loMonth;
273 
274     /* Compute 0~31 day */
275     u32Tmp = (g_u32hiDay * 10UL);
276     sPt->u32Day = u32Tmp + g_u32loDay;
277 
278     /* Compute 12/24 hour */
279     if(sPt->u32TimeScale == (uint32_t)RTC_CLOCK_12)
280     {
281         u32Tmp  = (g_u32hiHour * 10UL);
282         u32Tmp += g_u32loHour;
283         sPt->u32Hour = u32Tmp;          /* AM: 1~12. PM: 21~32. */
284 
285         if(sPt->u32Hour >= 21UL)
286         {
287             sPt->u32AmPm  = (uint32_t)RTC_PM;
288             sPt->u32Hour -= 20UL;
289         }
290         else
291         {
292             sPt->u32AmPm = (uint32_t)RTC_AM;
293         }
294 
295         u32Tmp  = (g_u32hiMin * 10UL);
296         u32Tmp += g_u32loMin;
297         sPt->u32Minute = u32Tmp;
298 
299         u32Tmp  = (g_u32hiSec * 10UL);
300         u32Tmp += g_u32loSec;
301         sPt->u32Second = u32Tmp;
302     }
303     else
304     {
305         u32Tmp  = (g_u32hiHour * 10UL);
306         u32Tmp +=  g_u32loHour;
307         sPt->u32Hour = u32Tmp;
308 
309         u32Tmp  = (g_u32hiMin * 10UL);
310         u32Tmp += g_u32loMin;
311         sPt->u32Minute = u32Tmp;
312 
313         u32Tmp  = (g_u32hiSec * 10UL);
314         u32Tmp += g_u32loSec;
315         sPt->u32Second = u32Tmp;
316     }
317 }
318 
319 /**
320   * @brief      Update Current RTC Date and Time
321   *
322   * @param[in]  sPt     Specify the time property and current date and time. It includes:           \n
323   *                     u32Year: Year value, range between 2000 ~ 2099.                             \n
324   *                     u32Month: Month value, range between 1 ~ 12.                                \n
325   *                     u32Day: Day value, range between 1 ~ 31.                                    \n
326   *                     u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
327   *                                                     RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
328   *                                                     RTC_SATURDAY]                               \n
329   *                     u32Hour: Hour value, range between 0 ~ 23.                                  \n
330   *                     u32Minute: Minute value, range between 0 ~ 59.                              \n
331   *                     u32Second: Second value, range between 0 ~ 59.                              \n
332   *                     u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24]                                 \n
333   *                     u8AmPm: [RTC_AM / RTC_PM]                                                   \n
334   *
335   * @return     None
336   *
337   * @details    This API is used to update current date and time to RTC.
338   */
RTC_SetDateAndTime(S_RTC_TIME_DATA_T * sPt)339 void RTC_SetDateAndTime(S_RTC_TIME_DATA_T *sPt)
340 {
341     uint32_t u32RegCAL, u32RegTIME;
342 
343     if(sPt != 0)
344     {
345         /*-----------------------------------------------------------------------------------------------------*/
346         /* Set RTC 24/12 hour setting and Day of the Week                                                      */
347         /*-----------------------------------------------------------------------------------------------------*/
348         if(sPt->u32TimeScale == (uint32_t)RTC_CLOCK_12)
349         {
350             RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
351 
352             /*-------------------------------------------------------------------------------------------------*/
353             /* Important, range of 12-hour PM mode is 21 up to 32                                               */
354             /*-------------------------------------------------------------------------------------------------*/
355             if(sPt->u32AmPm == (uint32_t)RTC_PM)
356             {
357                 sPt->u32Hour += 20UL;
358             }
359         }
360         else
361         {
362             RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
363         }
364 
365         /* Set Day of the Week */
366         RTC->WEEKDAY = sPt->u32DayOfWeek;
367 
368         /*-----------------------------------------------------------------------------------------------------*/
369         /* Set RTC Current Date and Time                                                                       */
370         /*-----------------------------------------------------------------------------------------------------*/
371         u32RegCAL  = ((sPt->u32Year - (uint32_t)RTC_YEAR2000) / 10UL) << 20;
372         u32RegCAL |= (((sPt->u32Year - (uint32_t)RTC_YEAR2000) % 10UL) << 16);
373         u32RegCAL |= ((sPt->u32Month  / 10UL) << 12);
374         u32RegCAL |= ((sPt->u32Month  % 10UL) << 8);
375         u32RegCAL |= ((sPt->u32Day    / 10UL) << 4);
376         u32RegCAL |= (sPt->u32Day     % 10UL);
377 
378         u32RegTIME  = ((sPt->u32Hour   / 10UL) << 20);
379         u32RegTIME |= ((sPt->u32Hour   % 10UL) << 16);
380         u32RegTIME |= ((sPt->u32Minute / 10UL) << 12);
381         u32RegTIME |= ((sPt->u32Minute % 10UL) << 8);
382         u32RegTIME |= ((sPt->u32Second / 10UL) << 4);
383         u32RegTIME |= (sPt->u32Second % 10UL);
384 
385         /*-----------------------------------------------------------------------------------------------------*/
386         /* Set RTC Calender and Time Loading                                                                   */
387         /*-----------------------------------------------------------------------------------------------------*/
388         RTC->CAL  = (uint32_t)u32RegCAL;
389         RTC->TIME = (uint32_t)u32RegTIME;
390     }
391 }
392 
393 /**
394   * @brief      Update RTC Alarm Date and Time
395   *
396   * @param[in]  sPt     Specify the time property and alarm date and time. It includes:             \n
397   *                     u32Year: Year value, range between 2000 ~ 2099.                             \n
398   *                     u32Month: Month value, range between 1 ~ 12.                                \n
399   *                     u32Day: Day value, range between 1 ~ 31.                                    \n
400   *                     u32DayOfWeek: Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
401   *                                                     RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
402   *                                                     RTC_SATURDAY]                               \n
403   *                     u32Hour: Hour value, range between 0 ~ 23.                                  \n
404   *                     u32Minute: Minute value, range between 0 ~ 59.                              \n
405   *                     u32Second: Second value, range between 0 ~ 59.                              \n
406   *                     u32TimeScale: [RTC_CLOCK_12 / RTC_CLOCK_24]                                 \n
407   *                     u8AmPm: [RTC_AM / RTC_PM]                                                   \n
408   *
409   * @return     None
410   *
411   * @details    This API is used to update alarm date and time setting to RTC.
412   */
RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T * sPt)413 void RTC_SetAlarmDateAndTime(S_RTC_TIME_DATA_T *sPt)
414 {
415     uint32_t u32RegCALM, u32RegTALM;
416 
417     if(sPt != 0)
418     {
419         /*-----------------------------------------------------------------------------------------------------*/
420         /* Set RTC 24/12 hour setting and Day of the Week                                                      */
421         /*-----------------------------------------------------------------------------------------------------*/
422         if(sPt->u32TimeScale == (uint32_t)RTC_CLOCK_12)
423         {
424             RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
425 
426             /*-------------------------------------------------------------------------------------------------*/
427             /* Important, range of 12-hour PM mode is 21 up to 32                                               */
428             /*-------------------------------------------------------------------------------------------------*/
429             if(sPt->u32AmPm == (uint32_t)RTC_PM)
430             {
431                 sPt->u32Hour += 20UL;
432             }
433         }
434         else
435         {
436             RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
437         }
438 
439         /*-----------------------------------------------------------------------------------------------------*/
440         /* Set RTC Alarm Date and Time                                                                         */
441         /*-----------------------------------------------------------------------------------------------------*/
442         u32RegCALM  = ((sPt->u32Year - (uint32_t)RTC_YEAR2000) / 10UL) << 20;
443         u32RegCALM |= (((sPt->u32Year - (uint32_t)RTC_YEAR2000) % 10UL) << 16);
444         u32RegCALM |= ((sPt->u32Month  / 10UL) << 12);
445         u32RegCALM |= ((sPt->u32Month  % 10UL) << 8);
446         u32RegCALM |= ((sPt->u32Day    / 10UL) << 4);
447         u32RegCALM |= (sPt->u32Day    % 10UL);
448 
449         u32RegTALM  = ((sPt->u32Hour   / 10UL) << 20);
450         u32RegTALM |= ((sPt->u32Hour   % 10UL) << 16);
451         u32RegTALM |= ((sPt->u32Minute / 10UL) << 12);
452         u32RegTALM |= ((sPt->u32Minute % 10UL) << 8);
453         u32RegTALM |= ((sPt->u32Second / 10UL) << 4);
454         u32RegTALM |= (sPt->u32Second % 10UL);
455 
456         RTC->CALM = (uint32_t)u32RegCALM;
457         RTC->TALM = (uint32_t)u32RegTALM;
458     }
459 }
460 
461 /**
462   * @brief      Update RTC Current Date
463   *
464   * @param[in]  u32Year         The year calendar digit of current RTC setting.
465   * @param[in]  u32Month        The month calendar digit of current RTC setting.
466   * @param[in]  u32Day          The day calendar digit of current RTC setting.
467   * @param[in]  u32DayOfWeek    The Day of the week. [RTC_SUNDAY / RTC_MONDAY / RTC_TUESDAY /
468   *                                                   RTC_WEDNESDAY / RTC_THURSDAY / RTC_FRIDAY /
469   *                                                   RTC_SATURDAY]
470   *
471   * @return     None
472   *
473   * @details    This API is used to update current date to RTC.
474   */
RTC_SetDate(uint32_t u32Year,uint32_t u32Month,uint32_t u32Day,uint32_t u32DayOfWeek)475 void RTC_SetDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day, uint32_t u32DayOfWeek)
476 {
477     uint32_t u32RegCAL;
478 
479     u32RegCAL  = ((u32Year - (uint32_t)RTC_YEAR2000) / 10UL) << 20;
480     u32RegCAL |= (((u32Year - (uint32_t)RTC_YEAR2000) % 10UL) << 16);
481     u32RegCAL |= ((u32Month / 10UL) << 12);
482     u32RegCAL |= ((u32Month % 10UL) << 8);
483     u32RegCAL |= ((u32Day   / 10UL) << 4);
484     u32RegCAL |= (u32Day   % 10UL);
485 
486 
487     /* Set Day of the Week */
488     RTC->WEEKDAY = u32DayOfWeek & RTC_WEEKDAY_WEEKDAY_Msk;
489 
490     /* Set RTC Calender Loading */
491     RTC->CAL = (uint32_t)u32RegCAL;
492 }
493 
494 /**
495   * @brief      Update RTC Current Time
496   *
497   * @param[in]  u32Hour         The hour time digit of current RTC setting.
498   * @param[in]  u32Minute       The minute time digit of current RTC setting.
499   * @param[in]  u32Second       The second time digit of current RTC setting.
500   * @param[in]  u32TimeMode     The 24-Hour / 12-Hour Time Scale Selection. [RTC_CLOCK_12 / RTC_CLOCK_24]
501   * @param[in]  u32AmPm         12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [RTC_AM / RTC_PM]
502   *
503   * @return     None
504   *
505   * @details    This API is used to update current time to RTC.
506   */
RTC_SetTime(uint32_t u32Hour,uint32_t u32Minute,uint32_t u32Second,uint32_t u32TimeMode,uint32_t u32AmPm)507 void RTC_SetTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm)
508 {
509     uint32_t u32RegTIME;
510 
511     /* Important, range of 12-hour PM mode is 21 up to 32 */
512     if((u32TimeMode == (uint32_t)RTC_CLOCK_12) && (u32AmPm == (uint32_t)RTC_PM))
513     {
514         u32Hour += 20UL;
515     }
516 
517     u32RegTIME  = ((u32Hour   / 10UL) << 20);
518     u32RegTIME |= ((u32Hour   % 10UL) << 16);
519     u32RegTIME |= ((u32Minute / 10UL) << 12);
520     u32RegTIME |= ((u32Minute % 10UL) << 8);
521     u32RegTIME |= ((u32Second / 10UL) << 4);
522     u32RegTIME |= (u32Second % 10UL);
523 
524     /*-----------------------------------------------------------------------------------------------------*/
525     /* Set RTC 24/12 hour setting and Day of the Week                                                      */
526     /*-----------------------------------------------------------------------------------------------------*/
527     if(u32TimeMode == (uint32_t)RTC_CLOCK_12)
528     {
529         RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
530     }
531     else
532     {
533         RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
534     }
535 
536     RTC->TIME = (uint32_t)u32RegTIME;
537 }
538 
539 /**
540   * @brief      Update RTC Alarm Date
541   *
542   * @param[in]  u32Year         The year calendar digit of RTC alarm setting.
543   * @param[in]  u32Month        The month calendar digit of RTC alarm setting.
544   * @param[in]  u32Day          The day calendar digit of RTC alarm setting.
545   *
546   * @return     None
547   *
548   * @details    This API is used to update alarm date setting to RTC.
549   */
RTC_SetAlarmDate(uint32_t u32Year,uint32_t u32Month,uint32_t u32Day)550 void RTC_SetAlarmDate(uint32_t u32Year, uint32_t u32Month, uint32_t u32Day)
551 {
552     uint32_t u32RegCALM;
553 
554     u32RegCALM  = ((u32Year - (uint32_t)RTC_YEAR2000) / 10UL) << 20;
555     u32RegCALM |= (((u32Year - (uint32_t)RTC_YEAR2000) % 10UL) << 16);
556     u32RegCALM |= ((u32Month / 10UL) << 12);
557     u32RegCALM |= ((u32Month % 10UL) << 8);
558     u32RegCALM |= ((u32Day   / 10UL) << 4);
559     u32RegCALM |= (u32Day   % 10UL);
560 
561 
562     /* Set RTC Alarm Date */
563     RTC->CALM = (uint32_t)u32RegCALM;
564 }
565 
566 /**
567   * @brief      Update RTC Alarm Time
568   *
569   * @param[in]  u32Hour         The hour time digit of RTC alarm setting.
570   * @param[in]  u32Minute       The minute time digit of RTC alarm setting.
571   * @param[in]  u32Second       The second time digit of RTC alarm setting.
572   * @param[in]  u32TimeMode     The 24-Hour / 12-Hour Time Scale Selection. [RTC_CLOCK_12 / RTC_CLOCK_24]
573   * @param[in]  u32AmPm         12-hour time scale with AM and PM indication. Only Time Scale select 12-hour used. [RTC_AM / RTC_PM]
574   *
575   * @return     None
576   *
577   * @details    This API is used to update alarm time setting to RTC.
578   */
RTC_SetAlarmTime(uint32_t u32Hour,uint32_t u32Minute,uint32_t u32Second,uint32_t u32TimeMode,uint32_t u32AmPm)579 void RTC_SetAlarmTime(uint32_t u32Hour, uint32_t u32Minute, uint32_t u32Second, uint32_t u32TimeMode, uint32_t u32AmPm)
580 {
581     uint32_t u32RegTALM;
582 
583     /* Important, range of 12-hour PM mode is 21 up to 32 */
584     if((u32TimeMode == (uint32_t)RTC_CLOCK_12) && (u32AmPm == (uint32_t)RTC_PM))
585     {
586         u32Hour += 20UL;
587     }
588 
589     u32RegTALM  = ((u32Hour   / 10UL) << 20);
590     u32RegTALM |= ((u32Hour   % 10UL) << 16);
591     u32RegTALM |= ((u32Minute / 10UL) << 12);
592     u32RegTALM |= ((u32Minute % 10UL) << 8);
593     u32RegTALM |= ((u32Second / 10UL) << 4);
594     u32RegTALM |= (u32Second % 10UL);
595 
596     /*-----------------------------------------------------------------------------------------------------*/
597     /* Set RTC 24/12 hour setting and Day of the Week                                                      */
598     /*-----------------------------------------------------------------------------------------------------*/
599     if(u32TimeMode == (uint32_t)RTC_CLOCK_12)
600     {
601         RTC->CLKFMT &= ~RTC_CLKFMT_24HEN_Msk;
602     }
603     else
604     {
605         RTC->CLKFMT |= RTC_CLKFMT_24HEN_Msk;
606     }
607 
608     /* Set RTC Alarm Time */
609     RTC->TALM = (uint32_t)u32RegTALM;
610 }
611 
612 /**
613   * @brief      Set RTC Alarm Date Mask Function
614   *
615   * @param[in]  u8IsTenYMsk     1: enable 10-Year digit alarm mask; 0: disabled.
616   * @param[in]  u8IsYMsk        1: enable 1-Year digit alarm mask; 0: disabled.
617   * @param[in]  u8IsTenMMsk     1: enable 10-Mon digit alarm mask; 0: disabled.
618   * @param[in]  u8IsMMsk        1: enable 1-Mon digit alarm mask; 0: disabled.
619   * @param[in]  u8IsTenDMsk     1: enable 10-Day digit alarm mask; 0: disabled.
620   * @param[in]  u8IsDMsk        1: enable 1-Day digit alarm mask; 0: disabled.
621   *
622   * @return     None
623   *
624   * @details    This API is used to enable or disable RTC alarm date mask function.
625   */
RTC_SetAlarmDateMask(uint8_t u8IsTenYMsk,uint8_t u8IsYMsk,uint8_t u8IsTenMMsk,uint8_t u8IsMMsk,uint8_t u8IsTenDMsk,uint8_t u8IsDMsk)626 void RTC_SetAlarmDateMask(uint8_t u8IsTenYMsk, uint8_t u8IsYMsk, uint8_t u8IsTenMMsk, uint8_t u8IsMMsk, uint8_t u8IsTenDMsk, uint8_t u8IsDMsk)
627 {
628     RTC->CAMSK = ((uint32_t)u8IsTenYMsk << RTC_CAMSK_MTENYEAR_Pos) |
629                  ((uint32_t)u8IsYMsk    << RTC_CAMSK_MYEAR_Pos) |
630                  ((uint32_t)u8IsTenMMsk << RTC_CAMSK_MTENMON_Pos) |
631                  ((uint32_t)u8IsMMsk    << RTC_CAMSK_MMON_Pos) |
632                  ((uint32_t)u8IsTenDMsk << RTC_CAMSK_MTENDAY_Pos) |
633                  ((uint32_t)u8IsDMsk    << RTC_CAMSK_MDAY_Pos);
634 }
635 
636 /**
637   * @brief      Set RTC Alarm Time Mask Function
638   *
639   * @param[in]  u8IsTenHMsk     1: enable 10-Hour digit alarm mask; 0: disabled.
640   * @param[in]  u8IsHMsk        1: enable 1-Hour digit alarm mask; 0: disabled.
641   * @param[in]  u8IsTenMMsk     1: enable 10-Min digit alarm mask; 0: disabled.
642   * @param[in]  u8IsMMsk        1: enable 1-Min digit alarm mask; 0: disabled.
643   * @param[in]  u8IsTenSMsk     1: enable 10-Sec digit alarm mask; 0: disabled.
644   * @param[in]  u8IsSMsk        1: enable 1-Sec digit alarm mask; 0: disabled.
645   *
646   * @return     None
647   *
648   * @details    This API is used to enable or disable RTC alarm time mask function.
649   */
RTC_SetAlarmTimeMask(uint8_t u8IsTenHMsk,uint8_t u8IsHMsk,uint8_t u8IsTenMMsk,uint8_t u8IsMMsk,uint8_t u8IsTenSMsk,uint8_t u8IsSMsk)650 void RTC_SetAlarmTimeMask(uint8_t u8IsTenHMsk, uint8_t u8IsHMsk, uint8_t u8IsTenMMsk, uint8_t u8IsMMsk, uint8_t u8IsTenSMsk, uint8_t u8IsSMsk)
651 {
652     RTC->TAMSK = ((uint32_t)u8IsTenHMsk << RTC_TAMSK_MTENHR_Pos) |
653                  ((uint32_t)u8IsHMsk    << RTC_TAMSK_MHR_Pos) |
654                  ((uint32_t)u8IsTenMMsk << RTC_TAMSK_MTENMIN_Pos) |
655                  ((uint32_t)u8IsMMsk    << RTC_TAMSK_MMIN_Pos) |
656                  ((uint32_t)u8IsTenSMsk << RTC_TAMSK_MTENSEC_Pos) |
657                  ((uint32_t)u8IsSMsk    << RTC_TAMSK_MSEC_Pos);
658 }
659 
660 /**
661   * @brief      Get Day of the Week
662   *
663   * @param      None
664   *
665   * @retval     0   Sunday
666   * @retval     1   Monday
667   * @retval     2   Tuesday
668   * @retval     3   Wednesday
669   * @retval     4   Thursday
670   * @retval     5   Friday
671   * @retval     6   Saturday
672   *
673   * @details    This API is used to get day of the week of current RTC date.
674   */
RTC_GetDayOfWeek(void)675 uint32_t RTC_GetDayOfWeek(void)
676 {
677     return (RTC->WEEKDAY & RTC_WEEKDAY_WEEKDAY_Msk);
678 }
679 
680 /**
681   * @brief      Set RTC Tick Period Time
682   *
683   * @param[in]  u32TickSelection    It is used to set the RTC tick period time for Periodic Time Tick request. \n
684   *                                 It consists of:
685   *                                     - \ref RTC_TICK_1_SEC     : Time tick is 1 second
686   *                                     - \ref RTC_TICK_1_2_SEC   : Time tick is 1/2 second
687   *                                     - \ref RTC_TICK_1_4_SEC   : Time tick is 1/4 second
688   *                                     - \ref RTC_TICK_1_8_SEC   : Time tick is 1/8 second
689   *                                     - \ref RTC_TICK_1_16_SEC  : Time tick is 1/16 second
690   *                                     - \ref RTC_TICK_1_32_SEC  : Time tick is 1/32 second
691   *                                     - \ref RTC_TICK_1_64_SEC  : Time tick is 1/64 second
692   *                                     - \ref RTC_TICK_1_128_SEC : Time tick is 1/128 second
693   *
694   * @return     None
695   *
696   * @details    This API is used to set RTC tick period time for each tick interrupt.
697   */
RTC_SetTickPeriod(uint32_t u32TickSelection)698 void RTC_SetTickPeriod(uint32_t u32TickSelection)
699 {
700     RTC->TICK = (RTC->TICK & ~RTC_TICK_TICK_Msk) | u32TickSelection;
701 }
702 
703 /**
704   * @brief      Enable RTC Interrupt
705   *
706   * @param[in]  u32IntFlagMask      Specify the interrupt source. It consists of:
707   *                                     - \ref RTC_INTEN_ALMIEN_Msk   : Alarm interrupt
708   *                                     - \ref RTC_INTEN_TICKIEN_Msk  : Tick interrupt
709   *                                     - \ref RTC_INTEN_TAMP0IEN_Msk : Tamper 0 Pin Event Detection interrupt
710   *                                     - \ref RTC_INTEN_TAMP1IEN_Msk : Tamper 1 or Pair 0 Pin Event Detection interrupt
711   *                                     - \ref RTC_INTEN_TAMP2IEN_Msk : Tamper 2 Pin Event Detection interrupt
712   *                                     - \ref RTC_INTEN_TAMP3IEN_Msk : Tamper 3 or Pair 1 Pin Event Detection interrupt
713   *                                     - \ref RTC_INTEN_TAMP4IEN_Msk : Tamper 4 Pin Event Detection interrupt
714   *                                     - \ref RTC_INTEN_TAMP5IEN_Msk : Tamper 5 or Pair 2 Pin Event Detection interrupt
715   *                                     - \ref RTC_INTEN_CLKFIEN_Msk  : LXT Clock Frequency Monitor Fail interrupt
716   *                                     - \ref RTC_INTEN_CLKSTIEN_Msk : LXT Clock Frequency Monitor Stop interrupt
717   *
718   * @return     None
719   *
720   * @details    This API is used to enable the specify RTC interrupt function.
721   */
RTC_EnableInt(uint32_t u32IntFlagMask)722 void RTC_EnableInt(uint32_t u32IntFlagMask)
723 {
724     RTC->INTEN |= u32IntFlagMask;
725 }
726 
727 /**
728   * @brief      Disable RTC Interrupt
729   *
730   * @param[in]  u32IntFlagMask      Specify the interrupt source. It consists of:
731   *                                     - \ref RTC_INTEN_ALMIEN_Msk   : Alarm interrupt
732   *                                     - \ref RTC_INTEN_TICKIEN_Msk  : Tick interrupt
733   *                                     - \ref RTC_INTEN_TAMP0IEN_Msk : Tamper 0 Pin Event Detection interrupt
734   *                                     - \ref RTC_INTEN_TAMP1IEN_Msk : Tamper 1 or Pair 0 Pin Event Detection interrupt
735   *                                     - \ref RTC_INTEN_TAMP2IEN_Msk : Tamper 2 Pin Event Detection interrupt
736   *                                     - \ref RTC_INTEN_TAMP3IEN_Msk : Tamper 3 or Pair 1 Pin Event Detection interrupt
737   *                                     - \ref RTC_INTEN_TAMP4IEN_Msk : Tamper 4 Pin Event Detection interrupt
738   *                                     - \ref RTC_INTEN_TAMP5IEN_Msk : Tamper 5 or Pair 2 Pin Event Detection interrupt
739   *                                     - \ref RTC_INTEN_CLKFIEN_Msk  : LXT Clock Frequency Monitor Fail interrupt
740   *                                     - \ref RTC_INTEN_CLKSTIEN_Msk : LXT Clock Frequency Monitor Stop interrupt
741   *
742   * @return     None
743   *
744   * @details    This API is used to disable the specify RTC interrupt function.
745   */
RTC_DisableInt(uint32_t u32IntFlagMask)746 void RTC_DisableInt(uint32_t u32IntFlagMask)
747 {
748     RTC->INTEN  &= ~u32IntFlagMask;
749     RTC->INTSTS = u32IntFlagMask;
750 }
751 
752 /**
753   * @brief      Enable Spare Registers Access
754   *
755   * @param      None
756   *
757   * @return     None
758   *
759   * @details    This API is used to enable the spare registers 0~19 can be accessed.
760   */
RTC_EnableSpareAccess(void)761 void RTC_EnableSpareAccess(void)
762 {
763     RTC->SPRCTL |= RTC_SPRCTL_SPRRWEN_Msk;
764 }
765 
766 /**
767   * @brief      Disable Spare Register
768   *
769   * @param      None
770   *
771   * @return     None
772   *
773   * @details    This API is used to disable the spare register 0~19 cannot be accessed.
774   */
RTC_DisableSpareRegister(void)775 void RTC_DisableSpareRegister(void)
776 {
777     RTC->SPRCTL &= ~RTC_SPRCTL_SPRRWEN_Msk;
778 }
779 
780 /**
781   * @brief      Static Tamper Detect
782   *
783   * @param[in]  u32TamperSelect     Tamper pin select. Possible options are
784   *                                 - \ref RTC_TAMPER5_SELECT
785   *                                 - \ref RTC_TAMPER4_SELECT
786   *                                 - \ref RTC_TAMPER3_SELECT
787   *                                 - \ref RTC_TAMPER2_SELECT
788   *                                 - \ref RTC_TAMPER1_SELECT
789   *                                 - \ref RTC_TAMPER0_SELECT
790   *
791   * @param[in]  u32DetecLevel       Tamper pin detection level select. Possible options are
792   *                                 - \ref RTC_TAMPER_HIGH_LEVEL_DETECT
793   *                                 - \ref RTC_TAMPER_LOW_LEVEL_DETECT
794   *
795   * @param[in]  u32DebounceEn       Tamper pin de-bounce enable
796   *                                 - \ref RTC_TAMPER_DEBOUNCE_ENABLE
797   *                                 - \ref RTC_TAMPER_DEBOUNCE_DISABLE
798   *
799   * @return     None
800   *
801   * @details    This API is used to enable the tamper pin detect function with specify trigger condition.
802   *             User need disable dynamic tamper function before use this API.
803   */
RTC_StaticTamperEnable(uint32_t u32TamperSelect,uint32_t u32DetecLevel,uint32_t u32DebounceEn)804 void RTC_StaticTamperEnable(uint32_t u32TamperSelect, uint32_t u32DetecLevel, uint32_t u32DebounceEn)
805 {
806     uint32_t i;
807     uint32_t u32Reg;
808     uint32_t u32TmpReg;
809 
810     u32Reg = RTC->TAMPCTL;
811 
812     u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk | (u32DetecLevel << RTC_TAMPCTL_TAMP0LV_Pos) |
813                  (u32DebounceEn << RTC_TAMPCTL_TAMP0DBEN_Pos));
814 
815     for(i = 0UL; i < (uint32_t)RTC_MAX_TAMPER_PIN_NUM; i++)
816     {
817         if(u32TamperSelect & (0x1UL << i))
818         {
819             u32Reg &= ~((RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP0LV_Msk | RTC_TAMPCTL_TAMP0DBEN_Msk) << (i * 4UL));
820             u32Reg |= (u32TmpReg << (i * 4UL));
821         }
822     }
823 
824     RTC->TAMPCTL = u32Reg;
825 
826 }
827 
828 /**
829   * @brief      Static Tamper Disable
830   *
831   * @param[in]  u32TamperSelect     Tamper pin select. Possible options are
832   *                                 - \ref RTC_TAMPER5_SELECT
833   *                                 - \ref RTC_TAMPER4_SELECT
834   *                                 - \ref RTC_TAMPER3_SELECT
835   *                                 - \ref RTC_TAMPER2_SELECT
836   *                                 - \ref RTC_TAMPER1_SELECT
837   *                                 - \ref RTC_TAMPER0_SELECT
838   *
839   * @return     None
840   *
841   * @details    This API is used to disable the static tamper pin detect.
842   */
RTC_StaticTamperDisable(uint32_t u32TamperSelect)843 void RTC_StaticTamperDisable(uint32_t u32TamperSelect)
844 {
845     uint32_t i;
846     uint32_t u32Reg;
847     uint32_t u32TmpReg;
848 
849     u32Reg = RTC->TAMPCTL;
850 
851     u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk);
852 
853     for(i = 0UL; i < (uint32_t)RTC_MAX_TAMPER_PIN_NUM; i++)
854     {
855         if(u32TamperSelect & (0x1UL << i))
856         {
857             u32Reg &= ~(u32TmpReg << (i * 4UL));
858         }
859     }
860 
861     RTC->TAMPCTL = u32Reg;
862 }
863 
864 /**
865   * @brief      Dynamic Tamper Detect
866   *
867   * @param[in]  u32PairSel          Tamper pin detection enable. Possible options are
868   *                                 - \ref RTC_PAIR0_SELECT
869   *                                 - \ref RTC_PAIR1_SELECT
870   *                                 - \ref RTC_PAIR2_SELECT
871   *
872   * @param[in]  u32DebounceEn       Tamper pin de-bounce enable
873   *                                 - \ref RTC_TAMPER_DEBOUNCE_ENABLE
874   *                                 - \ref RTC_TAMPER_DEBOUNCE_DISABLE
875   *
876   *  @param[in]  u32Pair1Source     Dynamic Pair 1 Input Source Select
877   *                                 0: Pair 1 source select tamper 2
878   *                                 1: Pair 1 source select tamper 0
879   *
880   *  @param[in]  u32Pair2Source     Dynamic Pair 2 Input Source Select
881   *                                 0: Pair 2 source select tamper 4
882   *                                 1: Pair 2 source select tamper 0
883   *
884   * @return     None
885   *
886   * @details    This API is used to enable the dynamic tamper.
887   */
RTC_DynamicTamperEnable(uint32_t u32PairSel,uint32_t u32DebounceEn,uint32_t u32Pair1Source,uint32_t u32Pair2Source)888 void RTC_DynamicTamperEnable(uint32_t u32PairSel, uint32_t u32DebounceEn, uint32_t u32Pair1Source, uint32_t u32Pair2Source)
889 {
890     uint32_t i;
891     uint32_t u32Reg;
892     uint32_t u32TmpReg;
893     uint32_t u32Tamper2Debounce, u32Tamper4Debounce;
894 
895     u32Reg = RTC->TAMPCTL;
896     u32Reg &= ~(RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP1EN_Msk | RTC_TAMPCTL_TAMP2EN_Msk |
897                 RTC_TAMPCTL_TAMP3EN_Msk | RTC_TAMPCTL_TAMP4EN_Msk | RTC_TAMPCTL_TAMP5EN_Msk);
898 
899     u32Tamper2Debounce = u32Reg & RTC_TAMPCTL_TAMP2DBEN_Msk;
900     u32Tamper4Debounce = u32Reg & RTC_TAMPCTL_TAMP4DBEN_Msk;
901 
902     u32Reg &= ~(RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP1EN_Msk | RTC_TAMPCTL_TAMP2EN_Msk |
903                 RTC_TAMPCTL_TAMP3EN_Msk | RTC_TAMPCTL_TAMP4EN_Msk | RTC_TAMPCTL_TAMP5EN_Msk);
904     u32Reg &= ~(RTC_TAMPCTL_DYN1ISS_Msk | RTC_TAMPCTL_DYN2ISS_Msk);
905     u32Reg |= ((u32Pair1Source & 0x1UL) << RTC_TAMPCTL_DYN1ISS_Pos) | ((u32Pair2Source & 0x1UL) << RTC_TAMPCTL_DYN2ISS_Pos);
906 
907     if(u32DebounceEn)
908     {
909         u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP1EN_Msk |
910                      RTC_TAMPCTL_TAMP0DBEN_Msk | RTC_TAMPCTL_TAMP1DBEN_Msk | RTC_TAMPCTL_DYNPR0EN_Msk);
911     }
912     else
913     {
914         u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP1EN_Msk | RTC_TAMPCTL_DYNPR0EN_Msk);
915     }
916 
917     for(i = 0UL; i < (uint32_t)RTC_MAX_PAIR_NUM; i++)
918     {
919         if(u32PairSel & (0x1UL << i))
920         {
921             u32Reg &= ~((RTC_TAMPCTL_TAMP0DBEN_Msk | RTC_TAMPCTL_TAMP1DBEN_Msk) << (i * 8UL));
922             u32Reg |= (u32TmpReg << (i * 8UL));
923         }
924     }
925 
926     if((u32Pair1Source) && (u32PairSel & (uint32_t)RTC_PAIR1_SELECT))
927     {
928         u32Reg &= ~RTC_TAMPCTL_TAMP2EN_Msk;
929         u32Reg |= u32Tamper2Debounce;
930     }
931 
932     if((u32Pair2Source) && (u32PairSel & (uint32_t)RTC_PAIR2_SELECT))
933     {
934         u32Reg &= ~RTC_TAMPCTL_TAMP4EN_Msk;
935         u32Reg |= u32Tamper4Debounce;
936     }
937 
938     RTC->TAMPCTL = u32Reg;
939 }
940 
941 /**
942   * @brief      Dynamic Tamper Disable
943   *
944   * @param[in]  u32PairSel          Tamper pin detection enable. Possible options are
945   *                                 - \ref RTC_PAIR0_SELECT
946   *                                 - \ref RTC_PAIR1_SELECT
947   *                                 - \ref RTC_PAIR2_SELECT
948   *
949   * @return     None
950   *
951   * @details    This API is used to disable the dynamic tamper.
952   */
RTC_DynamicTamperDisable(uint32_t u32PairSel)953 void RTC_DynamicTamperDisable(uint32_t u32PairSel)
954 {
955     uint32_t i;
956     uint32_t u32Reg;
957     uint32_t u32TmpReg;
958     uint32_t u32Tamper2En = 0UL, u32Tamper4En = 0UL;
959 
960     u32Reg = RTC->TAMPCTL;
961 
962     if((u32Reg & (uint32_t)RTC_TAMPCTL_DYN1ISS_Msk) && (u32PairSel & (uint32_t)RTC_PAIR1_SELECT))
963     {
964         u32Tamper2En = u32Reg & RTC_TAMPCTL_TAMP2EN_Msk;
965     }
966 
967     if((u32Reg & (uint32_t)RTC_TAMPCTL_DYN2ISS_Msk) && (u32PairSel & (uint32_t)RTC_PAIR2_SELECT))
968     {
969         u32Tamper4En = u32Reg & RTC_TAMPCTL_TAMP4EN_Msk;
970     }
971 
972     u32TmpReg = (RTC_TAMPCTL_TAMP0EN_Msk | RTC_TAMPCTL_TAMP1EN_Msk | RTC_TAMPCTL_DYNPR0EN_Msk);
973 
974     for(i = 0UL; i < (uint32_t)RTC_MAX_PAIR_NUM; i++)
975     {
976         if(u32PairSel & (0x1UL << i))
977         {
978             u32Reg &= ~(u32TmpReg << ((i * 8UL)));
979         }
980     }
981 
982     u32Reg |= (u32Tamper2En | u32Tamper4En);
983 
984     RTC->TAMPCTL = u32Reg;
985 }
986 
987 /**
988   * @brief      Config Dynamic Tamper
989   *
990   * @param[in]  u32ChangeRate       The dynamic tamper output change rate
991   *                                 - \ref RTC_2POW10_CLK
992   *                                 - \ref RTC_2POW11_CLK
993   *                                 - \ref RTC_2POW12_CLK
994   *                                 - \ref RTC_2POW13_CLK
995   *                                 - \ref RTC_2POW14_CLK
996   *                                 - \ref RTC_2POW15_CLK
997   *                                 - \ref RTC_2POW16_CLK
998   *                                 - \ref RTC_2POW17_CLK
999   *
1000   * @param[in]  u32SeedReload       Reload new seed or not
1001   *                                 0: not reload new seed
1002   *                                 1: reload new seed
1003   *
1004   * @param[in]  u32RefPattern       Reference pattern
1005   *                                 - \ref RTC_REF_RANDOM_PATTERN
1006   *                                 - \ref RTC_REF_SEED_VALUE
1007   *
1008   * @param[in]  u32Seed             Seed Value (0x0 ~ 0xFFFFFFFF)
1009   *
1010   * @return     None
1011   *
1012   * @details    This API is used to config dynamic tamper setting.
1013   */
RTC_DynamicTamperConfig(uint32_t u32ChangeRate,uint32_t u32SeedReload,uint32_t u32RefPattern,uint32_t u32Seed)1014 void RTC_DynamicTamperConfig(uint32_t u32ChangeRate, uint32_t u32SeedReload, uint32_t u32RefPattern, uint32_t u32Seed)
1015 {
1016     uint32_t u32Reg;
1017 
1018     u32Reg = RTC->TAMPCTL;
1019 
1020     u32Reg &= ~(RTC_TAMPCTL_DYNSRC_Msk | RTC_TAMPCTL_SEEDRLD_Msk | RTC_TAMPCTL_DYNRATE_Msk);
1021 
1022     u32Reg |= (u32ChangeRate) | ((u32SeedReload & 0x1UL) << RTC_TAMPCTL_SEEDRLD_Pos) |
1023               (u32RefPattern << RTC_TAMPCTL_DYNSRC_Pos);
1024 
1025     RTC->TAMPSEED = u32Seed; /* need set seed value before re-loade seed */
1026     RTC->TAMPCTL = u32Reg;
1027 }
1028 
1029 /**
1030   * @brief      Set RTC Clock Source
1031   *
1032   * @param[in]  u32ClkSrc       u32ClkSrc is the RTC clock source. It could be
1033   *                             - \ref RTC_CLOCK_SOURCE_LXT
1034   *                             - \ref RTC_CLOCK_SOURCE_LIRC
1035   *                             - \ref RTC_CLOCK_SOURCE_LIRC32K
1036   *
1037   * @retval     RTC_CLOCK_SOURCE_LXT
1038   * @retval     RTC_CLOCK_SOURCE_LIRC
1039   * @retval     RTC_CLOCK_SOURCE_LIRC32K
1040   *
1041   * @details    This API is used to get the setting of RTC clock source.
1042   *             User must to enable the selected clock source by themselves executing perform this API.
1043   */
RTC_SetClockSource(uint32_t u32ClkSrc)1044 uint32_t RTC_SetClockSource(uint32_t u32ClkSrc)
1045 {
1046     uint32_t u32TrimDefault = inpw(SYS_BASE + 0x14Cul);
1047 
1048     if(u32ClkSrc == RTC_CLOCK_SOURCE_LXT)
1049     {
1050         /* RTC clock source is external LXT */
1051         RTC->LXTCTL &= ~RTC_LXTCTL_RTCCKSEL_Msk;
1052         RTC->LXTCTL &= ~RTC_LXTCTL_C32KSEL_Msk;
1053 
1054         return RTC_CLOCK_SOURCE_LXT;
1055     }
1056     else if(u32ClkSrc == RTC_CLOCK_SOURCE_LIRC32K)
1057     {
1058         /* Load LIRC32 trim setting */
1059         RTC->LXTCTL = ((RTC->LXTCTL & ~(0x1FFul << 16)) | ((u32TrimDefault & 0x1FFul) << 16));
1060 
1061         /* RTC clock source is LIRC32K */
1062         RTC->LXTCTL |= RTC_LXTCTL_LIRC32KEN_Msk;
1063         RTC->LXTCTL &= ~RTC_LXTCTL_RTCCKSEL_Msk;
1064         RTC->LXTCTL |= RTC_LXTCTL_C32KSEL_Msk;
1065 
1066         return RTC_CLOCK_SOURCE_LIRC32K;
1067     }
1068     else if(u32ClkSrc == RTC_CLOCK_SOURCE_LIRC)
1069     {
1070         /* RTC clock source is LIRC */
1071         RTC->LXTCTL |= RTC_LXTCTL_RTCCKSEL_Msk;
1072 
1073         return RTC_CLOCK_SOURCE_LIRC;
1074     }
1075     else
1076     {
1077         /* Set the default RTC clock source is LIRC */
1078         RTC->LXTCTL |= RTC_LXTCTL_RTCCKSEL_Msk;
1079 
1080         return RTC_CLOCK_SOURCE_LIRC;
1081     }
1082 }
1083 
1084 /**
1085  * @brief       Set RTC GPIO Operation Mode
1086  *
1087  * @param[in]   u32Pin          The single pin of GPIO-F port.
1088  *                              It could be 4~11, which means PF.4~PF.11.
1089  * @param[in]   u32Mode         Operation mode. It could be
1090  *                              - \ref RTC_IO_MODE_INPUT
1091  *                              - \ref RTC_IO_MODE_OUTPUT
1092  *                              - \ref RTC_IO_MODE_OPEN_DRAIN
1093  *                              - \ref RTC_IO_MODE_QUASI
1094  * @param[in]   u32DigitalCtl   The digital input path control of specified pin. It could be
1095  *                              - \ref RTC_IO_DIGITAL_ENABLE
1096  *                              - \ref RTC_IO_DIGITAL_DISABLE
1097  * @param[in]   u32PullCtl      The pull-up or pull-down control of specified pin. It could be
1098  *                              - \ref RTC_IO_PULL_UP_DOWN_DISABLE
1099  *                              - \ref RTC_IO_PULL_UP_ENABLE
1100  *                              - \ref RTC_IO_PULL_DOWN_ENABLE
1101  * @param[in]   u32OutputLevel  The I/O output level. 0: output low; 1: output high.
1102  *
1103  * @return      None
1104  *
1105  * @details     This function is used to set specified GPIO operation mode controlled by RTC module.
1106  */
RTC_SetGPIOMode(uint32_t u32PFPin,uint32_t u32Mode,uint32_t u32DigitalCtl,uint32_t u32PullCtl,uint32_t u32OutputLevel)1107 void RTC_SetGPIOMode(uint32_t u32PFPin, uint32_t u32Mode, uint32_t u32DigitalCtl, uint32_t u32PullCtl, uint32_t u32OutputLevel)
1108 {
1109     uint32_t u32Offset;
1110 
1111     if((u32PFPin == 4) || (u32PFPin == 5) || (u32PFPin == 6) || (u32PFPin == 7))
1112     {
1113         u32Offset = u32PFPin - 4;
1114 
1115         RTC_SET_IOCTL_BY_RTC(RTC);
1116 
1117         RTC->GPIOCTL0 = (RTC->GPIOCTL0 & ~(0x3FUL << (u32Offset * 8))) |
1118                         (u32Mode << (u32Offset * 8)) |
1119                         (u32OutputLevel << ((u32Offset * 8) + 2)) |
1120                         (u32DigitalCtl << ((u32Offset * 8) + 3)) |
1121                         (u32PullCtl << ((u32Offset * 8) + 4));
1122     }
1123 
1124     if((u32PFPin == 8) || (u32PFPin == 9) || (u32PFPin == 10) || (u32PFPin == 11))
1125     {
1126         u32Offset = u32PFPin - 8;
1127 
1128         RTC_SET_IOCTL_BY_RTC(RTC);
1129 
1130         RTC->GPIOCTL1 = (RTC->GPIOCTL1 & ~(0x3FUL << (u32Offset * 8))) |
1131                         (u32Mode << (u32Offset * 8)) |
1132                         (u32OutputLevel << ((u32Offset * 8) + 2)) |
1133                         (u32DigitalCtl << ((u32Offset * 8) + 3)) |
1134                         (u32PullCtl << ((u32Offset * 8) + 4));
1135     }
1136 }
1137 
1138 /**
1139  * @brief       Set RTC GPIO Output Level
1140  *
1141  * @param[in]   u32Pin          The single pin of GPIO-F port.
1142  *                              It could be 4~11, which means PF.4~PF.11.
1143  * @param[in]   u32OutputLevel  The I/O output level. 0: output low; 1: output high.
1144  *
1145  * @return      None
1146  *
1147  * @details     This function is used to set GPIO output level by RTC module.
1148  */
RTC_SetGPIOLevel(uint32_t u32PFPin,uint32_t u32OutputLevel)1149 void RTC_SetGPIOLevel(uint32_t u32PFPin, uint32_t u32OutputLevel)
1150 {
1151     uint32_t u32Offset;
1152 
1153     if((u32PFPin == 4) || (u32PFPin == 5) || (u32PFPin == 6) || (u32PFPin == 7))
1154     {
1155         u32Offset = u32PFPin - 4;
1156 
1157         RTC->GPIOCTL0 = (RTC->GPIOCTL0 & ~(0x4UL << (u32Offset * 8))) |
1158                         (u32OutputLevel << ((u32Offset * 8) + 2));
1159     }
1160 
1161     if((u32PFPin == 8) || (u32PFPin == 9) || (u32PFPin == 10) || (u32PFPin == 11))
1162     {
1163         u32Offset = u32PFPin - 8;
1164 
1165         RTC->GPIOCTL1 = (RTC->GPIOCTL1 & ~(0x4UL << (u32Offset * 8))) |
1166                         (u32OutputLevel << ((u32Offset * 8) + 2));
1167     }
1168 }
1169 
1170 /**@}*/ /* end of group RTC_EXPORTED_FUNCTIONS */
1171 
1172 /**@}*/ /* end of group RTC_Driver */
1173 
1174 /**@}*/ /* end of group Standard_Driver */
1175