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