1 /**
2   ******************************************************************************
3   * @file    lib_rtc.c
4   * @author  Application Team
5   * @version V1.1.0
6   * @date    2019-10-28
7   * @brief   RTC library.
8   ******************************************************************************
9   * @attention
10   *
11   ******************************************************************************
12   */
13 #include "lib_rtc.h"
14 
15 #define RTCPWD_KEY    0x5AA55AA5
16 #define RTCCE_SETKEY  0xA55AA55B
17 #define RTCCE_CLRKEY  0xA55AA55A
18 
19 /**
20   * @brief  Enables or disables RTC registers write protection.
21   * @param  NewState:
22   *             ENABLE
23   *             DISABLE
24   * @retval None
25   */
RTC_WriteProtection(uint32_t NewState)26 void RTC_WriteProtection(uint32_t NewState)
27 {
28   /* Check parameters */
29   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
30 
31   /* Enable RTC Write-Protection */
32   if (NewState != DISABLE)
33   {
34     RTC->PWD = RTCPWD_KEY;
35     RTC->CE = RTCCE_CLRKEY;
36   }
37   /* Disable RTC Write-Protection */
38   else
39   {
40     RTC->PWD = RTCPWD_KEY;
41     RTC->CE = RTCCE_SETKEY;
42   }
43 }
44 
45 /**
46   * @brief  Waits until the RTC registers (be W/R protected) are synchronized
47   *         with RTC APB clock.
48   * @note   The RTC Resynchronization mode is write protected, use the
49   *         RTC_WriteProtection(DISABLE) before calling this function.
50   *           Write-Operation process as follows:
51   *             1. RTC_WriteProtection(DISABLE);
52   *             2. RTC Registers write operation(only first write-operation be
53   *                valid on the same register).
54   *             3. RTC_WriteProtection(ENABLE);
55   *             4. RTC_WaitForSynchro();  Wait until the RTC registers be
56   *                synchronized by calling this function.
57   * @retval None
58   */
RTC_WaitForSynchro(void)59 void RTC_WaitForSynchro(void)
60 {
61   while (RTC->CE & RTC_CE_BSY)
62   {
63   }
64 }
65 
66 /**
67   * @brief      Writes RTC registers(continuous/be write-protected).
68   * @param[in]  StartAddr   the start address of registers be written
69   * @param[in]  wBuffer     pointer to write
70   * @param[in]  Len         number of registers be written
71   * @retval     None
72   */
RTC_WriteRegisters(uint32_t StartAddr,const uint32_t * wBuffer,uint8_t Len)73 void RTC_WriteRegisters(uint32_t StartAddr, const uint32_t *wBuffer, uint8_t Len)
74 {
75   uint8_t cnt;
76 
77   /* Parameter check */
78   assert_parameters(IS_RTC_REGOP_STARTADDR(StartAddr));
79 
80   /* Wait until the RTC registers be synchronized */
81   RTC_WaitForSynchro();
82 
83   /* Disable RTC Registers write-protection */
84   RTC_WriteProtection(DISABLE);
85 
86   /* Write registers */
87   for (cnt=0; cnt<Len; cnt++)
88   {
89     *(volatile uint32_t *)(StartAddr) = *(wBuffer++);
90     StartAddr += 4;
91   }
92 
93   /* Enable RTC Registers write-protection */
94   RTC_WriteProtection(ENABLE);
95   /* Wait until the RTC registers be synchronized */
96   RTC_WaitForSynchro();
97 }
98 
99 /**
100   * @brief      Reads RTC registers(continuous/be read-protected).
101   * @param[in]  StartAddr   the start address of registers be read
102   * @param[out] rBuffer     pointer to read
103   * @param[in]  Len         number of registers be read
104   * @retval     None
105   */
RTC_ReadRegisters(uint32_t StartAddr,uint32_t * rBuffer,uint8_t Len)106 void RTC_ReadRegisters(uint32_t StartAddr, uint32_t *rBuffer, uint8_t Len)
107 {
108   __IO uint32_t tmp;
109   uint8_t cnt;
110 
111   /* Parameter check */
112   assert_parameters(IS_RTC_REGOP_STARTADDR(StartAddr));
113 
114   /* Wait until the RTC registers be synchronized */
115   RTC_WaitForSynchro();
116 
117   /* Dummy read-operation to RTC->LOAD */
118   tmp = RTC->LOAD;
119   tmp += 1;
120   /* Wait until the RTC registers be synchronized */
121   RTC_WaitForSynchro();
122 
123   /* Read registers */
124   for (cnt=0; cnt<Len; cnt++)
125   {
126     *(rBuffer++) = *(volatile uint32_t *)(StartAddr);
127     StartAddr += 4;
128   }
129 }
130 
131 /**
132   * @brief  Sets RTC current time.
133   * @param  sTime: Pointer to Time structure
134   *         AccurateSel:
135   *             RTC_ACCURATE
136   *             RTC_INACCURATE
137   * @retval None
138   */
RTC_SetTime(RTC_TimeTypeDef * sTime,uint32_t AccurateSel)139 void RTC_SetTime(RTC_TimeTypeDef *sTime, uint32_t AccurateSel)
140 {
141   uint32_t subsec,sec,alarmctl;
142 
143   /* Parameter check */
144   assert_parameters(IS_RTC_TIME_YEAR(sTime->Year));
145   assert_parameters(IS_RTC_TIME_MONTH(sTime->Month));
146   assert_parameters(IS_RTC_TIME_DATE(sTime->Date));
147   assert_parameters(IS_RTC_TIME_WEEKDAY(sTime->WeekDay));
148   assert_parameters(IS_RTC_TIME_HOURS(sTime->Hours));
149   assert_parameters(IS_RTC_TIME_MINS(sTime->Minutes));
150   assert_parameters(IS_RTC_TIME_SECS(sTime->Seconds));
151   if (AccurateSel == RTC_ACCURATE)
152     assert_parameters(IS_RTC_TIME_SubSECS(sTime->SubSeconds));
153   assert_parameters(IS_RTC_ACCURATESEL(AccurateSel));
154 
155   subsec = sTime->SubSeconds;
156   subsec = subsec -(subsec>>8)*156 -((subsec&0xFF)>>4)*6;
157   sec = sTime->Seconds;
158   sec = sec - (sec>>4)*6;
159   subsec = sec * 32768 + subsec * 32768 / 1000;
160 
161   alarmctl = RTC->ALARMCTL;
162   if (AccurateSel == RTC_ACCURATE)
163     alarmctl |= RTC_ALARMCTL_TIME_CNT_EN;
164   else
165     alarmctl &= ~RTC_ALARMCTL_TIME_CNT_EN;
166 
167   /* Wait until the RTC registers be synchronized */
168   RTC_WaitForSynchro();
169   /* Disable RTC Registers write-protection */
170   RTC_WriteProtection(DISABLE);
171 
172   /* Write RTC time registers */
173   RTC->TIME = subsec;
174   RTC->SEC  = sTime->Seconds;
175   RTC->MIN  = sTime->Minutes;
176   RTC->HOUR = sTime->Hours;
177   RTC->DAY  = sTime->Date;
178   RTC->WEEK = sTime->WeekDay;
179   RTC->MON  = sTime->Month;
180   RTC->YEAR = sTime->Year;
181   RTC->ALARMCTL = alarmctl;
182 
183   /* Enable RTC Registers write-protection */
184   RTC_WriteProtection(ENABLE);
185   /* Wait until the RTC registers be synchronized */
186   RTC_WaitForSynchro();
187 }
188 
189 /**
190   * @brief  Gets RTC current time.
191   * @param[out]  gTime: Pointer to Time structure
192   * @param[in]  AccurateSel:
193   *                 RTC_ACCURATE
194   *                 RTC_INACCURATE
195   * @retval None
196 */
RTC_GetTime(RTC_TimeTypeDef * gTime,uint32_t AccurateSel)197 void RTC_GetTime(RTC_TimeTypeDef *gTime, uint32_t AccurateSel)
198 {
199   __IO uint32_t dummy_data = 0;
200   uint32_t subsec,sec;
201 
202   /* Parameter check */
203   assert_parameters(IS_RTC_ACCURATESEL(AccurateSel));
204   /* Wait until the RTC registers be synchronized */
205   RTC_WaitForSynchro();
206 
207   /* Dummy read-operation to RTC->LOAD register */
208   dummy_data = RTC->LOAD;
209   dummy_data += 1;
210   /* Wait until the RTC registers be synchronized */
211   RTC_WaitForSynchro();
212 
213   /* Read RTC time registers */
214   gTime->Seconds  = RTC->SEC;
215   gTime->Minutes  = RTC->MIN;
216   gTime->Hours    = RTC->HOUR;
217   gTime->Date     = RTC->DAY;
218   gTime->WeekDay  = RTC->WEEK;
219   gTime->Month    = RTC->MON;
220   gTime->Year     = RTC->YEAR;
221   subsec          = RTC->TIME;
222 
223   if (AccurateSel == RTC_ACCURATE)
224   {
225     sec = subsec/32768;
226     sec = sec + (sec/10)*6;
227     gTime->Seconds = sec;
228     subsec = (subsec%32768)*1000/32768;
229     subsec = subsec + ((subsec%100)/10)*6 + (subsec/100)*156;
230     gTime->SubSeconds = subsec;
231   }
232   else
233   {
234     gTime->SubSeconds = 0;
235   }
236 }
237 
238 /**
239   * @brief  Enables or disables the RTC Sub Seconds.
240   * @param  NewState:
241   *             ENABLE
242   *             DISABLE
243   * @retval None
244   */
RTC_SubSecondCmd(uint32_t NewState)245 void RTC_SubSecondCmd(uint32_t NewState)
246 {
247   uint32_t tmp;
248 
249   /* Parameter check */
250   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
251 
252   tmp = RTC->ALARMCTL;
253   if (NewState == ENABLE)
254   {
255     tmp |= RTC_ALARMCTL_TIME_CNT_EN;
256   }
257   else
258   {
259     tmp &= ~RTC_ALARMCTL_TIME_CNT_EN;
260   }
261 
262   /* Wait until the RTC registers be synchronized */
263   RTC_WaitForSynchro();
264   /* Disable RTC Registers write-protection */
265   RTC_WriteProtection(DISABLE);
266 
267   RTC->ALARMCTL = tmp;
268 
269   /* Enable RTC Registers write-protection */
270   RTC_WriteProtection(ENABLE);
271   /* Wait until the RTC registers be synchronized */
272   RTC_WaitForSynchro();
273 }
274 
275 /**
276   * @brief  Sets the RTC Alarm.
277   * @param  RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that
278   *                          contains the alarm configuration parameters.
279   *         AccurateSel:
280   *             RTC_ACCURATE
281   *             RTC_INACCURATE
282   * @retval None
283   */
RTC_SetAlarm(RTC_AlarmTypeDef * RTC_AlarmStruct,uint32_t AccurateSel)284 void RTC_SetAlarm(RTC_AlarmTypeDef *RTC_AlarmStruct, uint32_t AccurateSel)
285 {
286   uint32_t subsec,sec,alarmctl;
287   /* Parameter check */
288   assert_parameters(IS_RTC_TIME_HOURS(RTC_AlarmStruct->AlarmHours));
289   assert_parameters(IS_RTC_TIME_MINS(RTC_AlarmStruct->AlarmMinutes));
290   assert_parameters(IS_RTC_TIME_SECS(RTC_AlarmStruct->AlarmSeconds));
291   if (AccurateSel == RTC_ACCURATE)
292     assert_parameters(IS_RTC_TIME_SubSECS(RTC_AlarmStruct->AlarmSubSeconds));
293   assert_parameters(IS_RTC_ACCURATESEL(AccurateSel));
294 
295   subsec = RTC_AlarmStruct->AlarmSubSeconds;
296   subsec = subsec -(subsec>>8)*156 -((subsec&0xFF)>>4)*6;
297   sec = RTC_AlarmStruct->AlarmSeconds;
298   sec = sec - (sec>>4)*6;
299   subsec = sec * 32768 + subsec * 32768 / 1000;
300 
301   alarmctl = RTC->ALARMCTL;
302   if (AccurateSel == RTC_ACCURATE)
303     alarmctl &= ~RTC_ALARMCTL_ALARM_INACCURATE;
304   else
305     alarmctl |= RTC_ALARMCTL_ALARM_INACCURATE;
306 
307   /* Wait until the RTC registers be synchronized */
308   RTC_WaitForSynchro();
309   /* Disable RTC Registers write-protection */
310   RTC_WriteProtection(DISABLE);
311 
312   RTC->ALARMHOUR = RTC_AlarmStruct->AlarmHours;
313   RTC->ALARMMIN = RTC_AlarmStruct->AlarmMinutes;
314   RTC->ALARMSEC = RTC_AlarmStruct->AlarmSeconds;
315   RTC->ALARMTIME = subsec;
316   RTC->ALARMCTL = alarmctl;
317   /* Write RTC time registers */
318 
319   /* Enable RTC Registers write-protection */
320   RTC_WriteProtection(ENABLE);
321   /* Wait until the RTC registers be synchronized */
322   RTC_WaitForSynchro();
323 }
324 
325 /**
326   * @brief  Gets the RTC Alarm.
327   * @param[out]  RTC_AlarmStruct: pointer to a RTC_AlarmTypeDef structure that will
328   *                          contains the output alarm configuration values.
329   * @param[in]  AccurateSel:
330   *                 RTC_ACCURATE
331   *                 RTC_INACCURATE
332   * @retval None
333   */
RTC_GetAlarm(RTC_AlarmTypeDef * RTC_AlarmStruct,uint32_t AccurateSel)334 void RTC_GetAlarm(RTC_AlarmTypeDef *RTC_AlarmStruct, uint32_t AccurateSel)
335 {
336   uint32_t sec,subsec;
337 
338   /* Parameter check */
339   assert_parameters(IS_RTC_ACCURATESEL(AccurateSel));
340 
341   /* Wait until the RTC registers be synchronized */
342   RTC_WaitForSynchro();
343 
344   /* Read RTC time registers */
345   RTC_AlarmStruct->AlarmHours = RTC->ALARMHOUR;
346   RTC_AlarmStruct->AlarmMinutes = RTC->ALARMMIN;
347   RTC_AlarmStruct->AlarmSeconds = RTC->ALARMSEC;
348   subsec = RTC->ALARMTIME;
349 
350   if (AccurateSel == RTC_ACCURATE)
351   {
352     sec = subsec/32768;
353     sec = sec + (sec/10)*6;
354     RTC_AlarmStruct->AlarmSeconds = sec;
355     subsec = (subsec%32768)*1000/32768;
356     subsec = subsec + ((subsec%100)/10)*6 + (subsec/100)*156;
357     RTC_AlarmStruct->AlarmSubSeconds = subsec;
358   }
359   else
360   {
361     RTC_AlarmStruct->AlarmSubSeconds = 0;
362   }
363 }
364 
365 /**
366   * @brief  Enables or disables the RTC Alarm.
367   * @param  NewState:
368   *             ENABLE
369   *             DISABLE
370   * @retval None
371   */
RTC_AlarmCmd(uint32_t NewState)372 void RTC_AlarmCmd(uint32_t NewState)
373 {
374   uint32_t tmp;
375   /* Parameter check */
376   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
377 
378   tmp = RTC->ALARMCTL;
379   if (NewState == ENABLE)
380   {
381     tmp |= (RTC_ALARMCTL_ALARM_EN);
382   }
383   else
384   {
385     tmp &= ~(RTC_ALARMCTL_ALARM_EN);
386   }
387 
388   /* Wait until the RTC registers be synchronized */
389   RTC_WaitForSynchro();
390   /* Disable RTC Registers write-protection */
391   RTC_WriteProtection(DISABLE);
392 
393   RTC->ALARMCTL = tmp;
394 
395   /* Enable RTC Registers write-protection */
396   RTC_WriteProtection(ENABLE);
397   /* Wait until the RTC registers be synchronized */
398   RTC_WaitForSynchro();
399 }
400 
401 /**
402   * @brief  Enables or disables the RTC alarm accurate.
403   * @param  NewState:
404   *             ENABLE
405   *             DISABLE
406   * @retval None
407   */
RTC_AlarmAccurateCmd(uint32_t NewState)408 void RTC_AlarmAccurateCmd(uint32_t NewState)
409 {
410   uint32_t tmp = 0;
411   /* Parameter check */
412   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
413 
414   tmp = RTC->ALARMCTL;
415   if (NewState == ENABLE)
416   {
417     tmp &= ~RTC_ALARMCTL_ALARM_INACCURATE;
418   }
419   else
420   {
421     tmp |= RTC_ALARMCTL_ALARM_INACCURATE;
422   }
423 
424   /* Wait until the RTC registers be synchronized */
425   RTC_WaitForSynchro();
426   /* Disable RTC Registers write-protection */
427   RTC_WriteProtection(DISABLE);
428 
429   RTC->ALARMCTL = tmp;
430 
431   /* Enable RTC Registers write-protection */
432   RTC_WriteProtection(ENABLE);
433   /* Wait until the RTC registers be synchronized */
434   RTC_WaitForSynchro();
435 }
436 
437 /**
438   * @brief  Enables or disables RTC interrupt.
439   * @param  INTMask: can use the '|' operator
440                 RTC_INT_ALARM
441                 RTC_INT_CEILLE
442                 RTC_INT_ACDONE
443                 RTC_INT_WKUCNT
444                 RTC_INT_MIDNIGHT
445                 RTC_INT_WKUHOUR
446                 RTC_INT_WKUMIN
447                 RTC_INT_WKUSEC
448                 RTC_INT_TIMEILLE
449                 RTC_INT_ITVSITV
450             NewState:
451                 ENABLE
452                 DISABLE
453   * @retval None
454   */
RTC_INTConfig(uint32_t INTMask,uint32_t NewState)455 void RTC_INTConfig(uint32_t INTMask, uint32_t NewState)
456 {
457   /* Parameter check */
458   assert_parameters(IS_RTC_INT(INTMask));
459   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
460 
461   if (NewState == ENABLE)
462     RTC->INTEN |= INTMask;
463   else
464     RTC->INTEN &= ~INTMask;
465 }
466 
467 /**
468   * @brief  Gets RTC interrupt status.
469   * @param  INTMask:
470                 RTC_INTSTS_ALARM
471                 RTC_INTSTS_CEILLE
472                 RTC_INTSTS_WKUCNT
473                 RTC_INTSTS_MIDNIGHT
474                 RTC_INTSTS_WKUHOUR
475                 RTC_INTSTS_WKUMIN
476                 RTC_INTSTS_WKUSEC
477                 RTC_INTSTS_TIMEILLE
478                 RTC_INTSTS_ITVSITV
479     * @retval 1: status set
480               0: status reset.
481   */
RTC_GetINTStatus(uint32_t FlagMask)482 uint8_t RTC_GetINTStatus(uint32_t FlagMask)
483 {
484   /* Parameter check */
485   assert_parameters(IS_RTC_INTFLAGR(FlagMask));
486 
487   if (RTC->INTSTS&FlagMask)
488   {
489     return 1;
490   }
491   else
492   {
493     return 0;
494   }
495 }
496 
497 /**
498   * @brief  Clears RTC interrupt status.
499   * @param  INTMask: can use the '|' operator
500                 RTC_INTSTS_ALARM
501                 RTC_INTSTS_CEILLE
502                 RTC_INTSTS_WKUCNT
503                 RTC_INTSTS_MIDNIGHT
504                 RTC_INTSTS_WKUHOUR
505                 RTC_INTSTS_WKUMIN
506                 RTC_INTSTS_WKUSEC
507                 RTC_INTSTS_TIMEILLE
508                 RTC_INTSTS_ITVSITV
509   * @retval  None
510   */
RTC_ClearINTStatus(uint32_t FlagMask)511 void RTC_ClearINTStatus(uint32_t FlagMask)
512 {
513   /* Parameter check */
514   assert_parameters(IS_RTC_INTFLAGC(FlagMask));
515 
516   RTC->INTSTS = FlagMask;
517 }
518 
519 /*
520   * @brief  Configures Multi-second wake up function.
521   * @param  nPeriod��N seconds interval.
522   * @note   For the first interrupt generated by calling this function, it may
523   *         have < 1 sec error if the new WKUSEC number(parameter) is not equal
524   *         to current WKUSEC number.  If the new WKUSEC is equal to current WKUSEC,
525   *         the first interrupt time may have 0~(WKUSEC +1) variation.
526   *         To avoid this problem, set an alternative parameter (like 1) by calling
527   *         this function, then set the correct parameter to it.
528   * @retval None
529   */
RTC_WKUSecondsConfig(uint8_t nPeriod)530 void RTC_WKUSecondsConfig(uint8_t nPeriod)
531 {
532   /* Parameter check */
533   assert_parameters(IS_RTC_WKUSEC_PERIOD(nPeriod));
534 
535   /* Wait until the RTC registers be synchronized */
536   RTC_WaitForSynchro();
537   /* Disable RTC Registers write-protection */
538   RTC_WriteProtection(DISABLE);
539 
540   /* Write registers */
541   RTC->WKUSEC = nPeriod - 1;
542 
543   /* Enable RTC Registers write-protection */
544   RTC_WriteProtection(ENABLE);
545   /* Wait until the RTC registers be synchronized */
546   RTC_WaitForSynchro();
547 }
548 
549 /*
550   * @brief  Configures Multi-minute wake up function.
551   * @param  nPeriod��N minute interval.
552   * @note   For the first interrupt generated by calling this function, it may
553   *         have < 1 min error if the new WKUMIN number(parameter) is not equal
554   *         to current WKUMIN number.  If the new WKUMIN is equal to current WKUMIN,
555   *         the first interrupt time may have 0~(WKUMIN +1) variation.
556   *         To avoid this problem, set an alternative parameter (like 1) by calling
557   *         this function, then set the correct parameter to it.
558   * @retval None
559   */
RTC_WKUMinutesConfig(uint8_t nPeriod)560 void RTC_WKUMinutesConfig(uint8_t nPeriod)
561 {
562   /* Parameter check */
563   assert_parameters(IS_RTC_WKUMIN_PERIOD(nPeriod));
564 
565   /* Wait until the RTC registers be synchronized */
566   RTC_WaitForSynchro();
567   /* Disable RTC Registers write-protection */
568   RTC_WriteProtection(DISABLE);
569 
570   /* Write registers */
571   RTC->WKUMIN = nPeriod - 1;
572 
573   /* Enable RTC Registers write-protection */
574   RTC_WriteProtection(ENABLE);
575   /* Wait until the RTC registers be synchronized */
576   RTC_WaitForSynchro();
577 }
578 
579 /*
580   * @brief  Configures Multi-hour wake up function.
581   * @param  nPeriod��N hour interval.
582   * @note   For the first interrupt generated by calling this function, it may
583   *         have < 1 hour error if the new WKUHOUR number(parameter) is not equal
584   *         to current WKUHOUR number.  If the new WKUHOUR is equal to current WKUHOUR,
585   *         the first interrupt time may have 0~(WKUHOUR +1) variation.
586   *         To avoid this problem, set an alternative parameter (like 1) by calling
587   *         this function, then set the correct parameter to it.
588   * @retval None
589   */
RTC_WKUHoursConfig(uint8_t nPeriod)590 void RTC_WKUHoursConfig(uint8_t nPeriod)
591 {
592   /* Parameter check */
593   assert_parameters(IS_RTC_WKUHOUR_PERIOD(nPeriod));
594 
595   /* Wait until the RTC registers be synchronized */
596   RTC_WaitForSynchro();
597   /* Disable RTC Registers write-protection */
598   RTC_WriteProtection(DISABLE);
599 
600   /* Write registers */
601   RTC->WKUHOUR = nPeriod - 1;
602 
603   /* Enable RTC Registers write-protection */
604   RTC_WriteProtection(ENABLE);
605   /* Wait until the RTC registers be synchronized */
606   RTC_WaitForSynchro();
607 }
608 
609 /**
610   * @brief  Configures RTC counter wake up function.
611   * @param  nClock:
612             CNTCLK:
613                 RTC_WKUCNT_RTCCLK
614                 RTC_WKUCNT_2048
615                 RTC_WKUCNT_512
616                 RTC_WKUCNT_128
617   * @retval None
618   */
RTC_WKUCounterConfig(uint32_t nClock,uint32_t CNTCLK)619 void RTC_WKUCounterConfig(uint32_t nClock,uint32_t CNTCLK)
620 {
621   /* Parameter check */
622   assert_parameters(IS_RTC_WKUCNT_PERIOD(nClock));
623   assert_parameters(IS_RTC_WKUCNT_CNTSEL(CNTCLK));
624 
625   /* Wait until the RTC registers be synchronized */
626   RTC_WaitForSynchro();
627   /* Disable RTC Registers write-protection */
628   RTC_WriteProtection(DISABLE);
629 
630   /* Write registers */
631   RTC->WKUCNT = (CNTCLK & RTC_WKUCNT_CNTSEL) | ((nClock & RTC_WKUCNT_WKUCNT) -1 );
632 
633   /* Enable RTC Registers write-protection */
634   RTC_WriteProtection(ENABLE);
635   /* Wait until the RTC registers be synchronized */
636   RTC_WaitForSynchro();
637 }
638 
639 /**
640   * @brief  Configures RTC ITV wake up function.
641   * @param  nType:
642               RTC_ITV_SEC
643               RTC_ITV_MIN
644               RTC_ITV_HOUR
645               RTC_ITV_DAY
646               RTC_ITV_500MS
647               RTC_ITV_250MS
648               RTC_ITV_125MS
649               RTC_ITV_62MS
650   * @retval None
651   */
RTC_WAKE_ITV(uint8_t nType)652 void RTC_WAKE_ITV(uint8_t nType)
653 {
654   /* Parameter check */
655   assert_parameters(IS_RTC_ITV(nType));
656 
657   /* Wait until the RTC registers be synchronized */
658   RTC_WaitForSynchro();
659   /* Disable RTC Registers write-protection */
660   RTC_WriteProtection(DISABLE);
661 
662   RTC->ITV = nType;
663   RTC->SITV = 0;
664 
665   /* Enable RTC Registers write-protection */
666   RTC_WriteProtection(ENABLE);
667   /* Wait until the RTC registers be synchronized */
668   RTC_WaitForSynchro();
669 }
670 
671 /**
672   * @brief  Configures RTC SITV wake up function.
673   * @param  nPeriod:1~63
674   * @retval None
675   */
RTC_WAKE_SITV(uint8_t nPeriod)676 void RTC_WAKE_SITV(uint8_t nPeriod)
677 {
678   /* Parameter check */
679   assert_parameters(IS_RTC_SITV(nPeriod));
680 
681   /* Wait until the RTC registers be synchronized */
682   RTC_WaitForSynchro();
683   /* Disable RTC Registers write-protection */
684   RTC_WriteProtection(DISABLE);
685 
686   RTC->ITV = RTC_ITV_SITVSEC;
687   RTC->SITV = RTC_SITV_SITVEN | (nPeriod - 1);
688 
689   /* Enable RTC Registers write-protection */
690   RTC_WriteProtection(ENABLE);
691   /* Wait until the RTC registers be synchronized */
692   RTC_WaitForSynchro();
693 }
694 
695 /**
696   * @brief  Gets RTC wake-up counter value.
697   * @retval RTC wake-up counter value
698   */
RTC_GetWKUCounterValue(void)699 uint32_t RTC_GetWKUCounterValue(void)
700 {
701   return RTC->WKUCNTR;
702 }
703 
704 /**
705   * @brief      Configures RTC clock prescaler.
706   * @param[in]  Prescaler:
707   *                     RTC_CLKDIV_1
708   *                     RTC_CLKDIV_4
709   * @retval     None
710   */
RTC_PrescalerConfig(uint32_t Prescaler)711 void RTC_PrescalerConfig(uint32_t Prescaler)
712 {
713   uint32_t tmp;
714 
715   /* Parameter check */
716   assert_parameters(IS_RTC_CLKDIV(Prescaler));
717 
718   tmp = RTC->PSCA;
719   tmp &= ~RTC_PSCA_PSCA;
720   tmp |= Prescaler;
721 
722   /* Wait until the RTC registers be synchronized */
723   RTC_WaitForSynchro();
724   /* Disable RTC Registers write-protection */
725   RTC_WriteProtection(DISABLE);
726 
727   RTC->PSCA = tmp;
728 
729   /* Enable RTC Registers write-protection */
730   RTC_WriteProtection(ENABLE);
731   /* Wait until the RTC registers be synchronized */
732   RTC_WaitForSynchro();
733 }
734 
735 /**
736   * @brief  Configures RTC PLLDIV clock-source and frequency.
737   * @param  Source:
738                 RTC_PLLDIVSOURCE_PLLL
739                 RTC_PLLDIVSOURCE_PCLK
740             nfrequency(HZ): the frequency of RTC PLLDIV output configuration.
741   * @note   Ensure clocks be configured by calling function CLK_ClockConfig(),
742   *         get correct PCLK frequency by calling function CLK_GetPCLKFreq().
743   * @retval None
744   */
RTC_PLLDIVConfig(uint32_t DIVSource,uint32_t nfrequency)745 void RTC_PLLDIVConfig(uint32_t DIVSource,uint32_t nfrequency)
746 {
747   /* Parameter check */
748   assert_parameters(IS_RTC_PLLDIVSOURCE(DIVSource));
749 
750   if (DIVSource == RTC_PLLDIVSOURCE_PLLL)
751   {
752     RTC->CTL |= RTC_CTL_RTCPLLCLKSEL;
753     if (nfrequency == 0)
754     {
755       RTC->DIV = RTC_DIV_RTCDIV;
756     }
757     else
758     {
759       RTC->DIV = CLK_GetPLLLFreq()/2/nfrequency - 1;
760     }
761   }
762   else
763   {
764     RTC->CTL &= ~RTC_CTL_RTCPLLCLKSEL;
765     if (nfrequency == 0)
766     {
767       RTC->DIV = RTC_DIV_RTCDIV;
768     }
769     else
770     {
771       RTC->DIV = CLK_GetPLLLFreq()/2/nfrequency - 1;
772     }
773   }
774 }
775 
776 /**
777   * @brief  Enables or disables RTC PLLDIV output function.
778   * @param  NewState:
779   *             ENABLE
780   *             DISABLE
781   * @retval None
782   */
RTC_PLLDIVOutputCmd(uint8_t NewState)783 void RTC_PLLDIVOutputCmd(uint8_t NewState)
784 {
785   /* Parameter check */
786   assert_parameters(IS_FUNCTIONAL_STATE(NewState));
787 
788   if (NewState == ENABLE)   RTC->CTL |= RTC_CTL_RTCPLLOE;
789   else                      RTC->CTL &= ~RTC_CTL_RTCPLLOE;
790 }
791 
792 
793 /*********************************** END OF FILE ******************************/
794