1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_hal_rtc_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended RTC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Real-Time Clock (RTC) Extended peripheral:
8   *           + RTC Wakeup functions
9   *           + Extended Control functions
10   *           + Extended RTC features functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2024 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### How to use this driver #####
26   ==============================================================================
27   [..]
28     (+) Enable the RTC domain access.
29     (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour
30         format using the HAL_RTC_Init() function.
31 
32   *** RTC Wakeup configuration ***
33   ================================
34   [..]
35     (+) To configure the RTC Wakeup Clock source and Counter use the
36         HAL_RTCEx_SetWakeUpTimer() function.
37         You can also configure the RTC Wakeup timer in interrupt mode using the
38         HAL_RTCEx_SetWakeUpTimer_IT() function.
39     (+) To read the RTC Wakeup Counter register, use the HAL_RTCEx_GetWakeUpTimer()
40         function.
41 
42   *** Backup Data Registers configuration ***
43   ===========================================
44   [..]
45     (+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite()
46         function.
47     (+) To read the RTC Backup Data registers, use the HAL_RTCEx_BKUPRead()
48         function.
49 
50   *** Smooth Digital Calibration configuration ***
51   ================================================
52   [..]
53     (+) RTC frequency can be digitally calibrated with a resolution of about
54         0.954 ppm with a range from -487.1 ppm to +488.5 ppm.
55         The correction of the frequency is performed using a series of small
56         adjustments (adding and/or subtracting individual RTCCLK pulses).
57     (+) The smooth digital calibration is performed during a cycle of about 2^20
58         RTCCLK pulses (or 32 seconds) when the input frequency is 32,768 Hz.
59         This cycle is maintained by a 20-bit counter clocked by RTCCLK.
60     (+) The smooth calibration register (RTC_CALR) specifies the number of RTCCLK
61         clock cycles to be masked during the 32-second cycle.
62     (+) To configure the RTC Smooth Digital Calibration value and the corresponding
63         calibration cycle period (32s,16s and 8s) use the HAL_RTCEx_SetSmoothCalib()
64         function.
65 
66   @endverbatim
67   ******************************************************************************
68   */
69 
70 /* Includes ------------------------------------------------------------------*/
71 #include "stm32wb0x_hal.h"
72 
73 /** @addtogroup STM32WB0x_HAL_Driver
74   * @{
75   */
76 
77 /** @defgroup RTCEx RTCEx
78   * @brief    RTC Extended HAL module driver
79   * @{
80   */
81 
82 #ifdef HAL_RTC_MODULE_ENABLED
83 
84 /* Private typedef -----------------------------------------------------------*/
85 /* Private define ------------------------------------------------------------*/
86 /* Private macro -------------------------------------------------------------*/
87 /* Private variables ---------------------------------------------------------*/
88 /* Private function prototypes -----------------------------------------------*/
89 /* Exported functions --------------------------------------------------------*/
90 
91 /** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions
92   * @{
93   */
94 
95 /** @defgroup RTCEx_Exported_Functions_Group2 RTC Wakeup functions
96   * @brief    RTC Wakeup functions
97   *
98 @verbatim
99  ===============================================================================
100                         ##### RTC Wakeup functions #####
101  ===============================================================================
102 
103  [..] This section provides functions allowing to configure Wakeup feature
104 
105 @endverbatim
106   * @{
107   */
108 
109 /**
110   * @brief  Sets wakeup timer.
111   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
112   *                the configuration information for RTC.
113   * @param  WakeUpCounter Wakeup counter
114   * @param  WakeUpClock Wakeup clock
115   * @retval HAL status
116   */
HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef * hrtc,uint32_t WakeUpCounter,uint32_t WakeUpClock)117 HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock)
118 {
119   uint32_t tickstart = 0U;
120 
121   /* Check the parameters */
122   assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock));
123   assert_param(IS_RTC_WAKEUP_COUNTER(WakeUpCounter));
124 
125   /* Process Locked */
126   __HAL_LOCK(hrtc);
127 
128   hrtc->State = HAL_RTC_STATE_BUSY;
129 
130   /* Disable the write protection for RTC registers */
131   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
132 
133   /* Check RTC WUTWF flag is reset only when wakeup timer enabled*/
134   if ((hrtc->Instance->CR & RTC_CR_WUTE) != 0U)
135   {
136     tickstart = HAL_GetTick();
137 
138     /* Wait till RTC WUTWF flag is reset and if timeout is reached exit */
139     while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) != 0U)
140     {
141       if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
142       {
143         /* Enable the write protection for RTC registers */
144         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
145 
146         hrtc->State = HAL_RTC_STATE_TIMEOUT;
147 
148         /* Process Unlocked */
149         __HAL_UNLOCK(hrtc);
150 
151         return HAL_TIMEOUT;
152       }
153     }
154   }
155 
156   /* Disable the Wakeup timer */
157   __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc);
158 
159   /* Clear the Wakeup flag */
160   __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF);
161 
162   /* Get tick */
163   tickstart = HAL_GetTick();
164 
165   /* Wait till RTC WUTWF flag is set and if timeout is reached exit */
166   while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) == 0U)
167   {
168     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
169     {
170       /* Enable the write protection for RTC registers */
171       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
172 
173       hrtc->State = HAL_RTC_STATE_TIMEOUT;
174 
175       /* Process Unlocked */
176       __HAL_UNLOCK(hrtc);
177 
178       return HAL_TIMEOUT;
179     }
180   }
181 
182   /* Clear the Wakeup Timer clock source bits in CR register */
183   hrtc->Instance->CR &= (uint32_t)~RTC_CR_WUCKSEL;
184 
185   /* Configure the clock source */
186   hrtc->Instance->CR |= (uint32_t)WakeUpClock;
187 
188   /* Configure the Wakeup Timer counter */
189   hrtc->Instance->WUTR = (uint32_t)WakeUpCounter;
190 
191   /* Enable the Wakeup Timer */
192   __HAL_RTC_WAKEUPTIMER_ENABLE(hrtc);
193 
194   /* Enable the write protection for RTC registers */
195   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
196 
197   hrtc->State = HAL_RTC_STATE_READY;
198 
199   /* Process Unlocked */
200   __HAL_UNLOCK(hrtc);
201 
202   return HAL_OK;
203 }
204 
205 /**
206   * @brief  Sets wakeup timer with interrupt.
207   * @note   The application must ensure that the RTC interrupt line is configured via HAL SYSCFG services and the PWR_WAKEUP_PIN_RTC bit is set.
208   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
209   *                the configuration information for RTC.
210   * @param  WakeUpCounter Wakeup counter
211   * @param  WakeUpClock Wakeup clock
212   * @retval HAL status
213   */
HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef * hrtc,uint32_t WakeUpCounter,uint32_t WakeUpClock)214 HAL_StatusTypeDef HAL_RTCEx_SetWakeUpTimer_IT(RTC_HandleTypeDef *hrtc, uint32_t WakeUpCounter, uint32_t WakeUpClock)
215 {
216   __IO uint32_t count  = RTC_TIMEOUT_VALUE * (SystemCoreClock / 32U / 1000U);
217 
218   /* Check the parameters */
219   assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock));
220   assert_param(IS_RTC_WAKEUP_COUNTER(WakeUpCounter));
221 
222   /* Process Locked */
223   __HAL_LOCK(hrtc);
224 
225   hrtc->State = HAL_RTC_STATE_BUSY;
226 
227   /* Disable the write protection for RTC registers */
228   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
229 
230   /* Check RTC WUTWF flag is reset only when wakeup timer enabled */
231   if ((hrtc->Instance->CR & RTC_CR_WUTE) != 0U)
232   {
233     /* Wait till RTC WUTWF flag is reset and if timeout is reached exit */
234     do
235     {
236       count = count - 1U;
237       if (count == 0U)
238       {
239         /* Enable the write protection for RTC registers */
240         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
241 
242         hrtc->State = HAL_RTC_STATE_TIMEOUT;
243 
244         /* Process Unlocked */
245         __HAL_UNLOCK(hrtc);
246 
247         return HAL_TIMEOUT;
248       }
249     } while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) != 0U);
250   }
251 
252   /* Disable the Wakeup timer */
253   __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc);
254 
255   /* Clear the Wakeup flag */
256   __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF);
257 
258   /* Reload the counter */
259   count = RTC_TIMEOUT_VALUE * (SystemCoreClock / 32U / 1000U);
260 
261   /* Wait till RTC WUTWF flag is set and if timeout is reached exit */
262   do
263   {
264     count = count - 1U;
265     if (count == 0U)
266     {
267       /* Enable the write protection for RTC registers */
268       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
269 
270       hrtc->State = HAL_RTC_STATE_TIMEOUT;
271 
272       /* Process Unlocked */
273       __HAL_UNLOCK(hrtc);
274 
275       return HAL_TIMEOUT;
276     }
277   } while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) == 0U);
278 
279   /* Clear the Wakeup Timer clock source bits in CR register */
280   hrtc->Instance->CR &= (uint32_t)~RTC_CR_WUCKSEL;
281 
282   /* Configure the clock source */
283   hrtc->Instance->CR |= (uint32_t)WakeUpClock;
284 
285   /* Configure the Wakeup Timer counter */
286   hrtc->Instance->WUTR = (uint32_t)WakeUpCounter;
287 
288   /* Configure the interrupt in the RTC_CR register */
289   __HAL_RTC_WAKEUPTIMER_ENABLE_IT(hrtc, RTC_IT_WUT);
290 
291   /* Enable the Wakeup Timer */
292   __HAL_RTC_WAKEUPTIMER_ENABLE(hrtc);
293 
294   /* Enable the write protection for RTC registers */
295   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
296 
297   hrtc->State = HAL_RTC_STATE_READY;
298 
299   /* Process Unlocked */
300   __HAL_UNLOCK(hrtc);
301 
302   return HAL_OK;
303 }
304 
305 /**
306   * @brief  Deactivates wakeup timer counter.
307   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
308   *                the configuration information for RTC.
309   * @retval HAL status
310   */
HAL_RTCEx_DeactivateWakeUpTimer(RTC_HandleTypeDef * hrtc)311 HAL_StatusTypeDef HAL_RTCEx_DeactivateWakeUpTimer(RTC_HandleTypeDef *hrtc)
312 {
313   uint32_t tickstart = 0U;
314 
315   /* Process Locked */
316   __HAL_LOCK(hrtc);
317 
318   hrtc->State = HAL_RTC_STATE_BUSY;
319 
320   /* Disable the write protection for RTC registers */
321   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
322 
323   /* Disable the Wakeup Timer */
324   __HAL_RTC_WAKEUPTIMER_DISABLE(hrtc);
325 
326   /* In case of interrupt mode is used, the interrupt source must disabled */
327   __HAL_RTC_WAKEUPTIMER_DISABLE_IT(hrtc, RTC_IT_WUT);
328 
329   /* Get tick */
330   tickstart = HAL_GetTick();
331 
332   /* Wait till RTC WUTWF flag is set and if timeout is reached exit */
333   while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTWF) == 0U)
334   {
335     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
336     {
337       /* Enable the write protection for RTC registers */
338       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
339 
340       hrtc->State = HAL_RTC_STATE_TIMEOUT;
341 
342       /* Process Unlocked */
343       __HAL_UNLOCK(hrtc);
344 
345       return HAL_TIMEOUT;
346     }
347   }
348 
349   /* Enable the write protection for RTC registers */
350   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
351 
352   hrtc->State = HAL_RTC_STATE_READY;
353 
354   /* Process Unlocked */
355   __HAL_UNLOCK(hrtc);
356 
357   return HAL_OK;
358 }
359 
360 /**
361   * @brief  Gets wakeup timer counter.
362   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
363   *                the configuration information for RTC.
364   * @retval Counter value
365   */
HAL_RTCEx_GetWakeUpTimer(RTC_HandleTypeDef * hrtc)366 uint32_t HAL_RTCEx_GetWakeUpTimer(RTC_HandleTypeDef *hrtc)
367 {
368   /* Get the counter value */
369   return ((uint32_t)(hrtc->Instance->WUTR & RTC_WUTR_WUT));
370 }
371 
372 /**
373   * @brief  Handles Wakeup Timer interrupt request.
374   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
375   *                the configuration information for RTC.
376   * @retval None
377   */
HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef * hrtc)378 void HAL_RTCEx_WakeUpTimerIRQHandler(RTC_HandleTypeDef *hrtc)
379 {
380   /* Get the pending status of the Wakeup timer Interrupt */
381   if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTF) != 0U)
382   {
383     /* Clear the Wakeup timer interrupt pending bit */
384     __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF);
385 
386     /* Wakeup timer callback */
387 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
388     hrtc->WakeUpTimerEventCallback(hrtc);
389 #else
390     HAL_RTCEx_WakeUpTimerEventCallback(hrtc);
391 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
392   }
393 
394   /* Change RTC state */
395   hrtc->State = HAL_RTC_STATE_READY;
396 }
397 
398 /**
399   * @brief  Wakeup Timer callback.
400   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
401   *                the configuration information for RTC.
402   * @retval None
403   */
HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef * hrtc)404 __weak void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
405 {
406   /* Prevent unused argument(s) compilation warning */
407   UNUSED(hrtc);
408 
409   /* NOTE: This function should not be modified, when the callback is needed,
410            the HAL_RTCEx_WakeUpTimerEventCallback could be implemented in the user file
411    */
412 }
413 
414 /**
415   * @brief  Handles Wakeup Timer Polling.
416   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
417   *                the configuration information for RTC.
418   * @param  Timeout Timeout duration
419   * @retval HAL status
420   */
HAL_RTCEx_PollForWakeUpTimerEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)421 HAL_StatusTypeDef HAL_RTCEx_PollForWakeUpTimerEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
422 {
423   uint32_t tickstart = 0U;
424 
425   /* Get tick */
426   tickstart = HAL_GetTick();
427 
428   while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(hrtc, RTC_FLAG_WUTF) == 0U)
429   {
430     if (Timeout != HAL_MAX_DELAY)
431     {
432       if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
433       {
434         hrtc->State = HAL_RTC_STATE_TIMEOUT;
435         return HAL_TIMEOUT;
436       }
437     }
438   }
439 
440   /* Clear the Wakeup timer Flag */
441   __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF);
442 
443   /* Change RTC state */
444   hrtc->State = HAL_RTC_STATE_READY;
445 
446   return HAL_OK;
447 }
448 
449 /**
450   * @}
451   */
452 
453 /** @defgroup RTCEx_Exported_Functions_Group3 Extended Peripheral Control functions
454   * @brief    Extended Peripheral Control functions
455   *
456 @verbatim
457  ===============================================================================
458               ##### Extended Peripheral Control functions #####
459  ===============================================================================
460     [..]
461     This subsection provides functions allowing to
462       (+) Write a data in a specified RTC Backup data register
463       (+) Read a data in a specified RTC Backup data register
464       (+) Set the Smooth calibration parameters.
465       (+) Configure the Synchronization Shift Control Settings.
466       (+) Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
467       (+) Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
468       (+) Enable the RTC reference clock detection.
469       (+) Disable the RTC reference clock detection.
470       (+) Enable the Bypass Shadow feature.
471       (+) Disable the Bypass Shadow feature.
472 
473 @endverbatim
474   * @{
475   */
476 
477 /**
478   * @brief  Writes a data in a specified RTC Backup data register.
479   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
480   *                the configuration information for RTC.
481   * @param  BackupRegister RTC Backup data Register number.
482   *          This parameter can be: RTC_BKP_DRx (where x can be from 0 to 1)
483   *                                 to specify the register.
484   * @param  Data Data to be written in the specified RTC Backup data register.
485   * @retval None
486   */
HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef * hrtc,uint32_t BackupRegister,uint32_t Data)487 void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
488 {
489   uint32_t tmp = 0U;
490 
491   /* Check the parameters */
492   assert_param(IS_RTC_BKP(BackupRegister));
493 
494   tmp = (uint32_t) & (hrtc->Instance->BKP0R);
495   tmp += (BackupRegister * 4U);
496 
497   /* Write the specified register */
498   *(__IO uint32_t *)tmp = (uint32_t)Data;
499 }
500 
501 /**
502   * @brief  Reads data from the specified RTC Backup data Register.
503   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
504   *                the configuration information for RTC.
505   * @param  BackupRegister RTC Backup data Register number.
506   *          This parameter can be: RTC_BKP_DRx (where x can be from 0 to 1)
507   *                                 to specify the register.
508   * @retval Read value
509   */
HAL_RTCEx_BKUPRead(RTC_HandleTypeDef * hrtc,uint32_t BackupRegister)510 uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister)
511 {
512   uint32_t tmp = 0U;
513 
514   /* Check the parameters */
515   assert_param(IS_RTC_BKP(BackupRegister));
516 
517   tmp = (uint32_t) & (hrtc->Instance->BKP0R);
518   tmp += (BackupRegister * 4U);
519 
520   /* Read the specified register */
521   return (*(__IO uint32_t *)tmp);
522 }
523 
524 /**
525   * @brief  Sets the Smooth calibration parameters.
526   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
527   *                the configuration information for RTC.
528   * @param  SmoothCalibPeriod Select the Smooth Calibration Period.
529   *          This parameter can be can be one of the following values:
530   *             @arg RTC_SMOOTHCALIB_PERIOD_32SEC: The smooth calibration period is 32s.
531   *             @arg RTC_SMOOTHCALIB_PERIOD_16SEC: The smooth calibration period is 16s.
532   *             @arg RTC_SMOOTHCALIB_PERIOD_8SEC: The smooth calibration period is 8s.
533   * @param  SmoothCalibPlusPulses Select to Set or reset the CALP bit.
534   *          This parameter can be one of the following values:
535   *             @arg RTC_SMOOTHCALIB_PLUSPULSES_SET: Add one RTCCLK pulse every 2*11 pulses.
536   *             @arg RTC_SMOOTHCALIB_PLUSPULSES_RESET: No RTCCLK pulses are added.
537   * @param  SmoothCalibMinusPulsesValue Select the value of CALM[8:0] bits.
538   *          This parameter can be one any value from 0 to 0x000001FF.
539   * @note   To deactivate the smooth calibration, the field SmoothCalibPlusPulses
540   *         must be equal to SMOOTHCALIB_PLUSPULSES_RESET and the field
541   *         SmoothCalibMinusPulsesValue must be equal to 0.
542   * @retval HAL status
543   */
HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef * hrtc,uint32_t SmoothCalibPeriod,uint32_t SmoothCalibPlusPulses,uint32_t SmoothCalibMinusPulsesValue)544 HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef *hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmoothCalibMinusPulsesValue)
545 {
546   uint32_t tickstart = 0U;
547 
548   /* Check the parameters */
549   assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(SmoothCalibPeriod));
550   assert_param(IS_RTC_SMOOTH_CALIB_PLUS(SmoothCalibPlusPulses));
551   assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmoothCalibMinusPulsesValue));
552 
553   /* Process Locked */
554   __HAL_LOCK(hrtc);
555 
556   hrtc->State = HAL_RTC_STATE_BUSY;
557 
558   /* Disable the write protection for RTC registers */
559   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
560 
561   /* check if a calibration is pending*/
562   if ((hrtc->Instance->ISR & RTC_ISR_RECALPF) != 0U)
563   {
564     /* Get tick */
565     tickstart = HAL_GetTick();
566 
567     /* check if a calibration is pending*/
568     while ((hrtc->Instance->ISR & RTC_ISR_RECALPF) != 0U)
569     {
570       if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
571       {
572         /* Enable the write protection for RTC registers */
573         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
574 
575         /* Change RTC state */
576         hrtc->State = HAL_RTC_STATE_TIMEOUT;
577 
578         /* Process Unlocked */
579         __HAL_UNLOCK(hrtc);
580 
581         return HAL_TIMEOUT;
582       }
583     }
584   }
585 
586   /* Configure the Smooth calibration settings */
587   hrtc->Instance->CALR = (uint32_t)((uint32_t)SmoothCalibPeriod     | \
588                                     (uint32_t)SmoothCalibPlusPulses | \
589                                     (uint32_t)SmoothCalibMinusPulsesValue);
590 
591   /* Enable the write protection for RTC registers */
592   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
593 
594   /* Change RTC state */
595   hrtc->State = HAL_RTC_STATE_READY;
596 
597   /* Process Unlocked */
598   __HAL_UNLOCK(hrtc);
599 
600   return HAL_OK;
601 }
602 
603 /**
604   * @brief  Configures the Synchronization Shift Control Settings.
605   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
606   *                the configuration information for RTC.
607   * @param  ShiftAdd1S Select to add or not 1 second to the time calendar.
608   *          This parameter can be one of the following values:
609   *             @arg RTC_SHIFTADD1S_SET: Add one second to the clock calendar.
610   *             @arg RTC_SHIFTADD1S_RESET: No effect.
611   * @param  ShiftSubFS Select the number of Second Fractions to substitute.
612   *          This parameter can be one any value from 0 to 0x7FFF.
613   * @retval HAL status
614   */
HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef * hrtc,uint32_t ShiftAdd1S,uint32_t ShiftSubFS)615 HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef *hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS)
616 {
617   uint32_t tickstart = 0U;
618 
619   /* Check the parameters */
620   assert_param(IS_RTC_SHIFT_ADD1S(ShiftAdd1S));
621   assert_param(IS_RTC_SHIFT_SUBFS(ShiftSubFS));
622 
623   /* Process Locked */
624   __HAL_LOCK(hrtc);
625 
626   hrtc->State = HAL_RTC_STATE_BUSY;
627 
628   /* Disable the write protection for RTC registers */
629   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
630 
631   /* Get tick */
632   tickstart = HAL_GetTick();
633 
634   /* Wait until the shift is completed */
635   while ((hrtc->Instance->ISR & RTC_ISR_SHPF) != 0U)
636   {
637     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
638     {
639       /* Enable the write protection for RTC registers */
640       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
641 
642       hrtc->State = HAL_RTC_STATE_TIMEOUT;
643 
644       /* Process Unlocked */
645       __HAL_UNLOCK(hrtc);
646 
647       return HAL_TIMEOUT;
648     }
649   }
650 
651   /* Configure the Shift settings */
652   hrtc->Instance->SHIFTR = (uint32_t)(uint32_t)(ShiftSubFS) | (uint32_t)(ShiftAdd1S);
653 
654   /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
655   if ((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
656   {
657     if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
658     {
659       /* Enable the write protection for RTC registers */
660       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
661 
662       hrtc->State = HAL_RTC_STATE_ERROR;
663 
664       /* Process Unlocked */
665       __HAL_UNLOCK(hrtc);
666 
667       return HAL_ERROR;
668     }
669   }
670 
671   /* Enable the write protection for RTC registers */
672   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
673 
674   /* Change RTC state */
675   hrtc->State = HAL_RTC_STATE_READY;
676 
677   /* Process Unlocked */
678   __HAL_UNLOCK(hrtc);
679 
680   return HAL_OK;
681 }
682 
683 /**
684   * @brief  Configures the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
685   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
686   *                the configuration information for RTC.
687   * @param  CalibOutput Select the Calibration output Selection.
688   *          This parameter can be one of the following values:
689   *             @arg RTC_CALIBOUTPUT_512HZ: A signal has a regular waveform at 512Hz.
690   *             @arg RTC_CALIBOUTPUT_1HZ: A signal has a regular waveform at 1Hz.
691   * @retval HAL status
692   */
HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef * hrtc,uint32_t CalibOutput)693 HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef *hrtc, uint32_t CalibOutput)
694 {
695   /* Check the parameters */
696   assert_param(IS_RTC_CALIB_OUTPUT(CalibOutput));
697 
698   /* Process Locked */
699   __HAL_LOCK(hrtc);
700 
701   hrtc->State = HAL_RTC_STATE_BUSY;
702 
703   /* Disable the write protection for RTC registers */
704   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
705 
706   /* Clear flags before config */
707   hrtc->Instance->CR &= (uint32_t)~RTC_CR_COSEL;
708 
709   /* Configure the RTC_CR register */
710   hrtc->Instance->CR |= (uint32_t)CalibOutput;
711 
712   __HAL_RTC_CALIBRATION_OUTPUT_ENABLE(hrtc);
713 
714   /* Enable the write protection for RTC registers */
715   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
716 
717   /* Change RTC state */
718   hrtc->State = HAL_RTC_STATE_READY;
719 
720   /* Process Unlocked */
721   __HAL_UNLOCK(hrtc);
722 
723   return HAL_OK;
724 }
725 
726 /**
727   * @brief  Deactivates the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
728   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
729   *                the configuration information for RTC.
730   * @retval HAL status
731   */
HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef * hrtc)732 HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef *hrtc)
733 {
734   /* Process Locked */
735   __HAL_LOCK(hrtc);
736 
737   hrtc->State = HAL_RTC_STATE_BUSY;
738 
739   /* Disable the write protection for RTC registers */
740   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
741 
742   __HAL_RTC_CALIBRATION_OUTPUT_DISABLE(hrtc);
743 
744   /* Enable the write protection for RTC registers */
745   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
746 
747   /* Change RTC state */
748   hrtc->State = HAL_RTC_STATE_READY;
749 
750   /* Process Unlocked */
751   __HAL_UNLOCK(hrtc);
752 
753   return HAL_OK;
754 }
755 
756 /**
757   * @brief  Enables the Bypass Shadow feature.
758   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
759   *                the configuration information for RTC.
760   * @note   When the Bypass Shadow is enabled the calendar value are taken
761   *         directly from the Calendar counter.
762   * @retval HAL status
763   */
HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef * hrtc)764 HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef *hrtc)
765 {
766   /* Process Locked */
767   __HAL_LOCK(hrtc);
768 
769   hrtc->State = HAL_RTC_STATE_BUSY;
770 
771   /* Disable the write protection for RTC registers */
772   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
773 
774   /* Set the BYPSHAD bit */
775   hrtc->Instance->CR |= (uint8_t)RTC_CR_BYPSHAD;
776 
777   /* Enable the write protection for RTC registers */
778   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
779 
780   /* Change RTC state */
781   hrtc->State = HAL_RTC_STATE_READY;
782 
783   /* Process Unlocked */
784   __HAL_UNLOCK(hrtc);
785 
786   return HAL_OK;
787 }
788 
789 /**
790   * @brief  Disables the Bypass Shadow feature.
791   * @param  hrtc pointer to a RTC_HandleTypeDef structure that contains
792   *                the configuration information for RTC.
793   * @note   When the Bypass Shadow is enabled the calendar value are taken
794   *         directly from the Calendar counter.
795   * @retval HAL status
796   */
HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef * hrtc)797 HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef *hrtc)
798 {
799   /* Process Locked */
800   __HAL_LOCK(hrtc);
801 
802   hrtc->State = HAL_RTC_STATE_BUSY;
803 
804   /* Disable the write protection for RTC registers */
805   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
806 
807   /* Reset the BYPSHAD bit */
808   hrtc->Instance->CR &= (uint8_t)~RTC_CR_BYPSHAD;
809 
810   /* Enable the write protection for RTC registers */
811   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
812 
813   /* Change RTC state */
814   hrtc->State = HAL_RTC_STATE_READY;
815 
816   /* Process Unlocked */
817   __HAL_UNLOCK(hrtc);
818 
819   return HAL_OK;
820 }
821 
822 /**
823   * @}
824   */
825 
826 /**
827   * @}
828   */
829 
830 #endif /* HAL_RTC_MODULE_ENABLED */
831 /**
832   * @}
833   */
834 
835 /**
836   * @}
837   */
838