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