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