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