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