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