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