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