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