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