1 /**
2   ******************************************************************************
3   * @file    stm32h7rsxx_ll_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2022 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 "stm32h7rsxx_ll_rtc.h"
22 #include "stm32h7rsxx_ll_cortex.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32H7RSxx_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     ((uint32_t) 0x0000007FU)
47 #define RTC_SYNCH_PRESC_DEFAULT      ((uint32_t) 0x000000FFU)
48 
49 /* Values used for timeout */
50 #define RTC_INITMODE_TIMEOUT         ((uint32_t) 1000U) /* 1s when tick set to 1ms */
51 #define RTC_SYNCHRO_TIMEOUT          ((uint32_t) 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__) >= (uint32_t)1U) && ((__DAY__) <= (uint32_t)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 = ERROR;
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   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
149   {
150     WRITE_REG(RTCx->TR,       0U);
151     WRITE_REG(RTCx->DR, (RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0));
152     WRITE_REG(RTCx->CR,       0U);
153     WRITE_REG(RTCx->WUTR,     RTC_WUTR_WUT);
154     WRITE_REG(RTCx->PRER, (RTC_PRER_PREDIV_A | RTC_SYNCH_PRESC_DEFAULT));
155     WRITE_REG(RTCx->ALRMAR,   0U);
156     WRITE_REG(RTCx->ALRMBR,   0U);
157     WRITE_REG(RTCx->SHIFTR,   0U);
158     WRITE_REG(RTCx->CALR,     0U);
159     WRITE_REG(RTCx->ALRMASSR, 0U);
160     WRITE_REG(RTCx->ALRMBSSR, 0U);
161     WRITE_REG(RTCx->PRIVCFGR, 0U);
162 
163     /* Clear some bits of RTC_ICSR and exit Initialization mode */
164     CLEAR_BIT(RTCx->ICSR, RTC_ICSR_BCDU_Msk | RTC_ICSR_BIN_Msk | RTC_ICSR_INIT);
165 
166     /* Wait till the RTC RSF flag is set */
167     status = LL_RTC_WaitForSynchro(RTCx);
168   }
169 
170   /* Enable the write protection for RTC registers */
171   LL_RTC_EnableWriteProtection(RTCx);
172 
173   /* DeInitialization of the TAMP registers */
174   WRITE_REG(TAMP->CR1,        0U);
175   WRITE_REG(TAMP->CR2,        0U);
176   WRITE_REG(TAMP->CR3,        0U);
177   WRITE_REG(TAMP->CFGR,       0U);
178   WRITE_REG(TAMP->PRIVCFGR,   0U);
179   WRITE_REG(TAMP->FLTCR,      0U);
180   WRITE_REG(TAMP->ATCR1,      0x00070000U);
181   WRITE_REG(TAMP->ATCR2,      0U);
182   WRITE_REG(TAMP->IER,        0U);
183   WRITE_REG(TAMP->SCR,        0xFFFFFFFFU);
184 
185   return status;
186 }
187 
188 /**
189   * @brief  Initializes the RTC registers according to the specified parameters
190   *         in RTC_InitStruct.
191   * @param  RTCx RTC Instance
192   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
193   *         the configuration information for the RTC peripheral.
194   * @note   The RTC Prescaler register is write protected and can be written in
195   *         initialization mode only.
196   * @retval An ErrorStatus enumeration value:
197   *          - SUCCESS: RTC registers are initialized
198   *          - ERROR: RTC registers are not initialized
199   */
LL_RTC_Init(RTC_TypeDef * RTCx,LL_RTC_InitTypeDef * RTC_InitStruct)200 ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
201 {
202   ErrorStatus status = ERROR;
203 
204   /* Check the parameters */
205   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
206   assert_param(IS_LL_RTC_HOURFORMAT(RTC_InitStruct->HourFormat));
207   assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
208   assert_param(IS_LL_RTC_SYNCH_PREDIV(RTC_InitStruct->SynchPrescaler));
209 
210   /* Disable the write protection for RTC registers */
211   LL_RTC_DisableWriteProtection(RTCx);
212 
213   /* Set Initialization mode */
214   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
215   {
216     /* Set Hour Format */
217     LL_RTC_SetHourFormat(RTCx, RTC_InitStruct->HourFormat);
218 
219     /* Configure Synchronous and Asynchronous prescaler factor */
220     LL_RTC_SetSynchPrescaler(RTCx, RTC_InitStruct->SynchPrescaler);
221     LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
222 
223     /* Exit Initialization mode */
224     LL_RTC_DisableInitMode(RTCx);
225 
226     status = SUCCESS;
227   }
228   /* Enable the write protection for RTC registers */
229   LL_RTC_EnableWriteProtection(RTCx);
230 
231   return status;
232 }
233 
234 /**
235   * @brief  Set each @ref LL_RTC_InitTypeDef field to default value.
236   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
237   * @retval None
238   */
LL_RTC_StructInit(LL_RTC_InitTypeDef * RTC_InitStruct)239 void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
240 {
241   /* Set RTC_InitStruct fields to default values */
242   RTC_InitStruct->HourFormat      = LL_RTC_HOURFORMAT_24HOUR;
243   RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
244   RTC_InitStruct->SynchPrescaler  = RTC_SYNCH_PRESC_DEFAULT;
245 }
246 
247 /**
248   * @brief  Set the RTC current time.
249   * @param  RTCx RTC Instance
250   * @param  RTC_Format This parameter can be one of the following values:
251   *         @arg @ref LL_RTC_FORMAT_BIN
252   *         @arg @ref LL_RTC_FORMAT_BCD
253   * @param  RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
254   *                        the time configuration information for the RTC.
255   * @retval An ErrorStatus enumeration value:
256   *          - SUCCESS: RTC Time register is configured
257   *          - ERROR: RTC Time register is not configured
258   */
LL_RTC_TIME_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_TimeTypeDef * RTC_TimeStruct)259 ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
260 {
261   ErrorStatus status = ERROR;
262 
263   /* Check the parameters */
264   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
265   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
266 
267   if (RTC_Format == LL_RTC_FORMAT_BIN)
268   {
269     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
270     {
271       assert_param(IS_LL_RTC_HOUR12(RTC_TimeStruct->Hours));
272       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
273     }
274     else
275     {
276       RTC_TimeStruct->TimeFormat = 0x00U;
277       assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
278     }
279     assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
280     assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
281   }
282   else
283   {
284     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
285     {
286       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
287       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
288     }
289     else
290     {
291       RTC_TimeStruct->TimeFormat = 0U;
292       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
293     }
294     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
295     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
296   }
297 
298   /* Disable the write protection for RTC registers */
299   LL_RTC_DisableWriteProtection(RTCx);
300 
301   /* Set Initialization mode */
302   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
303   {
304     /* Check the input parameters format */
305     if (RTC_Format != LL_RTC_FORMAT_BIN)
306     {
307       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, RTC_TimeStruct->Hours,
308                          RTC_TimeStruct->Minutes, RTC_TimeStruct->Seconds);
309     }
310     else
311     {
312       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Hours),
313                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Minutes),
314                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Seconds));
315     }
316 
317     /* Exit Initialization mode */
318     LL_RTC_DisableInitMode(RTCx);
319 
320     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
321     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
322     {
323       status = LL_RTC_WaitForSynchro(RTCx);
324     }
325     else
326     {
327       status = SUCCESS;
328     }
329   }
330   /* Enable the write protection for RTC registers */
331   LL_RTC_EnableWriteProtection(RTCx);
332 
333   return status;
334 }
335 
336 /**
337   * @brief  Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
338   * @param  RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
339   * @retval None
340   */
LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef * RTC_TimeStruct)341 void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
342 {
343   /* Time = 00h:00min:00sec */
344   RTC_TimeStruct->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
345   RTC_TimeStruct->Hours      = 0U;
346   RTC_TimeStruct->Minutes    = 0U;
347   RTC_TimeStruct->Seconds    = 0U;
348 }
349 
350 /**
351   * @brief  Set the RTC current date.
352   * @param  RTCx RTC Instance
353   * @param  RTC_Format This parameter can be one of the following values:
354   *         @arg @ref LL_RTC_FORMAT_BIN
355   *         @arg @ref LL_RTC_FORMAT_BCD
356   * @param  RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains
357   *                         the date configuration information for the RTC.
358   * @retval An ErrorStatus enumeration value:
359   *          - SUCCESS: RTC Day register is configured
360   *          - ERROR: RTC Day register is not configured
361   */
LL_RTC_DATE_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_DateTypeDef * RTC_DateStruct)362 ErrorStatus LL_RTC_DATE_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_DateTypeDef *RTC_DateStruct)
363 {
364   ErrorStatus status = ERROR;
365 
366   /* Check the parameters */
367   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
368   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
369 
370   if ((RTC_Format == LL_RTC_FORMAT_BIN) && ((RTC_DateStruct->Month & 0x10U) == 0x10U))
371   {
372     RTC_DateStruct->Month = (uint8_t)((uint32_t) RTC_DateStruct->Month & (uint32_t)~(0x10U)) + 0x0AU;
373   }
374   if (RTC_Format == LL_RTC_FORMAT_BIN)
375   {
376     assert_param(IS_LL_RTC_YEAR(RTC_DateStruct->Year));
377     assert_param(IS_LL_RTC_MONTH(RTC_DateStruct->Month));
378     assert_param(IS_LL_RTC_DAY(RTC_DateStruct->Day));
379   }
380   else
381   {
382     assert_param(IS_LL_RTC_YEAR(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Year)));
383     assert_param(IS_LL_RTC_MONTH(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Month)));
384     assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Day)));
385   }
386   assert_param(IS_LL_RTC_WEEKDAY(RTC_DateStruct->WeekDay));
387 
388   /* Disable the write protection for RTC registers */
389   LL_RTC_DisableWriteProtection(RTCx);
390 
391   /* Set Initialization mode */
392   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
393   {
394     /* Check the input parameters format */
395     if (RTC_Format != LL_RTC_FORMAT_BIN)
396     {
397       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, RTC_DateStruct->Day, RTC_DateStruct->Month,
398                          RTC_DateStruct->Year);
399     }
400     else
401     {
402       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Day),
403                          __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Month),
404                          __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   uint32_t      tmp;
804   ErrorStatus   status  = SUCCESS;
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 != 1U))
815   {
816     if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
817     {
818       timeout--;
819     }
820     tmp = LL_RTC_IsActiveFlag_RS(RTCx);
821   }
822 
823   if (timeout == 0U)
824   {
825     status = ERROR;
826   }
827 
828   return status;
829 }
830 
831 /**
832   * @}
833   */
834 
835 /**
836   * @}
837   */
838 
839 /**
840   * @}
841   */
842 
843 #endif /* defined(RTC) */
844 
845 /**
846   * @}
847   */
848 
849 #endif /* USE_FULL_LL_DRIVER */
850