1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_ll_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2016 STMicroelectronics.
10   * All rights reserved.
11   *
12   * This software is licensed under terms that can be found in the LICENSE file
13   * in the root directory of this software component.
14   * If no LICENSE file comes with this software, it is provided AS-IS.
15   *
16   ******************************************************************************
17   */
18 #if defined(USE_FULL_LL_DRIVER)
19 
20 /* Includes ------------------------------------------------------------------*/
21 #include "stm32l1xx_ll_rtc.h"
22 #include "stm32l1xx_ll_cortex.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif
28 
29 /** @addtogroup STM32L1xx_LL_Driver
30   * @{
31   */
32 
33 #if defined(RTC)
34 
35 /** @addtogroup RTC_LL
36   * @{
37   */
38 
39 /* Private types -------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private constants ---------------------------------------------------------*/
42 /** @addtogroup RTC_LL_Private_Constants
43   * @{
44   */
45 /* Default values used for prescaler */
46 #define RTC_ASYNCH_PRESC_DEFAULT     0x0000007FU
47 #define RTC_SYNCH_PRESC_DEFAULT      0x000000FFU
48 
49 /* Values used for timeout */
50 #define RTC_INITMODE_TIMEOUT         1000U /* 1s when tick set to 1ms */
51 #define RTC_SYNCHRO_TIMEOUT          1000U /* 1s when tick set to 1ms */
52 /**
53   * @}
54   */
55 
56 /* Private macros ------------------------------------------------------------*/
57 /** @addtogroup RTC_LL_Private_Macros
58   * @{
59   */
60 
61 #define IS_LL_RTC_HOURFORMAT(__VALUE__) (((__VALUE__) == LL_RTC_HOURFORMAT_24HOUR) \
62                                       || ((__VALUE__) == LL_RTC_HOURFORMAT_AMPM))
63 
64 #define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__)   ((__VALUE__) <= 0x7FU)
65 
66 #define IS_LL_RTC_SYNCH_PREDIV(__VALUE__)    ((__VALUE__) <= 0x7FFFU)
67 
68 #define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \
69                                   || ((__VALUE__) == LL_RTC_FORMAT_BCD))
70 
71 #define IS_LL_RTC_TIME_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_TIME_FORMAT_AM_OR_24) \
72                                        || ((__VALUE__) == LL_RTC_TIME_FORMAT_PM))
73 
74 #define IS_LL_RTC_HOUR12(__HOUR__)            (((__HOUR__) > 0U) && ((__HOUR__) <= 12U))
75 #define IS_LL_RTC_HOUR24(__HOUR__)            ((__HOUR__) <= 23U)
76 #define IS_LL_RTC_MINUTES(__MINUTES__)        ((__MINUTES__) <= 59U)
77 #define IS_LL_RTC_SECONDS(__SECONDS__)        ((__SECONDS__) <= 59U)
78 
79 #define IS_LL_RTC_WEEKDAY(__VALUE__) (((__VALUE__) == LL_RTC_WEEKDAY_MONDAY) \
80                                    || ((__VALUE__) == LL_RTC_WEEKDAY_TUESDAY) \
81                                    || ((__VALUE__) == LL_RTC_WEEKDAY_WEDNESDAY) \
82                                    || ((__VALUE__) == LL_RTC_WEEKDAY_THURSDAY) \
83                                    || ((__VALUE__) == LL_RTC_WEEKDAY_FRIDAY) \
84                                    || ((__VALUE__) == LL_RTC_WEEKDAY_SATURDAY) \
85                                    || ((__VALUE__) == LL_RTC_WEEKDAY_SUNDAY))
86 
87 #define IS_LL_RTC_DAY(__DAY__)     (((__DAY__) >= 1U) && ((__DAY__) <= 31U))
88 
89 #define IS_LL_RTC_MONTH(__MONTH__) (((__MONTH__) >= 1U) && ((__MONTH__) <= 12U))
90 
91 #define IS_LL_RTC_YEAR(__YEAR__)   ((__YEAR__) <= 99U)
92 
93 #define IS_LL_RTC_ALMA_MASK(__VALUE__) (((__VALUE__) == LL_RTC_ALMA_MASK_NONE) \
94                                      || ((__VALUE__) == LL_RTC_ALMA_MASK_DATEWEEKDAY) \
95                                      || ((__VALUE__) == LL_RTC_ALMA_MASK_HOURS) \
96                                      || ((__VALUE__) == LL_RTC_ALMA_MASK_MINUTES) \
97                                      || ((__VALUE__) == LL_RTC_ALMA_MASK_SECONDS) \
98                                      || ((__VALUE__) == LL_RTC_ALMA_MASK_ALL))
99 
100 #define IS_LL_RTC_ALMB_MASK(__VALUE__) (((__VALUE__) == LL_RTC_ALMB_MASK_NONE) \
101                                      || ((__VALUE__) == LL_RTC_ALMB_MASK_DATEWEEKDAY) \
102                                      || ((__VALUE__) == LL_RTC_ALMB_MASK_HOURS) \
103                                      || ((__VALUE__) == LL_RTC_ALMB_MASK_MINUTES) \
104                                      || ((__VALUE__) == LL_RTC_ALMB_MASK_SECONDS) \
105                                      || ((__VALUE__) == LL_RTC_ALMB_MASK_ALL))
106 
107 #define IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(__SEL__) (((__SEL__) == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE) || \
108                                                   ((__SEL__) == LL_RTC_ALMA_DATEWEEKDAYSEL_WEEKDAY))
109 
110 #define IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(__SEL__) (((__SEL__) == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE) || \
111                                                   ((__SEL__) == LL_RTC_ALMB_DATEWEEKDAYSEL_WEEKDAY))
112 
113 /**
114   * @}
115   */
116 /* Private function prototypes -----------------------------------------------*/
117 /* Exported functions --------------------------------------------------------*/
118 /** @addtogroup RTC_LL_Exported_Functions
119   * @{
120   */
121 
122 /** @addtogroup RTC_LL_EF_Init
123   * @{
124   */
125 
126 /**
127   * @brief  De-Initializes the RTC registers to their default reset values.
128   * @note   This function does not reset the RTC Clock source and RTC Backup Data
129   *         registers.
130   * @param  RTCx RTC Instance
131   * @retval An ErrorStatus enumeration value:
132   *          - SUCCESS: RTC registers are de-initialized
133   *          - ERROR: RTC registers are not de-initialized
134   */
LL_RTC_DeInit(RTC_TypeDef * RTCx)135 ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx)
136 {
137   ErrorStatus status = ERROR;
138 
139   /* Check the parameter */
140   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
141 
142   /* Disable the write protection for RTC registers */
143   LL_RTC_DisableWriteProtection(RTCx);
144 
145   /* Set Initialization mode */
146   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
147   {
148     /* Reset TR, DR and CR registers */
149     LL_RTC_WriteReg(RTCx, TR,       0x00000000U);
150     LL_RTC_WriteReg(RTCx, WUTR,     RTC_WUTR_WUT);
151     LL_RTC_WriteReg(RTCx, DR,      (RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0));
152 
153     /* Reset All CR bits except CR[2:0] */
154     LL_RTC_WriteReg(RTCx, CR, (LL_RTC_ReadReg(RTCx, CR) & RTC_CR_WUCKSEL));
155 
156     LL_RTC_WriteReg(RTCx, PRER,    (RTC_PRER_PREDIV_A | RTC_SYNCH_PRESC_DEFAULT));
157     LL_RTC_WriteReg(RTCx, ALRMAR,   0x00000000U);
158     LL_RTC_WriteReg(RTCx, ALRMBR,   0x00000000U);
159 #if defined(RTC_SMOOTHCALIB_SUPPORT)
160     LL_RTC_WriteReg(RTCx, CALR,     0x00000000U);
161 #endif /* RTC_SMOOTHCALIB_SUPPORT */
162 #if defined(RTC_SUBSECOND_SUPPORT)
163     LL_RTC_WriteReg(RTCx, SHIFTR,   0x00000000U);
164     LL_RTC_WriteReg(RTCx, ALRMASSR, 0x00000000U);
165     LL_RTC_WriteReg(RTCx, ALRMBSSR, 0x00000000U);
166 #endif /* RTC_SUBSECOND_SUPPORT */
167 
168     /* Reset ISR register and exit initialization mode */
169     LL_RTC_WriteReg(RTCx, ISR,      0x00000000U);
170 
171     /* Reset Tamper and alternate functions configuration register */
172     LL_RTC_WriteReg(RTCx, TAFCR, 0x00000000U);
173 
174     /* Wait till the RTC RSF flag is set */
175     status = LL_RTC_WaitForSynchro(RTCx);
176   }
177 
178   /* Enable the write protection for RTC registers */
179   LL_RTC_EnableWriteProtection(RTCx);
180 
181   return status;
182 }
183 
184 /**
185   * @brief  Initializes the RTC registers according to the specified parameters
186   *         in RTC_InitStruct.
187   * @param  RTCx RTC Instance
188   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
189   *         the configuration information for the RTC peripheral.
190   * @note   The RTC Prescaler register is write protected and can be written in
191   *         initialization mode only.
192   * @retval An ErrorStatus enumeration value:
193   *          - SUCCESS: RTC registers are initialized
194   *          - ERROR: RTC registers are not initialized
195   */
LL_RTC_Init(RTC_TypeDef * RTCx,LL_RTC_InitTypeDef * RTC_InitStruct)196 ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
197 {
198   ErrorStatus status = ERROR;
199 
200   /* Check the parameters */
201   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
202   assert_param(IS_LL_RTC_HOURFORMAT(RTC_InitStruct->HourFormat));
203   assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
204   assert_param(IS_LL_RTC_SYNCH_PREDIV(RTC_InitStruct->SynchPrescaler));
205 
206   /* Disable the write protection for RTC registers */
207   LL_RTC_DisableWriteProtection(RTCx);
208 
209   /* Set Initialization mode */
210   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
211   {
212     /* Set Hour Format */
213     LL_RTC_SetHourFormat(RTCx, RTC_InitStruct->HourFormat);
214 
215     /* Configure Synchronous and Asynchronous prescaler factor */
216     LL_RTC_SetSynchPrescaler(RTCx, RTC_InitStruct->SynchPrescaler);
217     LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
218 
219     /* Exit Initialization mode */
220     LL_RTC_DisableInitMode(RTCx);
221 
222     status = SUCCESS;
223   }
224   /* Enable the write protection for RTC registers */
225   LL_RTC_EnableWriteProtection(RTCx);
226 
227   return status;
228 }
229 
230 /**
231   * @brief  Set each @ref LL_RTC_InitTypeDef field to default value.
232   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
233   * @retval None
234   */
LL_RTC_StructInit(LL_RTC_InitTypeDef * RTC_InitStruct)235 void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
236 {
237   /* Set RTC_InitStruct fields to default values */
238   RTC_InitStruct->HourFormat      = LL_RTC_HOURFORMAT_24HOUR;
239   RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
240   RTC_InitStruct->SynchPrescaler  = RTC_SYNCH_PRESC_DEFAULT;
241 }
242 
243 /**
244   * @brief  Set the RTC current time.
245   * @param  RTCx RTC Instance
246   * @param  RTC_Format This parameter can be one of the following values:
247   *         @arg @ref LL_RTC_FORMAT_BIN
248   *         @arg @ref LL_RTC_FORMAT_BCD
249   * @param  RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
250   *                        the time configuration information for the RTC.
251   * @retval An ErrorStatus enumeration value:
252   *          - SUCCESS: RTC Time register is configured
253   *          - ERROR: RTC Time register is not configured
254   */
LL_RTC_TIME_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_TimeTypeDef * RTC_TimeStruct)255 ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
256 {
257   ErrorStatus status = ERROR;
258 
259   /* Check the parameters */
260   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
261   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
262 
263   if (RTC_Format == LL_RTC_FORMAT_BIN)
264   {
265     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
266     {
267       assert_param(IS_LL_RTC_HOUR12(RTC_TimeStruct->Hours));
268       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
269     }
270     else
271     {
272       RTC_TimeStruct->TimeFormat = 0x00U;
273       assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
274     }
275     assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
276     assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
277   }
278   else
279   {
280     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
281     {
282       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
283       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
284     }
285     else
286     {
287       RTC_TimeStruct->TimeFormat = 0x00U;
288       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
289     }
290     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
291     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
292   }
293 
294   /* Disable the write protection for RTC registers */
295   LL_RTC_DisableWriteProtection(RTCx);
296 
297   /* Set Initialization mode */
298   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
299   {
300     /* Check the input parameters format */
301     if (RTC_Format != LL_RTC_FORMAT_BIN)
302     {
303       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, RTC_TimeStruct->Hours,
304                          RTC_TimeStruct->Minutes, RTC_TimeStruct->Seconds);
305     }
306     else
307     {
308       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Hours),
309                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Minutes),
310                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Seconds));
311     }
312 
313     /* Exit Initialization mode */
314     LL_RTC_DisableInitMode(RTCx);
315 
316 #if defined(RTC_CR_BYPSHAD)
317     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
318     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
319     {
320       status = LL_RTC_WaitForSynchro(RTCx);
321     }
322     else
323     {
324       status = SUCCESS;
325     }
326 #else /* RTC_CR_BYPSHAD */
327     status = SUCCESS;
328 #endif /* RTC_CR_BYPSHAD */
329   }
330   /* Enable the write protection for RTC registers */
331   LL_RTC_EnableWriteProtection(RTCx);
332 
333   return status;
334 }
335 
336 /**
337   * @brief  Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
338   * @param  RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
339   * @retval None
340   */
LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef * RTC_TimeStruct)341 void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
342 {
343   /* Time = 00h:00min:00sec */
344   RTC_TimeStruct->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
345   RTC_TimeStruct->Hours      = 0U;
346   RTC_TimeStruct->Minutes    = 0U;
347   RTC_TimeStruct->Seconds    = 0U;
348 }
349 
350 /**
351   * @brief  Set the RTC current date.
352   * @param  RTCx RTC Instance
353   * @param  RTC_Format This parameter can be one of the following values:
354   *         @arg @ref LL_RTC_FORMAT_BIN
355   *         @arg @ref LL_RTC_FORMAT_BCD
356   * @param  RTC_DateStruct pointer to a RTC_DateTypeDef structure that contains
357   *                         the date configuration information for the RTC.
358   * @retval An ErrorStatus enumeration value:
359   *          - SUCCESS: RTC Day register is configured
360   *          - ERROR: RTC Day register is not configured
361   */
LL_RTC_DATE_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_DateTypeDef * RTC_DateStruct)362 ErrorStatus LL_RTC_DATE_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_DateTypeDef *RTC_DateStruct)
363 {
364   ErrorStatus status = ERROR;
365 
366   /* Check the parameters */
367   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
368   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
369 
370   if ((RTC_Format == LL_RTC_FORMAT_BIN) && ((RTC_DateStruct->Month & 0x10U) == 0x10U))
371   {
372     RTC_DateStruct->Month = (uint8_t)(RTC_DateStruct->Month & (uint8_t)~(0x10U)) + 0x0AU;
373   }
374   if (RTC_Format == LL_RTC_FORMAT_BIN)
375   {
376     assert_param(IS_LL_RTC_YEAR(RTC_DateStruct->Year));
377     assert_param(IS_LL_RTC_MONTH(RTC_DateStruct->Month));
378     assert_param(IS_LL_RTC_DAY(RTC_DateStruct->Day));
379   }
380   else
381   {
382     assert_param(IS_LL_RTC_YEAR(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Year)));
383     assert_param(IS_LL_RTC_MONTH(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Month)));
384     assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Day)));
385   }
386   assert_param(IS_LL_RTC_WEEKDAY(RTC_DateStruct->WeekDay));
387 
388   /* Disable the write protection for RTC registers */
389   LL_RTC_DisableWriteProtection(RTCx);
390 
391   /* Set Initialization mode */
392   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
393   {
394     /* Check the input parameters format */
395     if (RTC_Format != LL_RTC_FORMAT_BIN)
396     {
397       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, RTC_DateStruct->Day, RTC_DateStruct->Month, RTC_DateStruct->Year);
398     }
399     else
400     {
401       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Day),
402                          __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Month), __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Year));
403     }
404 
405     /* Exit Initialization mode */
406     LL_RTC_DisableInitMode(RTCx);
407 
408 #if defined(RTC_CR_BYPSHAD)
409     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
410     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
411     {
412       status = LL_RTC_WaitForSynchro(RTCx);
413     }
414     else
415     {
416       status = SUCCESS;
417     }
418 #else /* RTC_CR_BYPSHAD */
419     status = SUCCESS;
420 #endif /* RTC_CR_BYPSHAD */
421   }
422   /* Enable the write protection for RTC registers */
423   LL_RTC_EnableWriteProtection(RTCx);
424 
425   return status;
426 }
427 
428 /**
429   * @brief  Set each @ref LL_RTC_DateTypeDef field to default value (date = Monday, January 01 xx00)
430   * @param  RTC_DateStruct pointer to a @ref LL_RTC_DateTypeDef structure which will be initialized.
431   * @retval None
432   */
LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef * RTC_DateStruct)433 void LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef *RTC_DateStruct)
434 {
435   /* Monday, January 01 xx00 */
436   RTC_DateStruct->WeekDay = LL_RTC_WEEKDAY_MONDAY;
437   RTC_DateStruct->Day     = 1U;
438   RTC_DateStruct->Month   = LL_RTC_MONTH_JANUARY;
439   RTC_DateStruct->Year    = 0U;
440 }
441 
442 /**
443   * @brief  Set the RTC Alarm A.
444   * @note   The Alarm register can only be written when the corresponding Alarm
445   *         is disabled (Use @ref LL_RTC_ALMA_Disable function).
446   * @param  RTCx RTC Instance
447   * @param  RTC_Format This parameter can be one of the following values:
448   *         @arg @ref LL_RTC_FORMAT_BIN
449   *         @arg @ref LL_RTC_FORMAT_BCD
450   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
451   *                         contains the alarm configuration parameters.
452   * @retval An ErrorStatus enumeration value:
453   *          - SUCCESS: ALARMA registers are configured
454   *          - ERROR: ALARMA registers are not configured
455   */
LL_RTC_ALMA_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)456 ErrorStatus LL_RTC_ALMA_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
457 {
458   /* Check the parameters */
459   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
460   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
461   assert_param(IS_LL_RTC_ALMA_MASK(RTC_AlarmStruct->AlarmMask));
462   assert_param(IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel));
463 
464   if (RTC_Format == LL_RTC_FORMAT_BIN)
465   {
466     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
467     {
468       assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours));
469       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
470     }
471     else
472     {
473       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
474       assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
475     }
476     assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
477     assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
478 
479     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
480     {
481       assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay));
482     }
483     else
484     {
485       assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay));
486     }
487   }
488   else
489   {
490     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
491     {
492       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
493       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
494     }
495     else
496     {
497       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
498       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
499     }
500 
501     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
502     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
503 
504     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
505     {
506       assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
507     }
508     else
509     {
510       assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
511     }
512   }
513 
514   /* Disable the write protection for RTC registers */
515   LL_RTC_DisableWriteProtection(RTCx);
516 
517   /* Select weekday selection */
518   if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
519   {
520     /* Set the date for ALARM */
521     LL_RTC_ALMA_DisableWeekday(RTCx);
522     if (RTC_Format != LL_RTC_FORMAT_BIN)
523     {
524       LL_RTC_ALMA_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
525     }
526     else
527     {
528       LL_RTC_ALMA_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay));
529     }
530   }
531   else
532   {
533     /* Set the week day for ALARM */
534     LL_RTC_ALMA_EnableWeekday(RTCx);
535     LL_RTC_ALMA_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
536   }
537 
538   /* Configure the Alarm register */
539   if (RTC_Format != LL_RTC_FORMAT_BIN)
540   {
541     LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours,
542                            RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds);
543   }
544   else
545   {
546     LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat,
547                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours),
548                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes),
549                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds));
550   }
551   /* Set ALARM mask */
552   LL_RTC_ALMA_SetMask(RTCx, RTC_AlarmStruct->AlarmMask);
553 
554   /* Enable the write protection for RTC registers */
555   LL_RTC_EnableWriteProtection(RTCx);
556 
557   return SUCCESS;
558 }
559 
560 /**
561   * @brief  Set the RTC Alarm B.
562   * @note   The Alarm register can only be written when the corresponding Alarm
563   *         is disabled (@ref LL_RTC_ALMB_Disable function).
564   * @param  RTCx RTC Instance
565   * @param  RTC_Format This parameter can be one of the following values:
566   *         @arg @ref LL_RTC_FORMAT_BIN
567   *         @arg @ref LL_RTC_FORMAT_BCD
568   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
569   *                         contains the alarm configuration parameters.
570   * @retval An ErrorStatus enumeration value:
571   *          - SUCCESS: ALARMB registers are configured
572   *          - ERROR: ALARMB registers are not configured
573   */
LL_RTC_ALMB_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)574 ErrorStatus LL_RTC_ALMB_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
575 {
576   /* Check the parameters */
577   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
578   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
579   assert_param(IS_LL_RTC_ALMB_MASK(RTC_AlarmStruct->AlarmMask));
580   assert_param(IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel));
581 
582   if (RTC_Format == LL_RTC_FORMAT_BIN)
583   {
584     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
585     {
586       assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours));
587       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
588     }
589     else
590     {
591       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
592       assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
593     }
594     assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
595     assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
596 
597     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
598     {
599       assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay));
600     }
601     else
602     {
603       assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay));
604     }
605   }
606   else
607   {
608     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
609     {
610       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
611       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
612     }
613     else
614     {
615       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
616       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
617     }
618 
619     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
620     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
621 
622     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
623     {
624       assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
625     }
626     else
627     {
628       assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
629     }
630   }
631 
632   /* Disable the write protection for RTC registers */
633   LL_RTC_DisableWriteProtection(RTCx);
634 
635   /* Select weekday selection */
636   if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
637   {
638     /* Set the date for ALARM */
639     LL_RTC_ALMB_DisableWeekday(RTCx);
640     if (RTC_Format != LL_RTC_FORMAT_BIN)
641     {
642       LL_RTC_ALMB_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
643     }
644     else
645     {
646       LL_RTC_ALMB_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay));
647     }
648   }
649   else
650   {
651     /* Set the week day for ALARM */
652     LL_RTC_ALMB_EnableWeekday(RTCx);
653     LL_RTC_ALMB_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
654   }
655 
656   /* Configure the Alarm register */
657   if (RTC_Format != LL_RTC_FORMAT_BIN)
658   {
659     LL_RTC_ALMB_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours,
660                            RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds);
661   }
662   else
663   {
664     LL_RTC_ALMB_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat,
665                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours),
666                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes),
667                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds));
668   }
669   /* Set ALARM mask */
670   LL_RTC_ALMB_SetMask(RTCx, RTC_AlarmStruct->AlarmMask);
671 
672   /* Enable the write protection for RTC registers */
673   LL_RTC_EnableWriteProtection(RTCx);
674 
675   return SUCCESS;
676 }
677 
678 /**
679   * @brief  Set each @ref LL_RTC_AlarmTypeDef of ALARMA field to default value (Time = 00h:00mn:00sec /
680   *         Day = 1st day of the month/Mask = all fields are masked).
681   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
682   * @retval None
683   */
LL_RTC_ALMA_StructInit(LL_RTC_AlarmTypeDef * RTC_AlarmStruct)684 void LL_RTC_ALMA_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
685 {
686   /* Alarm Time Settings : Time = 00h:00mn:00sec */
687   RTC_AlarmStruct->AlarmTime.TimeFormat = LL_RTC_ALMA_TIME_FORMAT_AM;
688   RTC_AlarmStruct->AlarmTime.Hours      = 0U;
689   RTC_AlarmStruct->AlarmTime.Minutes    = 0U;
690   RTC_AlarmStruct->AlarmTime.Seconds    = 0U;
691 
692   /* Alarm Day Settings : Day = 1st day of the month */
693   RTC_AlarmStruct->AlarmDateWeekDaySel = LL_RTC_ALMA_DATEWEEKDAYSEL_DATE;
694   RTC_AlarmStruct->AlarmDateWeekDay    = 1U;
695 
696   /* Alarm Masks Settings : Mask =  all fields are not masked */
697   RTC_AlarmStruct->AlarmMask           = LL_RTC_ALMA_MASK_NONE;
698 }
699 
700 /**
701   * @brief  Set each @ref LL_RTC_AlarmTypeDef of ALARMA field to default value (Time = 00h:00mn:00sec /
702   *         Day = 1st day of the month/Mask = all fields are masked).
703   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
704   * @retval None
705   */
LL_RTC_ALMB_StructInit(LL_RTC_AlarmTypeDef * RTC_AlarmStruct)706 void LL_RTC_ALMB_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
707 {
708   /* Alarm Time Settings : Time = 00h:00mn:00sec */
709   RTC_AlarmStruct->AlarmTime.TimeFormat = LL_RTC_ALMB_TIME_FORMAT_AM;
710   RTC_AlarmStruct->AlarmTime.Hours      = 0U;
711   RTC_AlarmStruct->AlarmTime.Minutes    = 0U;
712   RTC_AlarmStruct->AlarmTime.Seconds    = 0U;
713 
714   /* Alarm Day Settings : Day = 1st day of the month */
715   RTC_AlarmStruct->AlarmDateWeekDaySel = LL_RTC_ALMB_DATEWEEKDAYSEL_DATE;
716   RTC_AlarmStruct->AlarmDateWeekDay    = 1U;
717 
718   /* Alarm Masks Settings : Mask =  all fields are not masked */
719   RTC_AlarmStruct->AlarmMask           = LL_RTC_ALMB_MASK_NONE;
720 }
721 
722 /**
723   * @brief  Enters the RTC Initialization mode.
724   * @note   The RTC Initialization mode is write protected, use the
725   *         @ref LL_RTC_DisableWriteProtection before calling this function.
726   * @param  RTCx RTC Instance
727   * @retval An ErrorStatus enumeration value:
728   *          - SUCCESS: RTC is in Init mode
729   *          - ERROR: RTC is not in Init mode
730   */
LL_RTC_EnterInitMode(RTC_TypeDef * RTCx)731 ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx)
732 {
733   __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
734   ErrorStatus status = SUCCESS;
735   uint32_t tmp = 0U;
736 
737   /* Check the parameter */
738   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
739 
740   /* Check if the Initialization mode is set */
741   if (LL_RTC_IsActiveFlag_INIT(RTCx) == 0U)
742   {
743     /* Set the Initialization mode */
744     LL_RTC_EnableInitMode(RTCx);
745 
746     /* Wait till RTC is in INIT state and if Time out is reached exit */
747     tmp = LL_RTC_IsActiveFlag_INIT(RTCx);
748     while ((timeout != 0U) && (tmp != 1U))
749     {
750       if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
751       {
752         timeout --;
753       }
754       tmp = LL_RTC_IsActiveFlag_INIT(RTCx);
755       if (timeout == 0U)
756       {
757         status = ERROR;
758       }
759     }
760   }
761   return status;
762 }
763 
764 /**
765   * @brief  Exit the RTC Initialization mode.
766   * @note   When the initialization sequence is complete, the calendar restarts
767   *         counting after 4 RTCCLK cycles.
768   * @note   The RTC Initialization mode is write protected, use the
769   *         @ref LL_RTC_DisableWriteProtection before calling this function.
770   * @param  RTCx RTC Instance
771   * @retval An ErrorStatus enumeration value:
772   *          - SUCCESS: RTC exited from in Init mode
773   *          - ERROR: Not applicable
774   */
LL_RTC_ExitInitMode(RTC_TypeDef * RTCx)775 ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx)
776 {
777   /* Check the parameter */
778   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
779 
780   /* Disable initialization mode */
781   LL_RTC_DisableInitMode(RTCx);
782 
783   return SUCCESS;
784 }
785 
786 /**
787   * @brief  Waits until the RTC Time and Day registers (RTC_TR and RTC_DR) are
788   *         synchronized with RTC APB clock.
789   * @note   The RTC Resynchronization mode is write protected, use the
790   *         @ref LL_RTC_DisableWriteProtection before calling this function.
791   * @note   To read the calendar through the shadow registers after calendar
792   *         initialization, calendar update or after wakeup from low power modes
793   *         the software must first clear the RSF flag.
794   *         The software must then wait until it is set again before reading
795   *         the calendar, which means that the calendar registers have been
796   *         correctly copied into the RTC_TR and RTC_DR shadow registers.
797   * @param  RTCx RTC Instance
798   * @retval An ErrorStatus enumeration value:
799   *          - SUCCESS: RTC registers are synchronised
800   *          - ERROR: RTC registers are not synchronised
801   */
LL_RTC_WaitForSynchro(RTC_TypeDef * RTCx)802 ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx)
803 {
804   __IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT;
805   ErrorStatus status = SUCCESS;
806   uint32_t tmp = 0U;
807 
808   /* Check the parameter */
809   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
810 
811   /* Clear RSF flag */
812   LL_RTC_ClearFlag_RS(RTCx);
813 
814   /* Wait the registers to be synchronised */
815   tmp = LL_RTC_IsActiveFlag_RS(RTCx);
816   while ((timeout != 0U) && (tmp != 1U))
817   {
818     if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
819     {
820       timeout--;
821     }
822     tmp = LL_RTC_IsActiveFlag_RS(RTCx);
823     if (timeout == 0U)
824     {
825       status = ERROR;
826     }
827   }
828 
829   return (status);
830 }
831 
832 /**
833   * @}
834   */
835 
836 /**
837   * @}
838   */
839 
840 /**
841   * @}
842   */
843 
844 #endif /* defined(RTC) */
845 
846 /**
847   * @}
848   */
849 
850 #endif /* USE_FULL_LL_DRIVER */
851