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