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