1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_ll_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2017 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 "stm32f4xx_ll_rtc.h"
22 #include "stm32f4xx_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 STM32F4xx_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     LL_RTC_WriteReg(RTCx, CALR,     0x00000000U);
160     LL_RTC_WriteReg(RTCx, SHIFTR,   0x00000000U);
161     LL_RTC_WriteReg(RTCx, ALRMASSR, 0x00000000U);
162     LL_RTC_WriteReg(RTCx, ALRMBSSR, 0x00000000U);
163 
164     /* Reset ISR register and exit initialization mode */
165     LL_RTC_WriteReg(RTCx, ISR,      0x00000000U);
166 
167     /* Reset Tamper and alternate functions configuration register */
168     LL_RTC_WriteReg(RTCx, TAFCR, 0x00000000U);
169 
170     /* Wait till the RTC RSF flag is set */
171     status = LL_RTC_WaitForSynchro(RTCx);
172   }
173 
174   /* Enable the write protection for RTC registers */
175   LL_RTC_EnableWriteProtection(RTCx);
176 
177   return status;
178 }
179 
180 /**
181   * @brief  Initializes the RTC registers according to the specified parameters
182   *         in RTC_InitStruct.
183   * @param  RTCx RTC Instance
184   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
185   *         the configuration information for the RTC peripheral.
186   * @note   The RTC Prescaler register is write protected and can be written in
187   *         initialization mode only.
188   * @retval An ErrorStatus enumeration value:
189   *          - SUCCESS: RTC registers are initialized
190   *          - ERROR: RTC registers are not initialized
191   */
LL_RTC_Init(RTC_TypeDef * RTCx,LL_RTC_InitTypeDef * RTC_InitStruct)192 ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
193 {
194   ErrorStatus status = ERROR;
195 
196   /* Check the parameters */
197   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
198   assert_param(IS_LL_RTC_HOURFORMAT(RTC_InitStruct->HourFormat));
199   assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
200   assert_param(IS_LL_RTC_SYNCH_PREDIV(RTC_InitStruct->SynchPrescaler));
201 
202   /* Disable the write protection for RTC registers */
203   LL_RTC_DisableWriteProtection(RTCx);
204 
205   /* Set Initialization mode */
206   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
207   {
208     /* Set Hour Format */
209     LL_RTC_SetHourFormat(RTCx, RTC_InitStruct->HourFormat);
210 
211     /* Configure Synchronous and Asynchronous prescaler factor */
212     LL_RTC_SetSynchPrescaler(RTCx, RTC_InitStruct->SynchPrescaler);
213     LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
214 
215     /* Exit Initialization mode */
216     LL_RTC_DisableInitMode(RTCx);
217 
218     status = SUCCESS;
219   }
220   /* Enable the write protection for RTC registers */
221   LL_RTC_EnableWriteProtection(RTCx);
222 
223   return status;
224 }
225 
226 /**
227   * @brief  Set each @ref LL_RTC_InitTypeDef field to default value.
228   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
229   * @retval None
230   */
LL_RTC_StructInit(LL_RTC_InitTypeDef * RTC_InitStruct)231 void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
232 {
233   /* Set RTC_InitStruct fields to default values */
234   RTC_InitStruct->HourFormat      = LL_RTC_HOURFORMAT_24HOUR;
235   RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
236   RTC_InitStruct->SynchPrescaler  = RTC_SYNCH_PRESC_DEFAULT;
237 }
238 
239 /**
240   * @brief  Set the RTC current time.
241   * @param  RTCx RTC Instance
242   * @param  RTC_Format This parameter can be one of the following values:
243   *         @arg @ref LL_RTC_FORMAT_BIN
244   *         @arg @ref LL_RTC_FORMAT_BCD
245   * @param  RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
246   *                        the time configuration information for the RTC.
247   * @retval An ErrorStatus enumeration value:
248   *          - SUCCESS: RTC Time register is configured
249   *          - ERROR: RTC Time register is not configured
250   */
LL_RTC_TIME_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_TimeTypeDef * RTC_TimeStruct)251 ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
252 {
253   ErrorStatus status = ERROR;
254 
255   /* Check the parameters */
256   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
257   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
258 
259   if (RTC_Format == LL_RTC_FORMAT_BIN)
260   {
261     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
262     {
263       assert_param(IS_LL_RTC_HOUR12(RTC_TimeStruct->Hours));
264       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
265     }
266     else
267     {
268       RTC_TimeStruct->TimeFormat = 0x00U;
269       assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
270     }
271     assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
272     assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
273   }
274   else
275   {
276     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
277     {
278       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
279       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
280     }
281     else
282     {
283       RTC_TimeStruct->TimeFormat = 0x00U;
284       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
285     }
286     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
287     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
288   }
289 
290   /* Disable the write protection for RTC registers */
291   LL_RTC_DisableWriteProtection(RTCx);
292 
293   /* Set Initialization mode */
294   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
295   {
296     /* Check the input parameters format */
297     if (RTC_Format != LL_RTC_FORMAT_BIN)
298     {
299       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, RTC_TimeStruct->Hours,
300                          RTC_TimeStruct->Minutes, RTC_TimeStruct->Seconds);
301     }
302     else
303     {
304       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Hours),
305                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Minutes),
306                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Seconds));
307     }
308 
309     /* Exit Initialization mode */
310     LL_RTC_DisableInitMode(RTCx);
311 
312     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
313     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
314     {
315       status = LL_RTC_WaitForSynchro(RTCx);
316     }
317     else
318     {
319       status = SUCCESS;
320     }
321   }
322   /* Enable the write protection for RTC registers */
323   LL_RTC_EnableWriteProtection(RTCx);
324 
325   return status;
326 }
327 
328 /**
329   * @brief  Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
330   * @param  RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
331   * @retval None
332   */
LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef * RTC_TimeStruct)333 void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
334 {
335   /* Time = 00h:00min:00sec */
336   RTC_TimeStruct->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
337   RTC_TimeStruct->Hours      = 0U;
338   RTC_TimeStruct->Minutes    = 0U;
339   RTC_TimeStruct->Seconds    = 0U;
340 }
341 
342 /**
343   * @brief  Set the RTC current date.
344   * @param  RTCx RTC Instance
345   * @param  RTC_Format This parameter can be one of the following values:
346   *         @arg @ref LL_RTC_FORMAT_BIN
347   *         @arg @ref LL_RTC_FORMAT_BCD
348   * @param  RTC_DateStruct pointer to a RTC_DateTypeDef structure that contains
349   *                         the date configuration information for the RTC.
350   * @retval An ErrorStatus enumeration value:
351   *          - SUCCESS: RTC Day register is configured
352   *          - ERROR: RTC Day register is not configured
353   */
LL_RTC_DATE_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_DateTypeDef * RTC_DateStruct)354 ErrorStatus LL_RTC_DATE_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_DateTypeDef *RTC_DateStruct)
355 {
356   ErrorStatus status = ERROR;
357 
358   /* Check the parameters */
359   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
360   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
361 
362   if ((RTC_Format == LL_RTC_FORMAT_BIN) && ((RTC_DateStruct->Month & 0x10U) == 0x10U))
363   {
364     RTC_DateStruct->Month = (uint8_t)(RTC_DateStruct->Month & (uint8_t)~(0x10U)) + 0x0AU;
365   }
366   if (RTC_Format == LL_RTC_FORMAT_BIN)
367   {
368     assert_param(IS_LL_RTC_YEAR(RTC_DateStruct->Year));
369     assert_param(IS_LL_RTC_MONTH(RTC_DateStruct->Month));
370     assert_param(IS_LL_RTC_DAY(RTC_DateStruct->Day));
371   }
372   else
373   {
374     assert_param(IS_LL_RTC_YEAR(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Year)));
375     assert_param(IS_LL_RTC_MONTH(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Month)));
376     assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Day)));
377   }
378   assert_param(IS_LL_RTC_WEEKDAY(RTC_DateStruct->WeekDay));
379 
380   /* Disable the write protection for RTC registers */
381   LL_RTC_DisableWriteProtection(RTCx);
382 
383   /* Set Initialization mode */
384   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
385   {
386     /* Check the input parameters format */
387     if (RTC_Format != LL_RTC_FORMAT_BIN)
388     {
389       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, RTC_DateStruct->Day, RTC_DateStruct->Month, RTC_DateStruct->Year);
390     }
391     else
392     {
393       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Day),
394                          __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Month), __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Year));
395     }
396 
397     /* Exit Initialization mode */
398     LL_RTC_DisableInitMode(RTCx);
399 
400     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
401     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
402     {
403       status = LL_RTC_WaitForSynchro(RTCx);
404     }
405     else
406     {
407       status = SUCCESS;
408     }
409   }
410   /* Enable the write protection for RTC registers */
411   LL_RTC_EnableWriteProtection(RTCx);
412 
413   return status;
414 }
415 
416 /**
417   * @brief  Set each @ref LL_RTC_DateTypeDef field to default value (date = Monday, January 01 xx00)
418   * @param  RTC_DateStruct pointer to a @ref LL_RTC_DateTypeDef structure which will be initialized.
419   * @retval None
420   */
LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef * RTC_DateStruct)421 void LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef *RTC_DateStruct)
422 {
423   /* Monday, January 01 xx00 */
424   RTC_DateStruct->WeekDay = LL_RTC_WEEKDAY_MONDAY;
425   RTC_DateStruct->Day     = 1U;
426   RTC_DateStruct->Month   = LL_RTC_MONTH_JANUARY;
427   RTC_DateStruct->Year    = 0U;
428 }
429 
430 /**
431   * @brief  Set the RTC Alarm A.
432   * @note   The Alarm register can only be written when the corresponding Alarm
433   *         is disabled (Use @ref LL_RTC_ALMA_Disable function).
434   * @param  RTCx RTC Instance
435   * @param  RTC_Format This parameter can be one of the following values:
436   *         @arg @ref LL_RTC_FORMAT_BIN
437   *         @arg @ref LL_RTC_FORMAT_BCD
438   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
439   *                         contains the alarm configuration parameters.
440   * @retval An ErrorStatus enumeration value:
441   *          - SUCCESS: ALARMA registers are configured
442   *          - ERROR: ALARMA registers are not configured
443   */
LL_RTC_ALMA_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)444 ErrorStatus LL_RTC_ALMA_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
445 {
446   /* Check the parameters */
447   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
448   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
449   assert_param(IS_LL_RTC_ALMA_MASK(RTC_AlarmStruct->AlarmMask));
450   assert_param(IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel));
451 
452   if (RTC_Format == LL_RTC_FORMAT_BIN)
453   {
454     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
455     {
456       assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours));
457       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
458     }
459     else
460     {
461       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
462       assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
463     }
464     assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
465     assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
466 
467     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
468     {
469       assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay));
470     }
471     else
472     {
473       assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay));
474     }
475   }
476   else
477   {
478     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
479     {
480       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
481       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
482     }
483     else
484     {
485       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
486       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
487     }
488 
489     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
490     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
491 
492     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
493     {
494       assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
495     }
496     else
497     {
498       assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
499     }
500   }
501 
502   /* Disable the write protection for RTC registers */
503   LL_RTC_DisableWriteProtection(RTCx);
504 
505   /* Select weekday selection */
506   if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
507   {
508     /* Set the date for ALARM */
509     LL_RTC_ALMA_DisableWeekday(RTCx);
510     if (RTC_Format != LL_RTC_FORMAT_BIN)
511     {
512       LL_RTC_ALMA_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
513     }
514     else
515     {
516       LL_RTC_ALMA_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay));
517     }
518   }
519   else
520   {
521     /* Set the week day for ALARM */
522     LL_RTC_ALMA_EnableWeekday(RTCx);
523     LL_RTC_ALMA_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
524   }
525 
526   /* Configure the Alarm register */
527   if (RTC_Format != LL_RTC_FORMAT_BIN)
528   {
529     LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours,
530                            RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds);
531   }
532   else
533   {
534     LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat,
535                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours),
536                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes),
537                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds));
538   }
539   /* Set ALARM mask */
540   LL_RTC_ALMA_SetMask(RTCx, RTC_AlarmStruct->AlarmMask);
541 
542   /* Enable the write protection for RTC registers */
543   LL_RTC_EnableWriteProtection(RTCx);
544 
545   return SUCCESS;
546 }
547 
548 /**
549   * @brief  Set the RTC Alarm B.
550   * @note   The Alarm register can only be written when the corresponding Alarm
551   *         is disabled (@ref LL_RTC_ALMB_Disable function).
552   * @param  RTCx RTC Instance
553   * @param  RTC_Format This parameter can be one of the following values:
554   *         @arg @ref LL_RTC_FORMAT_BIN
555   *         @arg @ref LL_RTC_FORMAT_BCD
556   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
557   *                         contains the alarm configuration parameters.
558   * @retval An ErrorStatus enumeration value:
559   *          - SUCCESS: ALARMB registers are configured
560   *          - ERROR: ALARMB registers are not configured
561   */
LL_RTC_ALMB_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)562 ErrorStatus LL_RTC_ALMB_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
563 {
564   /* Check the parameters */
565   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
566   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
567   assert_param(IS_LL_RTC_ALMB_MASK(RTC_AlarmStruct->AlarmMask));
568   assert_param(IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel));
569 
570   if (RTC_Format == LL_RTC_FORMAT_BIN)
571   {
572     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
573     {
574       assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours));
575       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
576     }
577     else
578     {
579       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
580       assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
581     }
582     assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
583     assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
584 
585     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
586     {
587       assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay));
588     }
589     else
590     {
591       assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay));
592     }
593   }
594   else
595   {
596     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
597     {
598       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
599       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
600     }
601     else
602     {
603       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
604       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
605     }
606 
607     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
608     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
609 
610     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
611     {
612       assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
613     }
614     else
615     {
616       assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
617     }
618   }
619 
620   /* Disable the write protection for RTC registers */
621   LL_RTC_DisableWriteProtection(RTCx);
622 
623   /* Select weekday selection */
624   if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
625   {
626     /* Set the date for ALARM */
627     LL_RTC_ALMB_DisableWeekday(RTCx);
628     if (RTC_Format != LL_RTC_FORMAT_BIN)
629     {
630       LL_RTC_ALMB_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
631     }
632     else
633     {
634       LL_RTC_ALMB_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay));
635     }
636   }
637   else
638   {
639     /* Set the week day for ALARM */
640     LL_RTC_ALMB_EnableWeekday(RTCx);
641     LL_RTC_ALMB_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
642   }
643 
644   /* Configure the Alarm register */
645   if (RTC_Format != LL_RTC_FORMAT_BIN)
646   {
647     LL_RTC_ALMB_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours,
648                            RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds);
649   }
650   else
651   {
652     LL_RTC_ALMB_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat,
653                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours),
654                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes),
655                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds));
656   }
657   /* Set ALARM mask */
658   LL_RTC_ALMB_SetMask(RTCx, RTC_AlarmStruct->AlarmMask);
659 
660   /* Enable the write protection for RTC registers */
661   LL_RTC_EnableWriteProtection(RTCx);
662 
663   return SUCCESS;
664 }
665 
666 /**
667   * @brief  Set each @ref LL_RTC_AlarmTypeDef of ALARMA field to default value (Time = 00h:00mn:00sec /
668   *         Day = 1st day of the month/Mask = all fields are masked).
669   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
670   * @retval None
671   */
LL_RTC_ALMA_StructInit(LL_RTC_AlarmTypeDef * RTC_AlarmStruct)672 void LL_RTC_ALMA_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
673 {
674   /* Alarm Time Settings : Time = 00h:00mn:00sec */
675   RTC_AlarmStruct->AlarmTime.TimeFormat = LL_RTC_ALMA_TIME_FORMAT_AM;
676   RTC_AlarmStruct->AlarmTime.Hours      = 0U;
677   RTC_AlarmStruct->AlarmTime.Minutes    = 0U;
678   RTC_AlarmStruct->AlarmTime.Seconds    = 0U;
679 
680   /* Alarm Day Settings : Day = 1st day of the month */
681   RTC_AlarmStruct->AlarmDateWeekDaySel = LL_RTC_ALMA_DATEWEEKDAYSEL_DATE;
682   RTC_AlarmStruct->AlarmDateWeekDay    = 1U;
683 
684   /* Alarm Masks Settings : Mask =  all fields are not masked */
685   RTC_AlarmStruct->AlarmMask           = LL_RTC_ALMA_MASK_NONE;
686 }
687 
688 /**
689   * @brief  Set each @ref LL_RTC_AlarmTypeDef of ALARMA field to default value (Time = 00h:00mn:00sec /
690   *         Day = 1st day of the month/Mask = all fields are masked).
691   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
692   * @retval None
693   */
LL_RTC_ALMB_StructInit(LL_RTC_AlarmTypeDef * RTC_AlarmStruct)694 void LL_RTC_ALMB_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
695 {
696   /* Alarm Time Settings : Time = 00h:00mn:00sec */
697   RTC_AlarmStruct->AlarmTime.TimeFormat = LL_RTC_ALMB_TIME_FORMAT_AM;
698   RTC_AlarmStruct->AlarmTime.Hours      = 0U;
699   RTC_AlarmStruct->AlarmTime.Minutes    = 0U;
700   RTC_AlarmStruct->AlarmTime.Seconds    = 0U;
701 
702   /* Alarm Day Settings : Day = 1st day of the month */
703   RTC_AlarmStruct->AlarmDateWeekDaySel = LL_RTC_ALMB_DATEWEEKDAYSEL_DATE;
704   RTC_AlarmStruct->AlarmDateWeekDay    = 1U;
705 
706   /* Alarm Masks Settings : Mask =  all fields are not masked */
707   RTC_AlarmStruct->AlarmMask           = LL_RTC_ALMB_MASK_NONE;
708 }
709 
710 /**
711   * @brief  Enters the RTC Initialization mode.
712   * @note   The RTC Initialization mode is write protected, use the
713   *         @ref LL_RTC_DisableWriteProtection before calling this function.
714   * @param  RTCx RTC Instance
715   * @retval An ErrorStatus enumeration value:
716   *          - SUCCESS: RTC is in Init mode
717   *          - ERROR: RTC is not in Init mode
718   */
LL_RTC_EnterInitMode(RTC_TypeDef * RTCx)719 ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx)
720 {
721   __IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
722   ErrorStatus status = SUCCESS;
723   uint32_t tmp = 0U;
724 
725   /* Check the parameter */
726   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
727 
728   /* Check if the Initialization mode is set */
729   if (LL_RTC_IsActiveFlag_INIT(RTCx) == 0U)
730   {
731     /* Set the Initialization mode */
732     LL_RTC_EnableInitMode(RTCx);
733 
734     /* Wait till RTC is in INIT state and if Time out is reached exit */
735     tmp = LL_RTC_IsActiveFlag_INIT(RTCx);
736     while ((timeout != 0U) && (tmp != 1U))
737     {
738       if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
739       {
740         timeout --;
741       }
742       tmp = LL_RTC_IsActiveFlag_INIT(RTCx);
743       if (timeout == 0U)
744       {
745         status = ERROR;
746       }
747     }
748   }
749   return status;
750 }
751 
752 /**
753   * @brief  Exit the RTC Initialization mode.
754   * @note   When the initialization sequence is complete, the calendar restarts
755   *         counting after 4 RTCCLK cycles.
756   * @note   The RTC Initialization mode is write protected, use the
757   *         @ref LL_RTC_DisableWriteProtection before calling this function.
758   * @param  RTCx RTC Instance
759   * @retval An ErrorStatus enumeration value:
760   *          - SUCCESS: RTC exited from in Init mode
761   *          - ERROR: Not applicable
762   */
LL_RTC_ExitInitMode(RTC_TypeDef * RTCx)763 ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx)
764 {
765   /* Check the parameter */
766   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
767 
768   /* Disable initialization mode */
769   LL_RTC_DisableInitMode(RTCx);
770 
771   return SUCCESS;
772 }
773 
774 /**
775   * @brief  Waits until the RTC Time and Day registers (RTC_TR and RTC_DR) are
776   *         synchronized with RTC APB clock.
777   * @note   The RTC Resynchronization mode is write protected, use the
778   *         @ref LL_RTC_DisableWriteProtection before calling this function.
779   * @note   To read the calendar through the shadow registers after calendar
780   *         initialization, calendar update or after wakeup from low power modes
781   *         the software must first clear the RSF flag.
782   *         The software must then wait until it is set again before reading
783   *         the calendar, which means that the calendar registers have been
784   *         correctly copied into the RTC_TR and RTC_DR shadow registers.
785   * @param  RTCx RTC Instance
786   * @retval An ErrorStatus enumeration value:
787   *          - SUCCESS: RTC registers are synchronised
788   *          - ERROR: RTC registers are not synchronised
789   */
LL_RTC_WaitForSynchro(RTC_TypeDef * RTCx)790 ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx)
791 {
792   __IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT;
793   ErrorStatus status = SUCCESS;
794   uint32_t tmp = 0U;
795 
796   /* Check the parameter */
797   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
798 
799   /* Clear RSF flag */
800   LL_RTC_ClearFlag_RS(RTCx);
801 
802   /* Wait the registers to be synchronised */
803   tmp = LL_RTC_IsActiveFlag_RS(RTCx);
804   while ((timeout != 0U) && (tmp != 1U))
805   {
806     if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
807     {
808       timeout--;
809     }
810     tmp = LL_RTC_IsActiveFlag_RS(RTCx);
811     if (timeout == 0U)
812     {
813       status = ERROR;
814     }
815   }
816 
817   return (status);
818 }
819 
820 /**
821   * @}
822   */
823 
824 /**
825   * @}
826   */
827 
828 /**
829   * @}
830   */
831 
832 #endif /* defined(RTC) */
833 
834 /**
835   * @}
836   */
837 
838 #endif /* USE_FULL_LL_DRIVER */
839