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