1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_ll_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC LL module driver.
6   ******************************************************************************
7   * @attention
8   *
9   * Copyright (c) 2019 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 "stm32g4xx_ll_rtc.h"
22 #include "stm32g4xx_ll_cortex.h"
23 #ifdef  USE_FULL_ASSERT
24 #include "stm32_assert.h"
25 #else  /* USE_FULL_ASSERT */
26 #define assert_param(expr) ((void)0U)
27 #endif /* USE_FULL_ASSERT */
28 
29 /** @addtogroup STM32G4xx_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 #define IS_LL_RTC_HOURFORMAT(__VALUE__) (((__VALUE__) == LL_RTC_HOURFORMAT_24HOUR) \
61                                          || ((__VALUE__) == LL_RTC_HOURFORMAT_AMPM))
62 
63 #define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__)   ((__VALUE__) <= 0x7FU)
64 
65 #define IS_LL_RTC_SYNCH_PREDIV(__VALUE__)    ((__VALUE__) <= 0x7FFFU)
66 
67 #define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \
68                                      || ((__VALUE__) == LL_RTC_FORMAT_BCD))
69 
70 #define IS_LL_RTC_TIME_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_TIME_FORMAT_AM_OR_24) \
71                                           || ((__VALUE__) == LL_RTC_TIME_FORMAT_PM))
72 
73 #define IS_LL_RTC_HOUR12(__HOUR__)            (((__HOUR__) > 0U) && ((__HOUR__) <= 12U))
74 #define IS_LL_RTC_HOUR24(__HOUR__)            ((__HOUR__) <= 23U)
75 #define IS_LL_RTC_MINUTES(__MINUTES__)        ((__MINUTES__) <= 59U)
76 #define IS_LL_RTC_SECONDS(__SECONDS__)        ((__SECONDS__) <= 59U)
77 
78 #define IS_LL_RTC_WEEKDAY(__VALUE__) (((__VALUE__) == LL_RTC_WEEKDAY_MONDAY) \
79                                       || ((__VALUE__) == LL_RTC_WEEKDAY_TUESDAY) \
80                                       || ((__VALUE__) == LL_RTC_WEEKDAY_WEDNESDAY) \
81                                       || ((__VALUE__) == LL_RTC_WEEKDAY_THURSDAY) \
82                                       || ((__VALUE__) == LL_RTC_WEEKDAY_FRIDAY) \
83                                       || ((__VALUE__) == LL_RTC_WEEKDAY_SATURDAY) \
84                                       || ((__VALUE__) == LL_RTC_WEEKDAY_SUNDAY))
85 
86 #define IS_LL_RTC_DAY(__DAY__)    (((__DAY__) >= (uint32_t)1U) && ((__DAY__) <= (uint32_t)31U))
87 
88 #define IS_LL_RTC_MONTH(__MONTH__) (((__MONTH__) >= 1U) && ((__MONTH__) <= 12U))
89 
90 #define IS_LL_RTC_YEAR(__YEAR__) ((__YEAR__) <= 99U)
91 
92 #define IS_LL_RTC_ALMA_MASK(__VALUE__) (((__VALUE__) == LL_RTC_ALMA_MASK_NONE) \
93                                         || ((__VALUE__) == LL_RTC_ALMA_MASK_DATEWEEKDAY) \
94                                         || ((__VALUE__) == LL_RTC_ALMA_MASK_HOURS) \
95                                         || ((__VALUE__) == LL_RTC_ALMA_MASK_MINUTES) \
96                                         || ((__VALUE__) == LL_RTC_ALMA_MASK_SECONDS) \
97                                         || ((__VALUE__) == LL_RTC_ALMA_MASK_ALL))
98 
99 #define IS_LL_RTC_ALMB_MASK(__VALUE__) (((__VALUE__) == LL_RTC_ALMB_MASK_NONE) \
100                                         || ((__VALUE__) == LL_RTC_ALMB_MASK_DATEWEEKDAY) \
101                                         || ((__VALUE__) == LL_RTC_ALMB_MASK_HOURS) \
102                                         || ((__VALUE__) == LL_RTC_ALMB_MASK_MINUTES) \
103                                         || ((__VALUE__) == LL_RTC_ALMB_MASK_SECONDS) \
104                                         || ((__VALUE__) == LL_RTC_ALMB_MASK_ALL))
105 
106 
107 #define IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(__SEL__) (((__SEL__) == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE) || \
108                                                   ((__SEL__) == LL_RTC_ALMA_DATEWEEKDAYSEL_WEEKDAY))
109 
110 #define IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(__SEL__) (((__SEL__) == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE) || \
111                                                   ((__SEL__) == LL_RTC_ALMB_DATEWEEKDAYSEL_WEEKDAY))
112 /**
113   * @}
114   */
115 /* Private function prototypes -----------------------------------------------*/
116 /* Exported functions --------------------------------------------------------*/
117 /** @addtogroup RTC_LL_Exported_Functions
118   * @{
119   */
120 
121 /** @addtogroup RTC_LL_EF_Init
122   * @{
123   */
124 
125 /**
126   * @brief  De-Initializes the RTC registers to their default reset values.
127   * @note   This function does not reset the RTC Clock source and RTC Backup Data
128   *         registers.
129   * @param  RTCx RTC Instance
130   * @retval An ErrorStatus enumeration value:
131   *          - SUCCESS: RTC registers are de-initialized
132   *          - ERROR: RTC registers are not de-initialized
133   */
LL_RTC_DeInit(RTC_TypeDef * RTCx)134 ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx)
135 {
136   ErrorStatus status = ERROR;
137 
138   /* Check the parameter */
139   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
140   assert_param(IS_TAMP_ALL_INSTANCE(TAMP));
141 
142   /* Disable the write protection for RTC registers */
143   LL_RTC_DisableWriteProtection(RTCx);
144 
145   /* Set Initialization mode */
146   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
147   {
148     /* Reset TR, DR and CR registers */
149     WRITE_REG(RTCx->TR,       0x00000000U);
150 #if defined(RTC_WAKEUP_SUPPORT)
151     WRITE_REG(RTCx->WUTR,     RTC_WUTR_WUT);
152 #endif /* RTC_WAKEUP_SUPPORT */
153     WRITE_REG(RTCx->DR, (RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0));
154     /* Reset All CR bits except CR[2:0] */
155 #if defined(RTC_WAKEUP_SUPPORT)
156     WRITE_REG(RTCx->CR, (READ_REG(RTCx->CR) & RTC_CR_WUCKSEL));
157 #else
158     WRITE_REG(RTCx->CR, 0x00000000U);
159 #endif /* RTC_WAKEUP_SUPPORT */
160     WRITE_REG(RTCx->PRER, (RTC_PRER_PREDIV_A | RTC_SYNCH_PRESC_DEFAULT));
161     WRITE_REG(RTCx->ALRMAR,   0x00000000U);
162     WRITE_REG(RTCx->ALRMBR,   0x00000000U);
163     WRITE_REG(RTCx->SHIFTR,   0x00000000U);
164     WRITE_REG(RTCx->CALR,     0x00000000U);
165     WRITE_REG(RTCx->ALRMASSR, 0x00000000U);
166     WRITE_REG(RTCx->ALRMBSSR, 0x00000000U);
167 
168     /* Exit Initialization mode */
169     LL_RTC_DisableInitMode(RTCx);
170 
171     /* Wait till the RTC RSF flag is set */
172     status = LL_RTC_WaitForSynchro(RTCx);
173   }
174 
175   /* Enable the write protection for RTC registers */
176   LL_RTC_EnableWriteProtection(RTCx);
177 
178   /* DeInitialization of the TAMP */
179   /* Reset TAMP CR1 and CR2 registers */
180   WRITE_REG(TAMP->CR1,      0xFFFF0000U);
181   WRITE_REG(TAMP->CR2,     0x00000000U);
182 #if defined (RTC_OTHER_SUPPORT)
183   WRITE_REG(TAMP->CR3,     0x00000000U);
184   WRITE_REG(TAMP->SMCR,     0x00000000U);
185   WRITE_REG(TAMP->PRIVCR,   0x00000000U);
186 #endif /* RTC_OTHER_SUPPORT */
187   WRITE_REG(TAMP->FLTCR,    0x00000000U);
188 #if defined (RTC_ACTIVE_TAMPER_SUPPORT)
189   WRITE_REG(TAMP->ATCR1,    0x00000000U);
190   WRITE_REG(TAMP->ATCR2,    0x00000000U);
191 #endif /* RTC_ACTIVE_TAMPER_SUPPORT */
192   WRITE_REG(TAMP->IER,      0x00000000U);
193   WRITE_REG(TAMP->SCR,      0xFFFFFFFFU);
194 #if defined (RTC_OPTION_REG_SUPPORT)
195   WRITE_REG(TAMP->OR,       0x00000000U);
196 #endif /* RTC_OPTION_REG_SUPPORT */
197 
198   return status;
199 }
200 
201 /**
202   * @brief  Initializes the RTC registers according to the specified parameters
203   *         in RTC_InitStruct.
204   * @param  RTCx RTC Instance
205   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
206   *         the configuration information for the RTC peripheral.
207   * @note   The RTC Prescaler register is write protected and can be written in
208   *         initialization mode only.
209   * @retval An ErrorStatus enumeration value:
210   *          - SUCCESS: RTC registers are initialized
211   *          - ERROR: RTC registers are not initialized
212   */
LL_RTC_Init(RTC_TypeDef * RTCx,LL_RTC_InitTypeDef * RTC_InitStruct)213 ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
214 {
215   ErrorStatus status = ERROR;
216 
217   /* Check the parameters */
218   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
219   assert_param(IS_LL_RTC_HOURFORMAT(RTC_InitStruct->HourFormat));
220   assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
221   assert_param(IS_LL_RTC_SYNCH_PREDIV(RTC_InitStruct->SynchPrescaler));
222 
223   /* Disable the write protection for RTC registers */
224   LL_RTC_DisableWriteProtection(RTCx);
225 
226   /* Set Initialization mode */
227   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
228   {
229     /* Set Hour Format */
230     LL_RTC_SetHourFormat(RTCx, RTC_InitStruct->HourFormat);
231 
232     /* Configure Synchronous prescaler factor */
233     LL_RTC_SetSynchPrescaler(RTCx, RTC_InitStruct->SynchPrescaler);
234     /* Configure Asynchronous prescaler factor */
235     LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
236 
237     /* Exit Initialization mode */
238     LL_RTC_DisableInitMode(RTCx);
239 
240     status = SUCCESS;
241   }
242   /* Enable the write protection for RTC registers */
243   LL_RTC_EnableWriteProtection(RTCx);
244 
245   return status;
246 }
247 
248 /**
249   * @brief  Set each @ref LL_RTC_InitTypeDef field to default value.
250   * @param  RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
251   * @retval None
252   */
LL_RTC_StructInit(LL_RTC_InitTypeDef * RTC_InitStruct)253 void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
254 {
255   /* Set RTC_InitStruct fields to default values */
256   RTC_InitStruct->HourFormat      = LL_RTC_HOURFORMAT_24HOUR;
257   RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
258   RTC_InitStruct->SynchPrescaler  = RTC_SYNCH_PRESC_DEFAULT;
259 }
260 
261 /**
262   * @brief  Set the RTC current time.
263   * @param  RTCx RTC Instance
264   * @param  RTC_Format This parameter can be one of the following values:
265   *         @arg @ref LL_RTC_FORMAT_BIN
266   *         @arg @ref LL_RTC_FORMAT_BCD
267   * @param  RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
268   *                        the time configuration information for the RTC.
269   * @retval An ErrorStatus enumeration value:
270   *          - SUCCESS: RTC Time register is configured
271   *          - ERROR: RTC Time register is not configured
272   */
LL_RTC_TIME_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_TimeTypeDef * RTC_TimeStruct)273 ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
274 {
275   ErrorStatus status = ERROR;
276 
277   /* Check the parameters */
278   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
279   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
280 
281   if (RTC_Format == LL_RTC_FORMAT_BIN)
282   {
283     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
284     {
285       assert_param(IS_LL_RTC_HOUR12(RTC_TimeStruct->Hours));
286       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
287     }
288     else
289     {
290       RTC_TimeStruct->TimeFormat = 0x00U;
291       assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
292     }
293     assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
294     assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
295   }
296   else
297   {
298     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
299     {
300       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
301       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_TimeStruct->TimeFormat));
302     }
303     else
304     {
305       RTC_TimeStruct->TimeFormat = 0x00U;
306       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
307     }
308     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
309     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
310   }
311 
312   /* Disable the write protection for RTC registers */
313   LL_RTC_DisableWriteProtection(RTCx);
314 
315   /* Set Initialization mode */
316   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
317   {
318     /* Check the input parameters format */
319     if (RTC_Format != LL_RTC_FORMAT_BIN)
320     {
321       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, RTC_TimeStruct->Hours,
322                          RTC_TimeStruct->Minutes, RTC_TimeStruct->Seconds);
323     }
324     else
325     {
326       LL_RTC_TIME_Config(RTCx, RTC_TimeStruct->TimeFormat, __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Hours),
327                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Minutes),
328                          __LL_RTC_CONVERT_BIN2BCD(RTC_TimeStruct->Seconds));
329     }
330 
331     /* Exit Initialization mode */
332     LL_RTC_DisableInitMode(RTCx);
333 
334     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
335     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
336     {
337       status = LL_RTC_WaitForSynchro(RTCx);
338     }
339     else
340     {
341       status = SUCCESS;
342     }
343   }
344   /* Enable the write protection for RTC registers */
345   LL_RTC_EnableWriteProtection(RTCx);
346 
347   return status;
348 }
349 
350 /**
351   * @brief  Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
352   * @param  RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
353   * @retval None
354   */
LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef * RTC_TimeStruct)355 void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
356 {
357   /* Time = 00h:00min:00sec */
358   RTC_TimeStruct->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
359   RTC_TimeStruct->Hours      = 0U;
360   RTC_TimeStruct->Minutes    = 0U;
361   RTC_TimeStruct->Seconds    = 0U;
362 }
363 
364 /**
365   * @brief  Set the RTC current date.
366   * @param  RTCx RTC Instance
367   * @param  RTC_Format This parameter can be one of the following values:
368   *         @arg @ref LL_RTC_FORMAT_BIN
369   *         @arg @ref LL_RTC_FORMAT_BCD
370   * @param  RTC_DateStruct: pointer to a RTC_DateTypeDef structure that contains
371   *                         the date configuration information for the RTC.
372   * @retval An ErrorStatus enumeration value:
373   *          - SUCCESS: RTC Day register is configured
374   *          - ERROR: RTC Day register is not configured
375   */
LL_RTC_DATE_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_DateTypeDef * RTC_DateStruct)376 ErrorStatus LL_RTC_DATE_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_DateTypeDef *RTC_DateStruct)
377 {
378   ErrorStatus status = ERROR;
379 
380   /* Check the parameters */
381   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
382   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
383 
384   if ((RTC_Format == LL_RTC_FORMAT_BIN) && ((RTC_DateStruct->Month & 0x10U) == 0x10U))
385   {
386     RTC_DateStruct->Month = (uint8_t)(RTC_DateStruct->Month & (uint8_t)~(0x10U)) + 0x0AU;
387   }
388   if (RTC_Format == LL_RTC_FORMAT_BIN)
389   {
390     assert_param(IS_LL_RTC_YEAR(RTC_DateStruct->Year));
391     assert_param(IS_LL_RTC_MONTH(RTC_DateStruct->Month));
392     assert_param(IS_LL_RTC_DAY(RTC_DateStruct->Day));
393   }
394   else
395   {
396     assert_param(IS_LL_RTC_YEAR(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Year)));
397     assert_param(IS_LL_RTC_MONTH(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Month)));
398     assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_DateStruct->Day)));
399   }
400   assert_param(IS_LL_RTC_WEEKDAY(RTC_DateStruct->WeekDay));
401 
402   /* Disable the write protection for RTC registers */
403   LL_RTC_DisableWriteProtection(RTCx);
404 
405   /* Set Initialization mode */
406   if (LL_RTC_EnterInitMode(RTCx) != ERROR)
407   {
408     /* Check the input parameters format */
409     if (RTC_Format != LL_RTC_FORMAT_BIN)
410     {
411       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, RTC_DateStruct->Day, RTC_DateStruct->Month, RTC_DateStruct->Year);
412     }
413     else
414     {
415       LL_RTC_DATE_Config(RTCx, RTC_DateStruct->WeekDay, __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Day),
416                          __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Month), __LL_RTC_CONVERT_BIN2BCD(RTC_DateStruct->Year));
417     }
418 
419     /* Exit Initialization mode */
420     LL_RTC_DisableInitMode(RTCx);
421 
422     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
423     if (LL_RTC_IsShadowRegBypassEnabled(RTCx) == 0U)
424     {
425       status = LL_RTC_WaitForSynchro(RTCx);
426     }
427     else
428     {
429       status = SUCCESS;
430     }
431   }
432   /* Enable the write protection for RTC registers */
433   LL_RTC_EnableWriteProtection(RTCx);
434 
435   return status;
436 }
437 
438 /**
439   * @brief  Set each @ref LL_RTC_DateTypeDef field to default value (date = Monday, January 01 xx00)
440   * @param  RTC_DateStruct pointer to a @ref LL_RTC_DateTypeDef structure which will be initialized.
441   * @retval None
442   */
LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef * RTC_DateStruct)443 void LL_RTC_DATE_StructInit(LL_RTC_DateTypeDef *RTC_DateStruct)
444 {
445   /* Monday, January 01 xx00 */
446   RTC_DateStruct->WeekDay = LL_RTC_WEEKDAY_MONDAY;
447   RTC_DateStruct->Day     = 1U;
448   RTC_DateStruct->Month   = LL_RTC_MONTH_JANUARY;
449   RTC_DateStruct->Year    = 0U;
450 }
451 
452 /**
453   * @brief  Set the RTC Alarm A.
454   * @note   The Alarm register can only be written when the corresponding Alarm
455   *         is disabled (Use @ref LL_RTC_ALMA_Disable function).
456   * @param  RTCx RTC Instance
457   * @param  RTC_Format This parameter can be one of the following values:
458   *         @arg @ref LL_RTC_FORMAT_BIN
459   *         @arg @ref LL_RTC_FORMAT_BCD
460   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
461   *                         contains the alarm configuration parameters.
462   * @retval An ErrorStatus enumeration value:
463   *          - SUCCESS: ALARMA registers are configured
464   *          - ERROR: ALARMA registers are not configured
465   */
LL_RTC_ALMA_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)466 ErrorStatus LL_RTC_ALMA_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
467 {
468   /* Check the parameters */
469   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
470   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
471   assert_param(IS_LL_RTC_ALMA_MASK(RTC_AlarmStruct->AlarmMask));
472   assert_param(IS_LL_RTC_ALMA_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel));
473 
474   if (RTC_Format == LL_RTC_FORMAT_BIN)
475   {
476     /* initialize the AlarmTime for Binary format */
477     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
478     {
479       assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours));
480       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
481     }
482     else
483     {
484       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
485       assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
486     }
487     assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
488     assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
489 
490     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
491     {
492       assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay));
493     }
494     else
495     {
496       assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay));
497     }
498   }
499   else
500   {
501     /* initialize the AlarmTime for BCD format */
502     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
503     {
504       assert_param(IS_LL_RTC_HOUR12(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
505       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
506     }
507     else
508     {
509       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
510       assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
511     }
512 
513     assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
514     assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
515 
516     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
517     {
518       assert_param(IS_LL_RTC_DAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
519     }
520     else
521     {
522       assert_param(IS_LL_RTC_WEEKDAY(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmDateWeekDay)));
523     }
524   }
525 
526   /* Disable the write protection for RTC registers */
527   LL_RTC_DisableWriteProtection(RTCx);
528 
529   /* Select weekday selection */
530   if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMA_DATEWEEKDAYSEL_DATE)
531   {
532     /* Set the date for ALARM */
533     LL_RTC_ALMA_DisableWeekday(RTCx);
534     if (RTC_Format != LL_RTC_FORMAT_BIN)
535     {
536       LL_RTC_ALMA_SetDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
537     }
538     else
539     {
540       LL_RTC_ALMA_SetDay(RTCx, __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmDateWeekDay));
541     }
542   }
543   else
544   {
545     /* Set the week day for ALARM */
546     LL_RTC_ALMA_EnableWeekday(RTCx);
547     LL_RTC_ALMA_SetWeekDay(RTCx, RTC_AlarmStruct->AlarmDateWeekDay);
548   }
549 
550   /* Configure the Alarm register */
551   if (RTC_Format != LL_RTC_FORMAT_BIN)
552   {
553     LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat, RTC_AlarmStruct->AlarmTime.Hours,
554                            RTC_AlarmStruct->AlarmTime.Minutes, RTC_AlarmStruct->AlarmTime.Seconds);
555   }
556   else
557   {
558     LL_RTC_ALMA_ConfigTime(RTCx, RTC_AlarmStruct->AlarmTime.TimeFormat,
559                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Hours),
560                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Minutes),
561                            __LL_RTC_CONVERT_BIN2BCD(RTC_AlarmStruct->AlarmTime.Seconds));
562   }
563   /* Set ALARM mask */
564   LL_RTC_ALMA_SetMask(RTCx, RTC_AlarmStruct->AlarmMask);
565 
566   /* Enable the write protection for RTC registers */
567   LL_RTC_EnableWriteProtection(RTCx);
568 
569   return SUCCESS;
570 }
571 
572 /**
573   * @brief  Set the RTC Alarm B.
574   * @note   The Alarm register can only be written when the corresponding Alarm
575   *         is disabled (@ref LL_RTC_ALMB_Disable function).
576   * @param  RTCx RTC Instance
577   * @param  RTC_Format This parameter can be one of the following values:
578   *         @arg @ref LL_RTC_FORMAT_BIN
579   *         @arg @ref LL_RTC_FORMAT_BCD
580   * @param  RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
581   *                         contains the alarm configuration parameters.
582   * @retval An ErrorStatus enumeration value:
583   *          - SUCCESS: ALARMB registers are configured
584   *          - ERROR: ALARMB registers are not configured
585   */
LL_RTC_ALMB_Init(RTC_TypeDef * RTCx,uint32_t RTC_Format,LL_RTC_AlarmTypeDef * RTC_AlarmStruct)586 ErrorStatus LL_RTC_ALMB_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
587 {
588   /* Check the parameters */
589   assert_param(IS_RTC_ALL_INSTANCE(RTCx));
590   assert_param(IS_LL_RTC_FORMAT(RTC_Format));
591   assert_param(IS_LL_RTC_ALMB_MASK(RTC_AlarmStruct->AlarmMask));
592   assert_param(IS_LL_RTC_ALMB_DATE_WEEKDAY_SEL(RTC_AlarmStruct->AlarmDateWeekDaySel));
593 
594   if (RTC_Format == LL_RTC_FORMAT_BIN)
595   {
596     /* initialize the AlarmTime for Binary format */
597     if (LL_RTC_GetHourFormat(RTCx) != LL_RTC_HOURFORMAT_24HOUR)
598     {
599       assert_param(IS_LL_RTC_HOUR12(RTC_AlarmStruct->AlarmTime.Hours));
600       assert_param(IS_LL_RTC_TIME_FORMAT(RTC_AlarmStruct->AlarmTime.TimeFormat));
601     }
602     else
603     {
604       RTC_AlarmStruct->AlarmTime.TimeFormat = 0x00U;
605       assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
606     }
607     assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
608     assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
609 
610     if (RTC_AlarmStruct->AlarmDateWeekDaySel == LL_RTC_ALMB_DATEWEEKDAYSEL_DATE)
611     {
612       assert_param(IS_LL_RTC_DAY(RTC_AlarmStruct->AlarmDateWeekDay));
613     }
614     else
615     {
616       assert_param(IS_LL_RTC_WEEKDAY(RTC_AlarmStruct->AlarmDateWeekDay));
617     }
618   }
619   else
620   {
621     /* initialize the AlarmTime for BCD format */
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 ALARMB 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