1 /**
2   ******************************************************************************
3   * @file    stm32f0xx_hal_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Real-Time Clock (RTC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + RTC Calendar (Time and Date) configuration functions
10   *           + RTC Alarm (Alarm A) configuration functions
11   *           + Peripheral Control functions
12   *           + Peripheral State functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2016 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                ##### RTC and Backup Domain Operating Condition #####
28   ==============================================================================
29   [..] The real-time clock (RTC) and the RTC backup registers can be powered
30        from the VBAT voltage when the main VDD supply is powered off.
31        To retain the content of the RTC backup registers and supply the RTC when
32        VDD is turned off, VBAT pin can be connected to an optional standby
33        voltage supplied by a battery or by another source.
34 
35   [..] To allow the RTC operating even when the main digital supply (VDD) is turned
36        off, the VBAT pin powers the following blocks:
37     (#) The RTC
38     (#) The LSE oscillator
39     (#) PC13 to PC15 I/Os, plus PA0 and PE6 I/Os (when available)
40 
41   [..] When the backup domain is supplied by VDD (analog switch connected to VDD),
42        the following pins are available:
43     (#) PC14 and PC15 can be used as either GPIO or LSE pins
44     (#) PC13 can be used as a GPIO or as the RTC_AF1 pin
45     (#) PA0 can be used as a GPIO or as the RTC_AF2 pin
46     (#) PE6 can be used as a GPIO or as the RTC_AF3 pin
47 
48   [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
49        because VDD is not present), the following pins are available:
50     (#) PC14 and PC15 can be used as LSE pins only
51     (#) PC13 can be used as the RTC_AF1 pin
52     (#) PA0 can be used as the RTC_AF2 pin
53     (#) PE6 can be used as the RTC_AF3 pin
54 
55                    ##### Backup Domain Reset #####
56   ==================================================================
57   [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
58        to their reset values.
59   [..] A backup domain reset is generated when one of the following events occurs:
60     (#) Software reset, triggered by setting the BDRST bit in the
61         RCC Backup domain control register (RCC_BDCR).
62     (#) VDD or VBAT power on, if both supplies have previously been powered off.
63 
64                    ##### Backup Domain Access #####
65   ==================================================================
66   [..] After reset, the backup domain (RTC registers, RTC backup data registers
67        is protected against possible unwanted write accesses.
68   [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
69     (+) Enable the Power Controller (PWR) APB1 interface clock using the
70         __HAL_RCC_PWR_CLK_ENABLE() macro.
71     (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
72     (+) Select the RTC clock source using the __HAL_RCC_RTC_CONFIG() macro.
73     (+) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() macro.
74 
75   ==============================================================================
76                         ##### How to use this driver #####
77   ==============================================================================
78   [..]
79     (+) Enable the RTC domain access (see description in the section above).
80     (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour
81         format using the HAL_RTC_Init() function.
82 
83   *** Time and Date configuration ***
84   ===================================
85   [..]
86     (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
87         and HAL_RTC_SetDate() functions.
88     (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate()
89         functions.
90     (+) To manage the RTC summer or winter time change, use the following
91         functions:
92         (++) HAL_RTC_DST_Add1Hour() or HAL_RTC_DST_Sub1Hour to add or subtract
93              1 hour from the calendar time.
94         (++) HAL_RTC_DST_SetStoreOperation() or HAL_RTC_DST_ClearStoreOperation
95              to memorize whether the time change has been performed or not.
96 
97   *** Alarm configuration ***
98   ===========================
99   [..]
100     (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
101         You can also configure the RTC Alarm with interrupt mode using the
102         HAL_RTC_SetAlarm_IT() function.
103     (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
104 
105                   ##### RTC and low power modes #####
106   ==================================================================
107   [..] The MCU can be woken up from a low power mode by an RTC alternate
108        function.
109   [..] The RTC alternate functions are the RTC alarm (Alarm A), RTC wakeup,
110        RTC tamper event detection and RTC timestamp event detection.
111        These RTC alternate functions can wake up the system from the Stop and
112        Standby low power modes.
113   [..] The system can also wake up from low power modes without depending
114        on an external interrupt (Auto-wakeup mode), by using the RTC alarm
115        or the RTC wakeup events.
116   [..] The RTC provides a programmable time base for waking up from the
117        Stop or Standby mode at regular intervals.
118        Wakeup from STOP and STANDBY modes is possible only when the RTC clock
119        source is LSE or LSI.
120 
121   *** Callback registration ***
122   =============================================
123   [..]
124   The compilation define  USE_HAL_RTC_REGISTER_CALLBACKS when set to 1
125   allows the user to configure dynamically the driver callbacks.
126   Use Function HAL_RTC_RegisterCallback() to register an interrupt callback.
127   [..]
128   Function HAL_RTC_RegisterCallback() allows to register following callbacks:
129     (+) AlarmAEventCallback          : RTC Alarm A Event callback.
130     (+) TimeStampEventCallback       : RTC Timestamp Event callback.
131     (+) WakeUpTimerEventCallback     : RTC WakeUpTimer Event callback.
132     (+) Tamper1EventCallback         : RTC Tamper 1 Event callback.
133     (+) Tamper2EventCallback         : RTC Tamper 2 Event callback.
134     (+) Tamper3EventCallback         : RTC Tamper 3 Event callback.
135     (+) MspInitCallback              : RTC MspInit callback.
136     (+) MspDeInitCallback            : RTC MspDeInit callback.
137   [..]
138   This function takes as parameters the HAL peripheral handle, the Callback ID
139   and a pointer to the user callback function.
140   [..]
141   Use function HAL_RTC_UnRegisterCallback() to reset a callback to the default
142   weak function.
143   HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
144   and the Callback ID.
145   This function allows to reset following callbacks:
146     (+) AlarmAEventCallback          : RTC Alarm A Event callback.
147     (+) TimeStampEventCallback       : RTC Timestamp Event callback.
148     (+) WakeUpTimerEventCallback     : RTC WakeUpTimer Event callback.
149     (+) Tamper1EventCallback         : RTC Tamper 1 Event callback.
150     (+) Tamper2EventCallback         : RTC Tamper 2 Event callback.
151     (+) Tamper3EventCallback         : RTC Tamper 3 Event callback.
152     (+) MspInitCallback              : RTC MspInit callback.
153     (+) MspDeInitCallback            : RTC MspDeInit callback.
154   [..]
155   By default, after the HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET,
156   all callbacks are set to the corresponding weak functions:
157   examples AlarmAEventCallback(), WakeUpTimerEventCallback().
158   Exception done for MspInit() and MspDeInit() callbacks that are reset to the
159   legacy weak function in the HAL_RTC_Init()/HAL_RTC_DeInit() only
160   when these callbacks are null (not registered beforehand).
161   If not, MspInit() or MspDeInit() are not null, HAL_RTC_Init()/HAL_RTC_DeInit()
162   keep and use the user MspInit()/MspDeInit() callbacks (registered beforehand).
163   [..]
164   Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only.
165   Exception done MspInit()/MspDeInit() that can be registered/unregistered
166   in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state.
167   Thus registered (user) MspInit()/MspDeInit() callbacks can be used during the
168   Init/DeInit.
169   In that case first register the MspInit()/MspDeInit() user callbacks
170   using HAL_RTC_RegisterCallback() before calling HAL_RTC_DeInit()
171   or HAL_RTC_Init() functions.
172   [..]
173   When The compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or
174   not defined, the callback registration feature is not available and all
175   callbacks are set to the corresponding weak functions.
176 
177   @endverbatim
178   ******************************************************************************
179   */
180 
181 /* Includes ------------------------------------------------------------------*/
182 #include "stm32f0xx_hal.h"
183 
184 /** @addtogroup STM32F0xx_HAL_Driver
185   * @{
186   */
187 
188 /** @defgroup RTC RTC
189   * @brief    RTC HAL module driver
190   * @{
191   */
192 
193 #ifdef HAL_RTC_MODULE_ENABLED
194 
195 /* Private typedef -----------------------------------------------------------*/
196 /* Private define ------------------------------------------------------------*/
197 /* Private macro -------------------------------------------------------------*/
198 /* Private variables ---------------------------------------------------------*/
199 /* Private function prototypes -----------------------------------------------*/
200 /* Exported functions --------------------------------------------------------*/
201 
202 /** @defgroup RTC_Exported_Functions RTC Exported Functions
203   * @{
204   */
205 
206 /** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
207   * @brief    Initialization and Configuration functions
208   *
209 @verbatim
210  ===============================================================================
211               ##### Initialization and de-initialization functions #####
212  ===============================================================================
213    [..] This section provides functions allowing to initialize and configure the
214          RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable
215          RTC registers Write protection, enter and exit the RTC initialization mode,
216          RTC registers synchronization check and reference clock detection enable.
217          (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base.
218              It is split into 2 programmable prescalers to minimize power consumption.
219              (++) A 7-bit asynchronous prescaler and a 15-bit synchronous prescaler.
220              (++) When both prescalers are used, it is recommended to configure the
221                  asynchronous prescaler to a high value to minimize power consumption.
222          (#) All RTC registers are Write protected. Writing to the RTC registers
223              is enabled by writing a key into the Write Protection register, RTC_WPR.
224          (#) To configure the RTC Calendar, user application should enter
225              initialization mode. In this mode, the calendar counter is stopped
226              and its value can be updated. When the initialization sequence is
227              complete, the calendar restarts counting after 4 RTCCLK cycles.
228          (#) To read the calendar through the shadow registers after Calendar
229              initialization, calendar update or after wakeup from low power modes
230              the software must first clear the RSF flag. The software must then
231              wait until it is set again before reading the calendar, which means
232              that the calendar registers have been correctly copied into the
233              RTC_TR and RTC_DR shadow registers. The HAL_RTC_WaitForSynchro() function
234              implements the above software sequence (RSF clear and RSF check).
235 
236 @endverbatim
237   * @{
238   */
239 
240 /**
241   * @brief  Initializes the RTC peripheral
242   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
243   *                the configuration information for RTC.
244   * @retval HAL status
245   */
HAL_RTC_Init(RTC_HandleTypeDef * hrtc)246 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
247 {
248   HAL_StatusTypeDef status = HAL_ERROR;
249 
250   /* Check RTC handler validity */
251   if (hrtc == NULL)
252   {
253     return HAL_ERROR;
254   }
255 
256   /* Check the parameters */
257   assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
258   assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));
259   assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
260   assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));
261   assert_param(IS_RTC_OUTPUT(hrtc->Init.OutPut));
262   assert_param(IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));
263   assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType));
264 
265 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
266   if (hrtc->State == HAL_RTC_STATE_RESET)
267   {
268     /* Allocate lock resource and initialize it */
269     hrtc->Lock = HAL_UNLOCKED;
270 
271     hrtc->AlarmAEventCallback          =  HAL_RTC_AlarmAEventCallback;        /* Legacy weak AlarmAEventCallback      */
272     hrtc->TimeStampEventCallback       =  HAL_RTCEx_TimeStampEventCallback;   /* Legacy weak TimeStampEventCallback   */
273 #if defined(RTC_WAKEUP_SUPPORT)
274     hrtc->WakeUpTimerEventCallback     =  HAL_RTCEx_WakeUpTimerEventCallback; /* Legacy weak WakeUpTimerEventCallback */
275 #endif /* RTC_WAKEUP_SUPPORT */
276     hrtc->Tamper1EventCallback         =  HAL_RTCEx_Tamper1EventCallback;     /* Legacy weak Tamper1EventCallback     */
277     hrtc->Tamper2EventCallback         =  HAL_RTCEx_Tamper2EventCallback;     /* Legacy weak Tamper2EventCallback     */
278 #if defined(RTC_TAMPER3_SUPPORT)
279     hrtc->Tamper3EventCallback         =  HAL_RTCEx_Tamper3EventCallback;     /* Legacy weak Tamper3EventCallback     */
280 #endif /* RTC_TAMPER3_SUPPORT */
281 
282     if (hrtc->MspInitCallback == NULL)
283     {
284       hrtc->MspInitCallback = HAL_RTC_MspInit;
285     }
286     /* Init the low level hardware */
287     hrtc->MspInitCallback(hrtc);
288 
289     if (hrtc->MspDeInitCallback == NULL)
290     {
291       hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
292     }
293   }
294 #else /* USE_HAL_RTC_REGISTER_CALLBACKS */
295   if (hrtc->State == HAL_RTC_STATE_RESET)
296   {
297     /* Allocate lock resource and initialize it */
298     hrtc->Lock = HAL_UNLOCKED;
299 
300     /* Initialize RTC MSP */
301     HAL_RTC_MspInit(hrtc);
302   }
303 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
304 
305   /* Set RTC state */
306   hrtc->State = HAL_RTC_STATE_BUSY;
307 
308   /* Check whether the calendar needs to be initialized */
309   if (__HAL_RTC_IS_CALENDAR_INITIALIZED(hrtc) == 0U)
310   {
311     /* Disable the write protection for RTC registers */
312     __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
313 
314     /* Enter Initialization mode */
315     status = RTC_EnterInitMode(hrtc);
316 
317     if (status == HAL_OK)
318     {
319       /* Clear RTC_CR FMT, OSEL and POL Bits */
320       hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
321       /* Set RTC_CR register */
322       hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);
323 
324       /* Configure the RTC PRER */
325       hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);
326       hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << RTC_PRER_PREDIV_A_Pos);
327 
328       /* Exit Initialization mode */
329       status = RTC_ExitInitMode(hrtc);
330     }
331 
332     if (status == HAL_OK)
333     {
334       hrtc->Instance->TAFCR &= (uint32_t)~RTC_OUTPUT_TYPE_PUSHPULL;
335       hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);
336     }
337 
338     /* Enable the write protection for RTC registers */
339     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
340   }
341   else
342   {
343     /* The calendar is already initialized */
344     status = HAL_OK;
345   }
346 
347   if (status == HAL_OK)
348   {
349     hrtc->State = HAL_RTC_STATE_READY;
350   }
351 
352   return status;
353 }
354 
355 /**
356   * @brief  DeInitializes the RTC peripheral
357   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
358   *                the configuration information for RTC.
359   * @note   This function does not reset the RTC Backup Data registers.
360   * @retval HAL status
361   */
HAL_RTC_DeInit(RTC_HandleTypeDef * hrtc)362 HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
363 {
364   HAL_StatusTypeDef status = HAL_ERROR;
365 
366   /* Check the parameters */
367   assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
368 
369   /* Set RTC state */
370   hrtc->State = HAL_RTC_STATE_BUSY;
371 
372   /* Disable the write protection for RTC registers */
373   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
374 
375   /* Enter Initialization mode */
376   status = RTC_EnterInitMode(hrtc);
377 
378   if (status == HAL_OK)
379   {
380     /* Reset RTC registers */
381     hrtc->Instance->TR = 0x00000000U;
382     hrtc->Instance->DR = (RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0);
383     hrtc->Instance->CR  &= 0x00000000U;
384 #if defined(RTC_WAKEUP_SUPPORT)
385     hrtc->Instance->WUTR = RTC_WUTR_WUT;
386 #endif /* RTC_WAKEUP_SUPPORT */
387     hrtc->Instance->PRER = (uint32_t)(RTC_PRER_PREDIV_A | 0x000000FFU);
388     hrtc->Instance->ALRMAR   = 0x00000000U;
389     hrtc->Instance->CALR     = 0x00000000U;
390     hrtc->Instance->SHIFTR   = 0x00000000U;
391     hrtc->Instance->ALRMASSR = 0x00000000U;
392 
393     /* Exit Initialization mode */
394     status = RTC_ExitInitMode(hrtc);
395   }
396 
397   /* Enable the write protection for RTC registers */
398   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
399 
400   if (status == HAL_OK)
401   {
402     /* Reset Tamper and alternate functions configuration register */
403     hrtc->Instance->TAFCR = 0x00000000U;
404 
405 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
406     if (hrtc->MspDeInitCallback == NULL)
407     {
408       hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
409     }
410 
411     /* DeInit the low level hardware: CLOCK, NVIC.*/
412     hrtc->MspDeInitCallback(hrtc);
413 #else /* USE_HAL_RTC_REGISTER_CALLBACKS */
414     /* De-Initialize RTC MSP */
415     HAL_RTC_MspDeInit(hrtc);
416 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
417 
418     hrtc->State = HAL_RTC_STATE_RESET;
419   }
420 
421   /* Release Lock */
422   __HAL_UNLOCK(hrtc);
423 
424   return status;
425 }
426 
427 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
428 /**
429   * @brief  Registers a User RTC Callback
430   *         To be used instead of the weak predefined callback
431   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
432   *                the configuration information for RTC.
433   * @param  CallbackID ID of the callback to be registered
434   *         This parameter can be one of the following values:
435   *          @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID          Alarm A Event Callback ID
436   *          @arg @ref HAL_RTC_TIMESTAMP_EVENT_CB_ID        Timestamp Event Callback ID
437   *          @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID      Wakeup Timer Event Callback ID
438   *          @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID          Tamper 1 Callback ID
439   *          @arg @ref HAL_RTC_TAMPER2_EVENT_CB_ID          Tamper 2 Callback ID
440   *          @arg @ref HAL_RTC_TAMPER3_EVENT_CB_ID          Tamper 3 Callback ID
441   *          @arg @ref HAL_RTC_MSPINIT_CB_ID                Msp Init callback ID
442   *          @arg @ref HAL_RTC_MSPDEINIT_CB_ID              Msp DeInit callback ID
443   * @note   HAL_RTC_TAMPER3_EVENT_CB_ID is not applicable to all devices.
444   * @param  pCallback pointer to the Callback function
445   * @retval HAL status
446   */
HAL_RTC_RegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID,pRTC_CallbackTypeDef pCallback)447 HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, pRTC_CallbackTypeDef pCallback)
448 {
449   HAL_StatusTypeDef status = HAL_OK;
450 
451   if (pCallback == NULL)
452   {
453     return HAL_ERROR;
454   }
455 
456   /* Process locked */
457   __HAL_LOCK(hrtc);
458 
459   if (HAL_RTC_STATE_READY == hrtc->State)
460   {
461     switch (CallbackID)
462     {
463       case HAL_RTC_ALARM_A_EVENT_CB_ID :
464         hrtc->AlarmAEventCallback = pCallback;
465         break;
466 
467       case HAL_RTC_TIMESTAMP_EVENT_CB_ID :
468         hrtc->TimeStampEventCallback = pCallback;
469         break;
470 
471 #if defined(RTC_WAKEUP_SUPPORT)
472       case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID :
473         hrtc->WakeUpTimerEventCallback = pCallback;
474         break;
475 #endif /* RTC_WAKEUP_SUPPORT */
476 
477       case HAL_RTC_TAMPER1_EVENT_CB_ID :
478         hrtc->Tamper1EventCallback = pCallback;
479         break;
480 
481       case HAL_RTC_TAMPER2_EVENT_CB_ID :
482         hrtc->Tamper2EventCallback = pCallback;
483         break;
484 
485 #if defined(RTC_TAMPER3_SUPPORT)
486       case HAL_RTC_TAMPER3_EVENT_CB_ID :
487         hrtc->Tamper3EventCallback = pCallback;
488         break;
489 #endif /* RTC_TAMPER3_SUPPORT */
490 
491       case HAL_RTC_MSPINIT_CB_ID :
492         hrtc->MspInitCallback = pCallback;
493         break;
494 
495       case HAL_RTC_MSPDEINIT_CB_ID :
496         hrtc->MspDeInitCallback = pCallback;
497         break;
498 
499       default :
500         /* Return error status */
501         status =  HAL_ERROR;
502         break;
503     }
504   }
505   else if (HAL_RTC_STATE_RESET == hrtc->State)
506   {
507     switch (CallbackID)
508     {
509       case HAL_RTC_MSPINIT_CB_ID :
510         hrtc->MspInitCallback = pCallback;
511         break;
512 
513       case HAL_RTC_MSPDEINIT_CB_ID :
514         hrtc->MspDeInitCallback = pCallback;
515         break;
516 
517       default :
518         /* Return error status */
519         status =  HAL_ERROR;
520         break;
521     }
522   }
523   else
524   {
525     /* Return error status */
526     status =  HAL_ERROR;
527   }
528 
529   /* Release Lock */
530   __HAL_UNLOCK(hrtc);
531 
532   return status;
533 }
534 
535 /**
536   * @brief  Unregisters an RTC Callback
537   *         RTC callback is redirected to the weak predefined callback
538   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
539   *                the configuration information for RTC.
540   * @param  CallbackID ID of the callback to be unregistered
541   *         This parameter can be one of the following values:
542   *          @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID          Alarm A Event Callback ID
543   *          @arg @ref HAL_RTC_TIMESTAMP_EVENT_CB_ID        Timestamp Event Callback ID
544   *          @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID      Wakeup Timer Event Callback ID
545   *          @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID          Tamper 1 Callback ID
546   *          @arg @ref HAL_RTC_TAMPER2_EVENT_CB_ID          Tamper 2 Callback ID
547   *          @arg @ref HAL_RTC_TAMPER3_EVENT_CB_ID          Tamper 3 Callback ID
548   *          @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID
549   *          @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID
550   * @note   HAL_RTC_TAMPER3_EVENT_CB_ID is not applicable to all devices.
551   * @retval HAL status
552   */
HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID)553 HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID)
554 {
555   HAL_StatusTypeDef status = HAL_OK;
556 
557   /* Process locked */
558   __HAL_LOCK(hrtc);
559 
560   if (HAL_RTC_STATE_READY == hrtc->State)
561   {
562     switch (CallbackID)
563     {
564       case HAL_RTC_ALARM_A_EVENT_CB_ID :
565         hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback;             /* Legacy weak AlarmAEventCallback    */
566         break;
567 
568       case HAL_RTC_TIMESTAMP_EVENT_CB_ID :
569         hrtc->TimeStampEventCallback = HAL_RTCEx_TimeStampEventCallback;     /* Legacy weak TimeStampEventCallback    */
570         break;
571 
572 #if defined(RTC_WAKEUP_SUPPORT)
573       case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID :
574         hrtc->WakeUpTimerEventCallback = HAL_RTCEx_WakeUpTimerEventCallback; /* Legacy weak WakeUpTimerEventCallback */
575         break;
576 #endif /* RTC_WAKEUP_SUPPORT */
577 
578       case HAL_RTC_TAMPER1_EVENT_CB_ID :
579         hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback;         /* Legacy weak Tamper1EventCallback   */
580         break;
581 
582       case HAL_RTC_TAMPER2_EVENT_CB_ID :
583         hrtc->Tamper2EventCallback = HAL_RTCEx_Tamper2EventCallback;         /* Legacy weak Tamper2EventCallback         */
584         break;
585 
586 #if defined(RTC_TAMPER3_SUPPORT)
587       case HAL_RTC_TAMPER3_EVENT_CB_ID :
588         hrtc->Tamper3EventCallback = HAL_RTCEx_Tamper3EventCallback;         /* Legacy weak Tamper3EventCallback         */
589         break;
590 #endif /* RTC_TAMPER3_SUPPORT */
591 
592       case HAL_RTC_MSPINIT_CB_ID :
593         hrtc->MspInitCallback = HAL_RTC_MspInit;
594         break;
595 
596       case HAL_RTC_MSPDEINIT_CB_ID :
597         hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
598         break;
599 
600       default :
601         /* Return error status */
602         status =  HAL_ERROR;
603         break;
604     }
605   }
606   else if (HAL_RTC_STATE_RESET == hrtc->State)
607   {
608     switch (CallbackID)
609     {
610       case HAL_RTC_MSPINIT_CB_ID :
611         hrtc->MspInitCallback = HAL_RTC_MspInit;
612         break;
613 
614       case HAL_RTC_MSPDEINIT_CB_ID :
615         hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
616         break;
617 
618       default :
619         /* Return error status */
620         status =  HAL_ERROR;
621         break;
622     }
623   }
624   else
625   {
626     /* Return error status */
627     status =  HAL_ERROR;
628   }
629 
630   /* Release Lock */
631   __HAL_UNLOCK(hrtc);
632 
633   return status;
634 }
635 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
636 
637 /**
638   * @brief  Initializes the RTC MSP.
639   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
640   *                the configuration information for RTC.
641   * @retval None
642   */
HAL_RTC_MspInit(RTC_HandleTypeDef * hrtc)643 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
644 {
645   /* Prevent unused argument(s) compilation warning */
646   UNUSED(hrtc);
647 
648   /* NOTE: This function should not be modified, when the callback is needed,
649            the HAL_RTC_MspInit could be implemented in the user file
650    */
651 }
652 
653 /**
654   * @brief  DeInitializes the RTC MSP.
655   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
656   *                the configuration information for RTC.
657   * @retval None
658   */
HAL_RTC_MspDeInit(RTC_HandleTypeDef * hrtc)659 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
660 {
661   /* Prevent unused argument(s) compilation warning */
662   UNUSED(hrtc);
663 
664   /* NOTE: This function should not be modified, when the callback is needed,
665            the HAL_RTC_MspDeInit could be implemented in the user file
666    */
667 }
668 
669 /**
670   * @}
671   */
672 
673 /** @defgroup RTC_Exported_Functions_Group2 RTC Time and Date functions
674   * @brief    RTC Time and Date functions
675   *
676 @verbatim
677  ===============================================================================
678                  ##### RTC Time and Date functions #####
679  ===============================================================================
680 
681  [..] This section provides functions allowing to configure Time and Date features
682 
683 @endverbatim
684   * @{
685   */
686 
687 /**
688   * @brief  Sets RTC current time.
689   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
690   *                the configuration information for RTC.
691   * @param  sTime Pointer to Time structure
692   * @note   DayLightSaving and StoreOperation interfaces are deprecated.
693   *         To manage Daylight Saving Time, please use HAL_RTC_DST_xxx functions.
694   * @param  Format Specifies the format of the entered parameters.
695   *          This parameter can be one of the following values:
696   *            @arg RTC_FORMAT_BIN: Binary data format
697   *            @arg RTC_FORMAT_BCD: BCD data format
698   * @retval HAL status
699   */
HAL_RTC_SetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)700 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
701 {
702   uint32_t tmpreg = 0U;
703   HAL_StatusTypeDef status;
704 
705   /* Check the parameters */
706   assert_param(IS_RTC_FORMAT(Format));
707   assert_param(IS_RTC_DAYLIGHT_SAVING(sTime->DayLightSaving));
708   assert_param(IS_RTC_STORE_OPERATION(sTime->StoreOperation));
709 
710   /* Process Locked */
711   __HAL_LOCK(hrtc);
712 
713   hrtc->State = HAL_RTC_STATE_BUSY;
714 
715   if (Format == RTC_FORMAT_BIN)
716   {
717     if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
718     {
719       assert_param(IS_RTC_HOUR12(sTime->Hours));
720       assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
721     }
722     else
723     {
724       sTime->TimeFormat = 0x00U;
725       assert_param(IS_RTC_HOUR24(sTime->Hours));
726     }
727     assert_param(IS_RTC_MINUTES(sTime->Minutes));
728     assert_param(IS_RTC_SECONDS(sTime->Seconds));
729 
730     tmpreg = (uint32_t)(( (uint32_t)RTC_ByteToBcd2(sTime->Hours)   << RTC_TR_HU_Pos)  | \
731                         ( (uint32_t)RTC_ByteToBcd2(sTime->Minutes) << RTC_TR_MNU_Pos) | \
732                         ( (uint32_t)RTC_ByteToBcd2(sTime->Seconds))                   | \
733                         (((uint32_t)sTime->TimeFormat)             << RTC_TR_PM_Pos));
734   }
735   else
736   {
737     if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
738     {
739       assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sTime->Hours)));
740       assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
741     }
742     else
743     {
744       sTime->TimeFormat = 0x00U;
745       assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
746     }
747     assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
748     assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
749     tmpreg = (((uint32_t)(sTime->Hours)      << RTC_TR_HU_Pos)  | \
750               ((uint32_t)(sTime->Minutes)    << RTC_TR_MNU_Pos) | \
751               ((uint32_t) sTime->Seconds)                       | \
752               ((uint32_t)(sTime->TimeFormat) << RTC_TR_PM_Pos));
753   }
754 
755   /* Disable the write protection for RTC registers */
756   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
757 
758   /* Enter Initialization mode */
759   status = RTC_EnterInitMode(hrtc);
760 
761   if (status == HAL_OK)
762   {
763     /* Set the RTC_TR register */
764     hrtc->Instance->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
765 
766     /* Clear the bits to be configured (Deprecated. Use HAL_RTC_DST_xxx functions instead) */
767     hrtc->Instance->CR &= (uint32_t)~RTC_CR_BKP;
768 
769     /* Configure the RTC_CR register (Deprecated. Use HAL_RTC_DST_xxx functions instead) */
770     hrtc->Instance->CR |= (uint32_t)(sTime->DayLightSaving | sTime->StoreOperation);
771 
772     /* Exit Initialization mode */
773     status = RTC_ExitInitMode(hrtc);
774   }
775 
776   if (status == HAL_OK)
777   {
778     hrtc->State = HAL_RTC_STATE_READY;
779   }
780 
781   /* Enable the write protection for RTC registers */
782   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
783 
784   /* Process Unlocked */
785   __HAL_UNLOCK(hrtc);
786 
787   return status;
788 }
789 
790 /**
791   * @brief  Gets RTC current time.
792   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
793   *                the configuration information for RTC.
794   * @param  sTime Pointer to Time structure
795   * @param  Format Specifies the format of the entered parameters.
796   *          This parameter can be one of the following values:
797   *            @arg RTC_FORMAT_BIN: Binary data format
798   *            @arg RTC_FORMAT_BCD: BCD data format
799   * @note  You can use SubSeconds and SecondFraction (sTime structure fields
800   *        returned) to convert SubSeconds value in second fraction ratio with
801   *        time unit following generic formula:
802   *        Second fraction ratio * time_unit =
803   *           [(SecondFraction - SubSeconds) / (SecondFraction + 1)] * time_unit
804   *        This conversion can be performed only if no shift operation is pending
805   *        (ie. SHFP=0) when PREDIV_S >= SS
806   * @note  You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the
807   *        values in the higher-order calendar shadow registers to ensure
808   *        consistency between the time and date values.
809   *        Reading RTC current time locks the values in calendar shadow registers
810   *        until current date is read to ensure consistency between the time and
811   *        date values.
812   * @retval HAL status
813   */
HAL_RTC_GetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)814 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
815 {
816   uint32_t tmpreg = 0U;
817 
818   /* Check the parameters */
819   assert_param(IS_RTC_FORMAT(Format));
820 
821   /* Get subseconds value from the corresponding register */
822   sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR);
823 
824   /* Get SecondFraction structure field from the corresponding register field*/
825   sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S);
826 
827   /* Get the TR register */
828   tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);
829 
830   /* Fill the structure fields with the read parameters */
831   sTime->Hours      = (uint8_t)((tmpreg & (RTC_TR_HT  | RTC_TR_HU))  >> RTC_TR_HU_Pos);
832   sTime->Minutes    = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos);
833   sTime->Seconds    = (uint8_t)( tmpreg & (RTC_TR_ST  | RTC_TR_SU));
834   sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM))               >> RTC_TR_PM_Pos);
835 
836   /* Check the input parameters format */
837   if (Format == RTC_FORMAT_BIN)
838   {
839     /* Convert the time structure parameters to Binary format */
840     sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours);
841     sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes);
842     sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds);
843   }
844 
845   return HAL_OK;
846 }
847 
848 /**
849   * @brief  Sets RTC current date.
850   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
851   *                the configuration information for RTC.
852   * @param  sDate Pointer to date structure
853   * @param  Format specifies the format of the entered parameters.
854   *          This parameter can be one of the following values:
855   *            @arg RTC_FORMAT_BIN: Binary data format
856   *            @arg RTC_FORMAT_BCD: BCD data format
857   * @retval HAL status
858   */
HAL_RTC_SetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)859 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
860 {
861   uint32_t datetmpreg = 0U;
862   HAL_StatusTypeDef status;
863 
864   /* Check the parameters */
865   assert_param(IS_RTC_FORMAT(Format));
866 
867   /* Process Locked */
868   __HAL_LOCK(hrtc);
869 
870   hrtc->State = HAL_RTC_STATE_BUSY;
871 
872   if ((Format == RTC_FORMAT_BIN) && ((sDate->Month & 0x10U) == 0x10U))
873   {
874     sDate->Month = (uint8_t)((sDate->Month & (uint8_t)~(0x10U)) + (uint8_t)0x0AU);
875   }
876 
877   assert_param(IS_RTC_WEEKDAY(sDate->WeekDay));
878 
879   if (Format == RTC_FORMAT_BIN)
880   {
881     assert_param(IS_RTC_YEAR(sDate->Year));
882     assert_param(IS_RTC_MONTH(sDate->Month));
883     assert_param(IS_RTC_DATE(sDate->Date));
884 
885     datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year)  << RTC_DR_YU_Pos) | \
886                   ((uint32_t)RTC_ByteToBcd2(sDate->Month) << RTC_DR_MU_Pos) | \
887                   ((uint32_t)RTC_ByteToBcd2(sDate->Date))                   | \
888                   ((uint32_t)sDate->WeekDay               << RTC_DR_WDU_Pos));
889   }
890   else
891   {
892     assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
893     assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
894     assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
895 
896     datetmpreg = ((((uint32_t)sDate->Year)    << RTC_DR_YU_Pos) | \
897                   (((uint32_t)sDate->Month)   << RTC_DR_MU_Pos) | \
898                   ((uint32_t) sDate->Date)                      | \
899                   (((uint32_t)sDate->WeekDay) << RTC_DR_WDU_Pos));
900   }
901 
902   /* Disable the write protection for RTC registers */
903   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
904 
905   /* Enter Initialization mode */
906   status = RTC_EnterInitMode(hrtc);
907 
908   if (status == HAL_OK)
909   {
910     /* Set the RTC_DR register */
911     hrtc->Instance->DR = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK);
912 
913     /* Exit Initialization mode */
914     status = RTC_ExitInitMode(hrtc);
915   }
916 
917   if (status == HAL_OK)
918   {
919     hrtc->State = HAL_RTC_STATE_READY;
920   }
921 
922   /* Enable the write protection for RTC registers */
923   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
924 
925   /* Process Unlocked */
926   __HAL_UNLOCK(hrtc);
927 
928   return status;
929 }
930 
931 /**
932   * @brief  Gets RTC current date.
933   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
934   *                the configuration information for RTC.
935   * @param  sDate Pointer to Date structure
936   * @param  Format Specifies the format of the entered parameters.
937   *          This parameter can be one of the following values:
938   *            @arg RTC_FORMAT_BIN:  Binary data format
939   *            @arg RTC_FORMAT_BCD:  BCD data format
940   * @note  You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the
941   *        values in the higher-order calendar shadow registers to ensure
942   *        consistency between the time and date values.
943   *        Reading RTC current time locks the values in calendar shadow registers
944   *        until current date is read to ensure consistency between the time and
945   *        date values.
946   * @retval HAL status
947   */
HAL_RTC_GetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)948 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
949 {
950   uint32_t datetmpreg = 0U;
951 
952   /* Check the parameters */
953   assert_param(IS_RTC_FORMAT(Format));
954 
955   /* Get the DR register */
956   datetmpreg = (uint32_t)(hrtc->Instance->DR & RTC_DR_RESERVED_MASK);
957 
958   /* Fill the structure fields with the read parameters */
959   sDate->Year    = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos);
960   sDate->Month   = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos);
961   sDate->Date    = (uint8_t) (datetmpreg & (RTC_DR_DT | RTC_DR_DU));
962   sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU))            >> RTC_DR_WDU_Pos);
963 
964   /* Check the input parameters format */
965   if (Format == RTC_FORMAT_BIN)
966   {
967     /* Convert the date structure parameters to Binary format */
968     sDate->Year  = (uint8_t)RTC_Bcd2ToByte(sDate->Year);
969     sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month);
970     sDate->Date  = (uint8_t)RTC_Bcd2ToByte(sDate->Date);
971   }
972   return HAL_OK;
973 }
974 
975 /**
976   * @}
977   */
978 
979 /** @defgroup RTC_Exported_Functions_Group3 RTC Alarm functions
980   * @brief    RTC Alarm functions
981   *
982 @verbatim
983  ===============================================================================
984                  ##### RTC Alarm functions #####
985  ===============================================================================
986 
987  [..] This section provides functions allowing to configure Alarm feature
988 
989 @endverbatim
990   * @{
991   */
992 /**
993   * @brief  Sets the specified RTC Alarm.
994   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
995   *                the configuration information for RTC.
996   * @param  sAlarm Pointer to Alarm structure
997   * @param  Format Specifies the format of the entered parameters.
998   *          This parameter can be one of the following values:
999   *             @arg RTC_FORMAT_BIN: Binary data format
1000   *             @arg RTC_FORMAT_BCD: BCD data format
1001   * @note   The Alarm register can only be written when the corresponding Alarm
1002   *         is disabled (Use the HAL_RTC_DeactivateAlarm()).
1003   * @note   The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
1004   * @retval HAL status
1005   */
HAL_RTC_SetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1006 HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1007 {
1008   uint32_t tickstart = 0U;
1009   uint32_t tmpreg = 0U;
1010   uint32_t subsecondtmpreg = 0U;
1011 
1012   /* Check the parameters */
1013   assert_param(IS_RTC_FORMAT(Format));
1014   assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1015   assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask));
1016   assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel));
1017   assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds));
1018   assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask));
1019 
1020   /* Process Locked */
1021   __HAL_LOCK(hrtc);
1022 
1023   /* Change RTC state to BUSY */
1024   hrtc->State = HAL_RTC_STATE_BUSY;
1025 
1026   /* Check the data format (binary or BCD) and store the Alarm time and date
1027      configuration accordingly */
1028   if (Format == RTC_FORMAT_BIN)
1029   {
1030     if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1031     {
1032       assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours));
1033       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1034     }
1035     else
1036     {
1037       sAlarm->AlarmTime.TimeFormat = 0x00U;
1038       assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1039     }
1040     assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1041     assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1042 
1043     if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1044     {
1045       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay));
1046     }
1047     else
1048     {
1049       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay));
1050     }
1051 
1052     tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours)   << RTC_ALRMAR_HU_Pos)  | \
1053               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1054               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds))                       | \
1055               ((uint32_t)(sAlarm->AlarmTime.TimeFormat)            << RTC_TR_PM_Pos)      | \
1056               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay)  << RTC_ALRMAR_DU_Pos)  | \
1057               ((uint32_t)sAlarm->AlarmDateWeekDaySel)                                     | \
1058               ((uint32_t)sAlarm->AlarmMask));
1059   }
1060   else
1061   {
1062     if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1063     {
1064       assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1065       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1066     }
1067     else
1068     {
1069       sAlarm->AlarmTime.TimeFormat = 0x00U;
1070       assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1071     }
1072 
1073     assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1074     assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1075 
1076     if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1077     {
1078       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1079     }
1080     else
1081     {
1082       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1083     }
1084 
1085     tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours)      << RTC_ALRMAR_HU_Pos)  | \
1086               ((uint32_t)(sAlarm->AlarmTime.Minutes)    << RTC_ALRMAR_MNU_Pos) | \
1087               ((uint32_t) sAlarm->AlarmTime.Seconds)                           | \
1088               ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_TR_PM_Pos)      | \
1089               ((uint32_t)(sAlarm->AlarmDateWeekDay)     << RTC_ALRMAR_DU_Pos)  | \
1090               ((uint32_t) sAlarm->AlarmDateWeekDaySel)                         | \
1091               ((uint32_t) sAlarm->AlarmMask));
1092   }
1093 
1094   /* Store the Alarm subseconds configuration */
1095   subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | \
1096                                (uint32_t)(sAlarm->AlarmSubSecondMask));
1097 
1098   /* Disable the write protection for RTC registers */
1099   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1100 
1101     /* Disable the Alarm A */
1102     __HAL_RTC_ALARMA_DISABLE(hrtc);
1103 
1104     /* In case interrupt mode is used, the interrupt source must be disabled */
1105     __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1106 
1107     /* Clear the Alarm flag */
1108     __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1109 
1110     /* Get tick */
1111     tickstart = HAL_GetTick();
1112 
1113     /* Wait till RTC ALRAWF flag is set and if timeout is reached exit */
1114     while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1115     {
1116       if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1117       {
1118         /* Enable the write protection for RTC registers */
1119         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1120 
1121         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1122 
1123         /* Process Unlocked */
1124         __HAL_UNLOCK(hrtc);
1125 
1126         return HAL_TIMEOUT;
1127       }
1128     }
1129 
1130     hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
1131     /* Configure the Alarm A Subseconds register */
1132     hrtc->Instance->ALRMASSR = subsecondtmpreg;
1133     /* Configure the Alarm state: Enable Alarm */
1134     __HAL_RTC_ALARMA_ENABLE(hrtc);
1135 
1136   /* Enable the write protection for RTC registers */
1137   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1138 
1139   /* Change RTC state back to READY */
1140   hrtc->State = HAL_RTC_STATE_READY;
1141 
1142   /* Process Unlocked */
1143   __HAL_UNLOCK(hrtc);
1144 
1145   return HAL_OK;
1146 }
1147 
1148 /**
1149   * @brief  Sets the specified RTC Alarm with Interrupt.
1150   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1151   *                the configuration information for RTC.
1152   * @param  sAlarm Pointer to Alarm structure
1153   * @param  Format Specifies the format of the entered parameters.
1154   *          This parameter can be one of the following values:
1155   *             @arg RTC_FORMAT_BIN: Binary data format
1156   *             @arg RTC_FORMAT_BCD: BCD data format
1157   * @note   The Alarm register can only be written when the corresponding Alarm
1158   *         is disabled (Use the HAL_RTC_DeactivateAlarm()).
1159   * @note   The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
1160   * @retval HAL status
1161   */
HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1162 HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1163 {
1164   __IO uint32_t count  = RTC_TIMEOUT_VALUE * (SystemCoreClock / 32U / 1000U);
1165        uint32_t tmpreg = 0U;
1166        uint32_t subsecondtmpreg = 0U;
1167 
1168   /* Check the parameters */
1169   assert_param(IS_RTC_FORMAT(Format));
1170   assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1171   assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask));
1172   assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel));
1173   assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds));
1174   assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask));
1175 
1176   /* Process Locked */
1177   __HAL_LOCK(hrtc);
1178 
1179   /* Change RTC state to BUSY */
1180   hrtc->State = HAL_RTC_STATE_BUSY;
1181 
1182   /* Check the data format (binary or BCD) and store the Alarm time and date
1183      configuration accordingly */
1184   if (Format == RTC_FORMAT_BIN)
1185   {
1186     if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1187     {
1188       assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours));
1189       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1190     }
1191     else
1192     {
1193       sAlarm->AlarmTime.TimeFormat = 0x00U;
1194       assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1195     }
1196     assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1197     assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1198 
1199     if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1200     {
1201       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay));
1202     }
1203     else
1204     {
1205       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay));
1206     }
1207 
1208     tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours)   << RTC_ALRMAR_HU_Pos)  | \
1209               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1210               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds))                       | \
1211               ((uint32_t)(sAlarm->AlarmTime.TimeFormat)            << RTC_TR_PM_Pos)      | \
1212               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay)  << RTC_ALRMAR_DU_Pos)  | \
1213               ((uint32_t)sAlarm->AlarmDateWeekDaySel)                                     | \
1214               ((uint32_t)sAlarm->AlarmMask));
1215   }
1216   else
1217   {
1218     if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1219     {
1220       assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1221       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1222     }
1223     else
1224     {
1225       sAlarm->AlarmTime.TimeFormat = 0x00U;
1226       assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1227     }
1228 
1229     assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1230     assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1231 
1232     if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1233     {
1234       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1235     }
1236     else
1237     {
1238       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1239     }
1240 
1241     tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours)      << RTC_ALRMAR_HU_Pos)  | \
1242               ((uint32_t)(sAlarm->AlarmTime.Minutes)    << RTC_ALRMAR_MNU_Pos) | \
1243               ((uint32_t) sAlarm->AlarmTime.Seconds)                           | \
1244               ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_TR_PM_Pos)      | \
1245               ((uint32_t)(sAlarm->AlarmDateWeekDay)     << RTC_ALRMAR_DU_Pos)  | \
1246               ((uint32_t) sAlarm->AlarmDateWeekDaySel)                         | \
1247               ((uint32_t) sAlarm->AlarmMask));
1248   }
1249 
1250   /* Store the Alarm subseconds configuration */
1251   subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | \
1252                                (uint32_t)(sAlarm->AlarmSubSecondMask));
1253 
1254   /* Disable the write protection for RTC registers */
1255   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1256 
1257     /* Disable the Alarm A */
1258     __HAL_RTC_ALARMA_DISABLE(hrtc);
1259 
1260     /* Clear the Alarm flag */
1261     __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1262 
1263     /* Wait till RTC ALRAWF flag is set and if timeout is reached exit */
1264     do
1265     {
1266       count = count - 1U;
1267       if (count == 0U)
1268       {
1269         /* Enable the write protection for RTC registers */
1270         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1271 
1272         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1273 
1274         /* Process Unlocked */
1275         __HAL_UNLOCK(hrtc);
1276 
1277         return HAL_TIMEOUT;
1278       }
1279     } while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U);
1280 
1281     hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
1282     /* Configure the Alarm A Subseconds register */
1283     hrtc->Instance->ALRMASSR = subsecondtmpreg;
1284     /* Configure the Alarm state: Enable Alarm */
1285     __HAL_RTC_ALARMA_ENABLE(hrtc);
1286     /* Configure the Alarm interrupt */
1287     __HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRA);
1288 
1289   /* RTC Alarm Interrupt Configuration: EXTI configuration */
1290   __HAL_RTC_ALARM_EXTI_ENABLE_IT();
1291   __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
1292 
1293   /* Enable the write protection for RTC registers */
1294   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1295 
1296   /* Change RTC state back to READY */
1297   hrtc->State = HAL_RTC_STATE_READY;
1298 
1299   /* Process Unlocked */
1300   __HAL_UNLOCK(hrtc);
1301 
1302   return HAL_OK;
1303 }
1304 
1305 /**
1306   * @brief  Deactivates the specified RTC Alarm.
1307   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1308   *                the configuration information for RTC.
1309   * @param  Alarm Specifies the Alarm.
1310   *          This parameter can be:
1311   *            @arg RTC_ALARM_A: Alarm A
1312   * @retval HAL status
1313   */
HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef * hrtc,uint32_t Alarm)1314 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
1315 {
1316   uint32_t tickstart = 0U;
1317 
1318   /* Check the parameters */
1319   assert_param(IS_RTC_ALARM(Alarm));
1320 
1321   /* Process Locked */
1322   __HAL_LOCK(hrtc);
1323 
1324   hrtc->State = HAL_RTC_STATE_BUSY;
1325 
1326   /* Disable the write protection for RTC registers */
1327   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1328 
1329     /* Disable Alarm A */
1330     __HAL_RTC_ALARMA_DISABLE(hrtc);
1331 
1332     /* In case interrupt mode is used, the interrupt source must be disabled */
1333     __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1334 
1335     /* Get tick */
1336     tickstart = HAL_GetTick();
1337 
1338     /* Wait till RTC ALRxWF flag is set and if timeout is reached exit */
1339     while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1340     {
1341       if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1342       {
1343         /* Enable the write protection for RTC registers */
1344         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1345 
1346         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1347 
1348         /* Process Unlocked */
1349         __HAL_UNLOCK(hrtc);
1350 
1351         return HAL_TIMEOUT;
1352       }
1353     }
1354 
1355   /* Enable the write protection for RTC registers */
1356   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1357 
1358   hrtc->State = HAL_RTC_STATE_READY;
1359 
1360   /* Process Unlocked */
1361   __HAL_UNLOCK(hrtc);
1362 
1363   return HAL_OK;
1364 }
1365 
1366 /**
1367   * @brief  Gets the RTC Alarm value and masks.
1368   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1369   *                the configuration information for RTC.
1370   * @param  sAlarm Pointer to Date structure
1371   * @param  Alarm Specifies the Alarm.
1372   *          This parameter can be:
1373   *            @arg RTC_ALARM_A: Alarm A
1374   * @param  Format Specifies the format of the entered parameters.
1375   *          This parameter can be one of the following values:
1376   *             @arg RTC_FORMAT_BIN: Binary data format
1377   *             @arg RTC_FORMAT_BCD: BCD data format
1378   * @retval HAL status
1379   */
HAL_RTC_GetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Alarm,uint32_t Format)1380 HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
1381 {
1382   uint32_t tmpreg = 0U;
1383   uint32_t subsecondtmpreg = 0U;
1384 
1385   /* Check the parameters */
1386   assert_param(IS_RTC_FORMAT(Format));
1387   assert_param(IS_RTC_ALARM(Alarm));
1388 
1389   sAlarm->Alarm = RTC_ALARM_A;
1390 
1391   tmpreg = (uint32_t)(hrtc->Instance->ALRMAR);
1392   subsecondtmpreg = (uint32_t)((hrtc->Instance->ALRMASSR) & RTC_ALRMASSR_SS);
1393 
1394   /* Fill the structure with the read parameters */
1395   sAlarm->AlarmTime.Hours      = (uint8_t) ((tmpreg & (RTC_ALRMAR_HT  | RTC_ALRMAR_HU))  >> RTC_ALRMAR_HU_Pos);
1396   sAlarm->AlarmTime.Minutes    = (uint8_t) ((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> RTC_ALRMAR_MNU_Pos);
1397   sAlarm->AlarmTime.Seconds    = (uint8_t) ( tmpreg & (RTC_ALRMAR_ST  | RTC_ALRMAR_SU));
1398   sAlarm->AlarmTime.TimeFormat = (uint8_t) ((tmpreg & RTC_ALRMAR_PM)                     >> RTC_TR_PM_Pos);
1399   sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg;
1400   sAlarm->AlarmDateWeekDay     = (uint8_t) ((tmpreg & (RTC_ALRMAR_DT  | RTC_ALRMAR_DU))  >> RTC_ALRMAR_DU_Pos);
1401   sAlarm->AlarmDateWeekDaySel  = (uint32_t) (tmpreg & RTC_ALRMAR_WDSEL);
1402   sAlarm->AlarmMask            = (uint32_t) (tmpreg & RTC_ALARMMASK_ALL);
1403 
1404   if (Format == RTC_FORMAT_BIN)
1405   {
1406     sAlarm->AlarmTime.Hours   = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours);
1407     sAlarm->AlarmTime.Minutes = RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes);
1408     sAlarm->AlarmTime.Seconds = RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds);
1409     sAlarm->AlarmDateWeekDay  = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1410   }
1411 
1412   return HAL_OK;
1413 }
1414 
1415 /**
1416   * @brief  Handles Alarm interrupt request.
1417   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1418   *                the configuration information for RTC.
1419   * @retval None
1420   */
HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef * hrtc)1421 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc)
1422 {
1423   /* Clear the EXTI's line Flag for RTC Alarm */
1424   __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
1425 
1426   /* Get the Alarm A interrupt source enable status */
1427   if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA) != 0U)
1428   {
1429     /* Get the pending status of the Alarm A Interrupt */
1430     if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != 0U)
1431     {
1432       /* Clear the Alarm A interrupt pending bit */
1433       __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1434 
1435       /* Alarm A callback */
1436 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1437       hrtc->AlarmAEventCallback(hrtc);
1438 #else
1439       HAL_RTC_AlarmAEventCallback(hrtc);
1440 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
1441     }
1442   }
1443 
1444   /* Change RTC state */
1445   hrtc->State = HAL_RTC_STATE_READY;
1446 }
1447 
1448 /**
1449   * @brief  Alarm A callback.
1450   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1451   *                the configuration information for RTC.
1452   * @retval None
1453   */
HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef * hrtc)1454 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
1455 {
1456   /* Prevent unused argument(s) compilation warning */
1457   UNUSED(hrtc);
1458 
1459   /* NOTE: This function should not be modified, when the callback is needed,
1460            the HAL_RTC_AlarmAEventCallback could be implemented in the user file
1461    */
1462 }
1463 
1464 /**
1465   * @brief  Handles Alarm A Polling request.
1466   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1467   *                the configuration information for RTC.
1468   * @param  Timeout Timeout duration
1469   * @retval HAL status
1470   */
HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)1471 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
1472 {
1473   uint32_t tickstart = 0U;
1474 
1475   /* Get tick */
1476   tickstart = HAL_GetTick();
1477 
1478   /* Wait till RTC ALRAF flag is set and if timeout is reached exit */
1479   while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == 0U)
1480   {
1481     if (Timeout != HAL_MAX_DELAY)
1482     {
1483       if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1484       {
1485         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1486         return HAL_TIMEOUT;
1487       }
1488     }
1489   }
1490 
1491   /* Clear the Alarm flag */
1492   __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1493 
1494   /* Change RTC state */
1495   hrtc->State = HAL_RTC_STATE_READY;
1496 
1497   return HAL_OK;
1498 }
1499 
1500 /**
1501   * @}
1502   */
1503 
1504 /** @defgroup RTC_Exported_Functions_Group4 Peripheral Control functions
1505   * @brief    Peripheral Control functions
1506   *
1507 @verbatim
1508  ===============================================================================
1509                      ##### Peripheral Control functions #####
1510  ===============================================================================
1511     [..]
1512     This subsection provides functions allowing to
1513       (+) Wait for RTC Time and Date Synchronization
1514       (+) Manage RTC Summer or Winter time change
1515 
1516 @endverbatim
1517   * @{
1518   */
1519 
1520 /**
1521   * @brief  Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are
1522   *         synchronized with RTC APB clock.
1523   * @note   The RTC Resynchronization mode is write protected, use the
1524   *         __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
1525   * @note   To read the calendar through the shadow registers after Calendar
1526   *         initialization, calendar update or after wakeup from low power modes
1527   *         the software must first clear the RSF flag.
1528   *         The software must then wait until it is set again before reading
1529   *         the calendar, which means that the calendar registers have been
1530   *         correctly copied into the RTC_TR and RTC_DR shadow registers.
1531   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1532   *                the configuration information for RTC.
1533   * @retval HAL status
1534   */
HAL_RTC_WaitForSynchro(RTC_HandleTypeDef * hrtc)1535 HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc)
1536 {
1537   uint32_t tickstart = 0U;
1538 
1539   /* Clear RSF flag, keep reserved bits at reset values (setting other flags has no effect) */
1540   hrtc->Instance->ISR = ((uint32_t)(RTC_RSF_MASK & RTC_ISR_RESERVED_MASK));
1541 
1542   /* Get tick */
1543   tickstart = HAL_GetTick();
1544 
1545   /* Wait the registers to be synchronised */
1546   while ((hrtc->Instance->ISR & RTC_ISR_RSF) == 0U)
1547   {
1548     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1549     {
1550       return HAL_TIMEOUT;
1551     }
1552   }
1553 
1554   return HAL_OK;
1555 }
1556 
1557 /**
1558   * @brief  Daylight Saving Time, adds one hour to the calendar in one
1559   *         single operation without going through the initialization procedure.
1560   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1561   *                the configuration information for RTC.
1562   * @retval None
1563   */
HAL_RTC_DST_Add1Hour(RTC_HandleTypeDef * hrtc)1564 void HAL_RTC_DST_Add1Hour(RTC_HandleTypeDef *hrtc)
1565 {
1566   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1567   SET_BIT(hrtc->Instance->CR, RTC_CR_ADD1H);
1568   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1569 }
1570 
1571 /**
1572   * @brief  Daylight Saving Time, subtracts one hour from the calendar in one
1573   *         single operation without going through the initialization procedure.
1574   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1575   *                the configuration information for RTC.
1576   * @retval None
1577   */
HAL_RTC_DST_Sub1Hour(RTC_HandleTypeDef * hrtc)1578 void HAL_RTC_DST_Sub1Hour(RTC_HandleTypeDef *hrtc)
1579 {
1580   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1581   SET_BIT(hrtc->Instance->CR, RTC_CR_SUB1H);
1582   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1583 }
1584 
1585 /**
1586   * @brief  Daylight Saving Time, sets the store operation bit.
1587   * @note   It can be used by the software in order to memorize the DST status.
1588   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1589   *                the configuration information for RTC.
1590   * @retval None
1591   */
HAL_RTC_DST_SetStoreOperation(RTC_HandleTypeDef * hrtc)1592 void HAL_RTC_DST_SetStoreOperation(RTC_HandleTypeDef *hrtc)
1593 {
1594   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1595   SET_BIT(hrtc->Instance->CR, RTC_CR_BKP);
1596   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1597 }
1598 
1599 /**
1600   * @brief  Daylight Saving Time, clears the store operation bit.
1601   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1602   *                the configuration information for RTC.
1603   * @retval None
1604   */
HAL_RTC_DST_ClearStoreOperation(RTC_HandleTypeDef * hrtc)1605 void HAL_RTC_DST_ClearStoreOperation(RTC_HandleTypeDef *hrtc)
1606 {
1607   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1608   CLEAR_BIT(hrtc->Instance->CR, RTC_CR_BKP);
1609   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1610 }
1611 
1612 /**
1613   * @brief  Daylight Saving Time, reads the store operation bit.
1614   * @param  hrtc RTC handle
1615   * @retval operation see RTC_StoreOperation_Definitions
1616   */
HAL_RTC_DST_ReadStoreOperation(RTC_HandleTypeDef * hrtc)1617 uint32_t HAL_RTC_DST_ReadStoreOperation(RTC_HandleTypeDef *hrtc)
1618 {
1619   return READ_BIT(hrtc->Instance->CR, RTC_CR_BKP);
1620 }
1621 
1622 /**
1623   * @}
1624   */
1625 
1626 /** @defgroup RTC_Exported_Functions_Group5 Peripheral State functions
1627   * @brief    Peripheral State functions
1628   *
1629 @verbatim
1630  ===============================================================================
1631                      ##### Peripheral State functions #####
1632  ===============================================================================
1633     [..]
1634     This subsection provides functions allowing to
1635       (+) Get RTC state
1636 
1637 @endverbatim
1638   * @{
1639   */
1640 /**
1641   * @brief  Returns the RTC state.
1642   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1643   *                the configuration information for RTC.
1644   * @retval HAL state
1645   */
HAL_RTC_GetState(RTC_HandleTypeDef * hrtc)1646 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc)
1647 {
1648   return hrtc->State;
1649 }
1650 
1651 /**
1652   * @}
1653   */
1654 
1655 
1656 /**
1657   * @}
1658   */
1659 
1660 /** @addtogroup RTC_Private_Functions
1661   * @{
1662   */
1663 
1664 /**
1665   * @brief  Enters the RTC Initialization mode.
1666   * @note   The RTC Initialization mode is write protected, use the
1667   *         __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
1668   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1669   *                the configuration information for RTC.
1670   * @retval HAL status
1671   */
RTC_EnterInitMode(RTC_HandleTypeDef * hrtc)1672 HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
1673 {
1674   uint32_t tickstart = 0U;
1675   HAL_StatusTypeDef status = HAL_OK;
1676 
1677   /* Check that Initialization mode is not already set */
1678   if (READ_BIT(hrtc->Instance->ISR, RTC_ISR_INITF) == 0U)
1679   {
1680     /* Set INIT bit to enter Initialization mode */
1681     SET_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
1682 
1683     /* Get tick */
1684     tickstart = HAL_GetTick();
1685 
1686     /* Wait till RTC is in INIT state and if timeout is reached exit */
1687     while ((READ_BIT(hrtc->Instance->ISR, RTC_ISR_INITF) == 0U) && (status != HAL_ERROR))
1688     {
1689       if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1690       {
1691         /* Set RTC state */
1692         hrtc->State = HAL_RTC_STATE_ERROR;
1693         status = HAL_ERROR;
1694       }
1695     }
1696   }
1697 
1698   return status;
1699 }
1700 
1701 /**
1702   * @brief  Exits the RTC Initialization mode.
1703   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
1704   *                the configuration information for RTC.
1705   * @retval HAL status
1706   */
RTC_ExitInitMode(RTC_HandleTypeDef * hrtc)1707 HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc)
1708 {
1709   HAL_StatusTypeDef status = HAL_OK;
1710 
1711   /* Clear INIT bit to exit Initialization mode */
1712   CLEAR_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
1713 
1714   /* If CR_BYPSHAD bit = 0, wait for synchro */
1715   if (READ_BIT(hrtc->Instance->CR, RTC_CR_BYPSHAD) == 0U)
1716   {
1717     if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
1718     {
1719       /* Set RTC state */
1720       hrtc->State = HAL_RTC_STATE_ERROR;
1721       status = HAL_ERROR;
1722     }
1723   }
1724 
1725   return status;
1726 }
1727 
1728 /**
1729   * @brief  Converts a 2-digit number from decimal to BCD format.
1730   * @param  number decimal-formatted number (from 0 to 99) to be converted
1731   * @retval Converted byte
1732   */
RTC_ByteToBcd2(uint8_t number)1733 uint8_t RTC_ByteToBcd2(uint8_t number)
1734 {
1735   uint32_t bcdhigh = 0U;
1736 
1737   while (number >= 10U)
1738   {
1739     bcdhigh++;
1740     number -= 10U;
1741   }
1742 
1743   return ((uint8_t)(bcdhigh << 4U) | number);
1744 }
1745 
1746 /**
1747   * @brief  Converts a 2-digit number from BCD to decimal format.
1748   * @param  number BCD-formatted number (from 00 to 99) to be converted
1749   * @retval Converted word
1750   */
RTC_Bcd2ToByte(uint8_t number)1751 uint8_t RTC_Bcd2ToByte(uint8_t number)
1752 {
1753   uint32_t tens = 0U;
1754   tens = (((uint32_t)number & 0xF0U) >> 4U) * 10U;
1755   return (uint8_t)(tens + ((uint32_t)number & 0x0FU));
1756 }
1757 
1758 /**
1759   * @}
1760   */
1761 
1762 #endif /* HAL_RTC_MODULE_ENABLED */
1763 /**
1764   * @}
1765   */
1766 
1767 /**
1768   * @}
1769   */
1770