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