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