1 /**
2   ******************************************************************************
3   * @file    stm32c0xx_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 Time Stamp functions
9   *           + Extended Control functions
10   *           + Extended RTC features functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2022 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   *** Outputs configuration ***
33   =============================
34   [..]  The RTC has 2 different outputs:
35     (+) RTC_ALARM: this output is used to manage the RTC Alarm A.
36         To output the selected RTC signal, use the HAL_RTC_Init() function.
37     (+) RTC_CALIB: this output is 512Hz signal or 1Hz.
38         To enable the RTC_CALIB, use the HAL_RTCEx_SetCalibrationOutPut() function.
39     (+) Two pins can be used as RTC_ALARM or RTC_CALIB (PC13, PB2) managed on
40         the RTC_OR register.
41     (+) When the RTC_CALIB or RTC_ALARM output is selected, the RTC_OUT pin is
42         automatically configured in output alternate function.
43 
44   *** Smooth digital Calibration configuration ***
45   ================================================
46   [..]
47     (+) Configure the RTC Original Digital Calibration Value and the corresponding
48         calibration cycle period (32s,16s and 8s) using the HAL_RTCEx_SetSmoothCalib()
49         function.
50 
51   *** TimeStamp configuration ***
52   ===============================
53   [..]
54     (+) Enable the RTC TimeStamp using the HAL_RTCEx_SetTimeStamp() function.
55         You can also configure the RTC TimeStamp with interrupt mode using the
56         HAL_RTCEx_SetTimeStamp_IT() function.
57     (+) To read the RTC TimeStamp Time and Date register, use the HAL_RTCEx_GetTimeStamp()
58         function.
59 
60    @endverbatim
61   ******************************************************************************
62   */
63 
64 /* Includes ------------------------------------------------------------------*/
65 #include "stm32c0xx_hal.h"
66 
67 /** @addtogroup STM32C0xx_HAL_Driver
68   * @{
69   */
70 
71 /** @addtogroup RTCEx
72   * @brief RTC Extended HAL module driver
73   * @{
74   */
75 
76 #ifdef HAL_RTC_MODULE_ENABLED
77 
78 /* Private typedef -----------------------------------------------------------*/
79 /* Private define ------------------------------------------------------------*/
80 /* Private macro -------------------------------------------------------------*/
81 /* Private variables ---------------------------------------------------------*/
82 /* Private function prototypes -----------------------------------------------*/
83 /* Exported functions --------------------------------------------------------*/
84 
85 /** @addtogroup RTCEx_Exported_Functions
86   * @{
87   */
88 
89 
90 /** @addtogroup RTCEx_Exported_Functions_Group1
91   *  @brief   RTC TimeStamp and Tamper functions
92   *
93 @verbatim
94  ===============================================================================
95                  ##### RTC TimeStamp and Tamper functions #####
96  ===============================================================================
97 
98  [..] This section provides functions allowing to configure TimeStamp feature
99 
100 @endverbatim
101   * @{
102   */
103 
104 /**
105   * @brief  Set TimeStamp.
106   * @note   This API must be called before enabling the TimeStamp feature.
107   * @param  hrtc RTC handle
108   * @param  TimeStampEdge Specifies the pin edge on which the TimeStamp is
109   *         activated.
110   *          This parameter can be one of the following values:
111   *             @arg RTC_TIMESTAMPEDGE_RISING: the Time stamp event occurs on the
112   *                                        rising edge of the related pin.
113   *             @arg RTC_TIMESTAMPEDGE_FALLING: the Time stamp event occurs on the
114   *                                         falling edge of the related pin.
115   * @param  RTC_TimeStampPin specifies the RTC TimeStamp Pin.
116   *          This parameter can be one of the following values:
117   *             @arg RTC_TIMESTAMPPIN_DEFAULT: PC13 is selected as RTC TimeStamp Pin.
118   *               The RTC TimeStamp Pin is per default PC13, but for reasons of
119   *               compatibility, this parameter is required.
120   * @retval HAL status
121   */
HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef * hrtc,uint32_t TimeStampEdge,uint32_t RTC_TimeStampPin)122 HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin)
123 {
124   uint32_t tmpreg;
125 
126   /* Check the parameters */
127   assert_param(IS_TIMESTAMP_EDGE(TimeStampEdge));
128   assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin));
129 
130   /* Process Locked */
131   __HAL_LOCK(hrtc);
132 
133   hrtc->State = HAL_RTC_STATE_BUSY;
134 
135   /* Get the RTC_CR register and clear the bits to be configured */
136   tmpreg = (uint32_t)(hrtc->Instance->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE));
137 
138   tmpreg |= TimeStampEdge;
139 
140   /* Disable the write protection for RTC registers */
141   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
142 
143   /* Configure the Time Stamp TSEDGE and Enable bits */
144   hrtc->Instance->CR = (uint32_t)tmpreg;
145 
146   __HAL_RTC_TIMESTAMP_ENABLE(hrtc);
147 
148   /* Enable the write protection for RTC registers */
149   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
150 
151   /* Change RTC state */
152   hrtc->State = HAL_RTC_STATE_READY;
153 
154   /* Process Unlocked */
155   __HAL_UNLOCK(hrtc);
156 
157   return HAL_OK;
158 }
159 
160 /**
161   * @brief  Set TimeStamp with Interrupt.
162   * @note   This API must be called before enabling the TimeStamp feature.
163   * @note   The application must ensure that the EXTI RTC interrupt line is enabled.
164   * @param  hrtc RTC handle
165   * @param  TimeStampEdge Specifies the pin edge on which the TimeStamp is
166   *         activated.
167   *          This parameter can be one of the following values:
168   *             @arg RTC_TIMESTAMPEDGE_RISING: the Time stamp event occurs on the
169   *                                        rising edge of the related pin.
170   *             @arg RTC_TIMESTAMPEDGE_FALLING: the Time stamp event occurs on the
171   *                                         falling edge of the related pin.
172   * @param  RTC_TimeStampPin Specifies the RTC TimeStamp Pin.
173   *          This parameter can be one of the following values:
174   *             @arg RTC_TIMESTAMPPIN_DEFAULT: PC13 is selected as RTC TimeStamp Pin.
175   *               The RTC TimeStamp Pin is per default PC13, but for reasons of
176   *               compatibility, this parameter is required.
177   * @retval HAL status
178   */
HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef * hrtc,uint32_t TimeStampEdge,uint32_t RTC_TimeStampPin)179 HAL_StatusTypeDef HAL_RTCEx_SetTimeStamp_IT(RTC_HandleTypeDef *hrtc, uint32_t TimeStampEdge, uint32_t RTC_TimeStampPin)
180 {
181   uint32_t tmpreg;
182 
183   /* Check the parameters */
184   assert_param(IS_TIMESTAMP_EDGE(TimeStampEdge));
185   assert_param(IS_RTC_TIMESTAMP_PIN(RTC_TimeStampPin));
186 
187   /* Process Locked */
188   __HAL_LOCK(hrtc);
189 
190   hrtc->State = HAL_RTC_STATE_BUSY;
191 
192   /* Get the RTC_CR register and clear the bits to be configured */
193   tmpreg = (uint32_t)(hrtc->Instance->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE));
194 
195   tmpreg |= TimeStampEdge;
196 
197   /* Disable the write protection for RTC registers */
198   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
199 
200   /* Configure the Time Stamp TSEDGE and Enable bits */
201   hrtc->Instance->CR = (uint32_t)tmpreg;
202 
203   __HAL_RTC_TIMESTAMP_ENABLE(hrtc);
204 
205   /* Enable IT timestamp */
206   __HAL_RTC_TIMESTAMP_ENABLE_IT(hrtc, RTC_IT_TS);
207 
208   /* RTC timestamp Interrupt Configuration: EXTI configuration */
209   __HAL_RTC_TIMESTAMP_EXTI_ENABLE_IT();
210 
211   /* Enable the write protection for RTC registers */
212   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
213 
214   hrtc->State = HAL_RTC_STATE_READY;
215 
216   /* Process Unlocked */
217   __HAL_UNLOCK(hrtc);
218 
219   return HAL_OK;
220 }
221 
222 /**
223   * @brief  Deactivate TimeStamp.
224   * @param  hrtc RTC handle
225   * @retval HAL status
226   */
HAL_RTCEx_DeactivateTimeStamp(RTC_HandleTypeDef * hrtc)227 HAL_StatusTypeDef HAL_RTCEx_DeactivateTimeStamp(RTC_HandleTypeDef *hrtc)
228 {
229   uint32_t tmpreg;
230 
231   /* Process Locked */
232   __HAL_LOCK(hrtc);
233 
234   hrtc->State = HAL_RTC_STATE_BUSY;
235 
236   /* Disable the write protection for RTC registers */
237   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
238 
239   /* In case of interrupt mode is used, the interrupt source must disabled */
240   __HAL_RTC_TIMESTAMP_DISABLE_IT(hrtc, RTC_IT_TS);
241 
242   /* Get the RTC_CR register and clear the bits to be configured */
243   tmpreg = (uint32_t)(hrtc->Instance->CR & (uint32_t)~(RTC_CR_TSEDGE | RTC_CR_TSE));
244 
245   /* Configure the Time Stamp TSEDGE and Enable bits */
246   hrtc->Instance->CR = (uint32_t)tmpreg;
247 
248   /* Enable the write protection for RTC registers */
249   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
250 
251   hrtc->State = HAL_RTC_STATE_READY;
252 
253   /* Process Unlocked */
254   __HAL_UNLOCK(hrtc);
255 
256   return HAL_OK;
257 }
258 
259 /**
260   * @brief  Get the RTC TimeStamp value.
261   * @param  hrtc RTC handle
262   * @param  sTimeStamp Pointer to Time structure
263   * @param  sTimeStampDate Pointer to Date structure
264   * @param  Format specifies the format of the entered parameters.
265   *          This parameter can be one of the following values:
266   *             @arg RTC_FORMAT_BIN: Binary data format
267   *             @arg RTC_FORMAT_BCD: BCD data format
268   * @retval HAL status
269   */
HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTimeStamp,RTC_DateTypeDef * sTimeStampDate,uint32_t Format)270 HAL_StatusTypeDef HAL_RTCEx_GetTimeStamp(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTimeStamp,
271                                          RTC_DateTypeDef *sTimeStampDate, uint32_t Format)
272 {
273   uint32_t tmptime, tmpdate;
274 
275   /* Check the parameters */
276   assert_param(IS_RTC_FORMAT(Format));
277 
278   /* Get the TimeStamp time and date registers values */
279   tmptime = (uint32_t)(hrtc->Instance->TSTR & RTC_TR_RESERVED_MASK);
280   tmpdate = (uint32_t)(hrtc->Instance->TSDR & RTC_DR_RESERVED_MASK);
281 
282   /* Fill the Time structure fields with the read parameters */
283   sTimeStamp->Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TSTR_HU_Pos);
284   sTimeStamp->Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TSTR_MNU_Pos);
285   sTimeStamp->Seconds = (uint8_t)((tmptime & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TSTR_SU_Pos);
286   sTimeStamp->TimeFormat = (uint8_t)((tmptime & (RTC_TR_PM)) >> RTC_TSTR_PM_Pos);
287   sTimeStamp->SubSeconds = (uint32_t) hrtc->Instance->TSSSR;
288 
289   /* Fill the Date structure fields with the read parameters */
290   sTimeStampDate->Year = 0U;
291   sTimeStampDate->Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> RTC_TSDR_MU_Pos);
292   sTimeStampDate->Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU));
293   sTimeStampDate->WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> RTC_TSDR_WDU_Pos);
294 
295   /* Check the input parameters format */
296   if (Format == RTC_FORMAT_BIN)
297   {
298     /* Convert the TimeStamp structure parameters to Binary format */
299     sTimeStamp->Hours = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Hours);
300     sTimeStamp->Minutes = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Minutes);
301     sTimeStamp->Seconds = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Seconds);
302 
303     /* Convert the DateTimeStamp structure parameters to Binary format */
304     sTimeStampDate->Month = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Month);
305     sTimeStampDate->Date = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Date);
306     sTimeStampDate->WeekDay = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->WeekDay);
307   }
308 
309   /* Clear the TIMESTAMP Flags */
310   __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc, RTC_FLAG_TSF);
311 
312   return HAL_OK;
313 }
314 
315 /**
316   * @brief  TimeStamp callback.
317   * @param  hrtc RTC handle
318   * @retval None
319   */
HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef * hrtc)320 __weak void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc)
321 {
322   /* Prevent unused argument(s) compilation warning */
323   UNUSED(hrtc);
324 
325   /* NOTE : This function should not be modified, when the callback is needed,
326             the HAL_RTCEx_TimeStampEventCallback could be implemented in the user file
327   */
328 }
329 
330 
331 /**
332   * @brief  Handle TimeStamp interrupt request.
333   * @param  hrtc RTC handle
334   * @retval None
335   */
HAL_RTCEx_TimeStampIRQHandler(RTC_HandleTypeDef * hrtc)336 void HAL_RTCEx_TimeStampIRQHandler(RTC_HandleTypeDef *hrtc)
337 {
338   /* Get the TimeStamp interrupt source enable status */
339   if (READ_BIT(RTC->MISR, RTC_MISR_TSMF) != 0U)
340   {
341 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
342     /* Call TimeStampEvent registered Callback */
343     hrtc->TimeStampEventCallback(hrtc);
344 #else
345     /* TIMESTAMP callback */
346     HAL_RTCEx_TimeStampEventCallback(hrtc);
347 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
348 
349     /* Clearing flags after the Callback because the content of RTC_TSTR and RTC_TSDR are cleared when TSF bit is reset.*/
350     WRITE_REG(RTC->SCR, RTC_SCR_CTSF);
351   }
352 
353   /* Change RTC state */
354   hrtc->State = HAL_RTC_STATE_READY;
355 }
356 
357 
358 /**
359   * @brief  Handle TimeStamp polling request.
360   * @param  hrtc RTC handle
361   * @param  Timeout Timeout duration
362   * @retval HAL status
363   */
HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)364 HAL_StatusTypeDef HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
365 {
366   uint32_t tickstart = HAL_GetTick();
367 
368   while (__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSF) == 0U)
369   {
370     if (__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSOVF) != 0U)
371     {
372       /* Clear the TIMESTAMP OverRun Flag */
373       __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc, RTC_FLAG_TSOVF);
374 
375       return HAL_ERROR;
376     }
377 
378     if (Timeout != HAL_MAX_DELAY)
379     {
380       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
381       {
382         /* New check to avoid false timeout detection in case of preemption */
383         if (__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSF) == 0U)
384         {
385           return HAL_TIMEOUT;
386         }
387         else
388         {
389           break;
390         }
391       }
392     }
393   }
394 
395   return HAL_OK;
396 }
397 
398 /**
399   * @}
400   */
401 
402 
403 /** @addtogroup RTCEx_Exported_Functions_Group3
404   * @brief    Extended Peripheral Control functions
405   *
406 @verbatim
407  ===============================================================================
408               ##### Extended Peripheral Control functions #####
409  ===============================================================================
410     [..]
411     This subsection provides functions allowing to
412       (+) Set the Coarse calibration parameters.
413       (+) Deactivate the Coarse calibration parameters
414       (+) Set the Smooth calibration parameters.
415       (+) Configure the Synchronization Shift Control Settings.
416       (+) Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
417       (+) Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
418       (+) Enable the RTC reference clock detection.
419       (+) Disable the RTC reference clock detection.
420       (+) Enable the Bypass Shadow feature.
421       (+) Disable the Bypass Shadow feature.
422 
423 @endverbatim
424   * @{
425   */
426 
427 
428 
429 /**
430   * @brief  Set the Smooth calibration parameters.
431   * @note   To deactivate the smooth calibration, the field SmoothCalibPlusPulses
432   *         must be equal to SMOOTHCALIB_PLUSPULSES_RESET and the field
433   *         SmoothCalibMinusPulsesValue must be equal to 0.
434   * @param  hrtc RTC handle
435   * @param  SmoothCalibPeriod Select the Smooth Calibration Period.
436   *          This parameter can be can be one of the following values :
437   *             @arg RTC_SMOOTHCALIB_PERIOD_32SEC: The smooth calibration period is 32s.
438   *             @arg RTC_SMOOTHCALIB_PERIOD_16SEC: The smooth calibration period is 16s.
439   *             @arg RTC_SMOOTHCALIB_PERIOD_8SEC: The smooth calibration period is 8s.
440   * @param  SmoothCalibPlusPulses Select to Set or reset the CALP bit.
441   *          This parameter can be one of the following values:
442   *             @arg RTC_SMOOTHCALIB_PLUSPULSES_SET: Add one RTCCLK pulse every 2*11 pulses.
443   *             @arg RTC_SMOOTHCALIB_PLUSPULSES_RESET: No RTCCLK pulses are added.
444   * @param  SmoothCalibMinusPulsesValue Select the value of CALM[8:0] bits.
445   *          This parameter can be one any value from 0 to 0x000001FF.
446   * @retval HAL status
447   */
HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef * hrtc,uint32_t SmoothCalibPeriod,uint32_t SmoothCalibPlusPulses,uint32_t SmoothCalibMinusPulsesValue)448 HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef *hrtc, uint32_t SmoothCalibPeriod,
449                                            uint32_t SmoothCalibPlusPulses, uint32_t SmoothCalibMinusPulsesValue)
450 {
451   uint32_t tickstart;
452 
453   /* Check the parameters */
454   assert_param(IS_RTC_SMOOTH_CALIB_PERIOD(SmoothCalibPeriod));
455   assert_param(IS_RTC_SMOOTH_CALIB_PLUS(SmoothCalibPlusPulses));
456   assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmoothCalibMinusPulsesValue));
457 
458   /* Process Locked */
459   __HAL_LOCK(hrtc);
460 
461   hrtc->State = HAL_RTC_STATE_BUSY;
462 
463   /* Disable the write protection for RTC registers */
464   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
465 
466   tickstart = HAL_GetTick();
467 
468   /* check if a calibration is pending*/
469   while ((hrtc->Instance->ICSR & RTC_ICSR_RECALPF) != 0U)
470   {
471     /* check if a calibration is pending*/
472     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
473     {
474       /* New check to avoid false timeout detection in case of preemption */
475       if ((hrtc->Instance->ICSR & RTC_ICSR_RECALPF) != 0U)
476       {
477         /* Enable the write protection for RTC registers */
478         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
479 
480         /* Change RTC state */
481         hrtc->State = HAL_RTC_STATE_TIMEOUT;
482 
483         /* Process Unlocked */
484         __HAL_UNLOCK(hrtc);
485 
486         return HAL_TIMEOUT;
487       }
488       else
489       {
490         break;
491       }
492     }
493   }
494 
495   /* Configure the Smooth calibration settings */
496   hrtc->Instance->CALR = (uint32_t)((uint32_t)SmoothCalibPeriod | (uint32_t)SmoothCalibPlusPulses | (uint32_t)SmoothCalibMinusPulsesValue);
497 
498   /* Enable the write protection for RTC registers */
499   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
500 
501   /* Change RTC state */
502   hrtc->State = HAL_RTC_STATE_READY;
503 
504   /* Process Unlocked */
505   __HAL_UNLOCK(hrtc);
506 
507   return HAL_OK;
508 }
509 
510 /**
511   * @brief  Configure the Synchronization Shift Control Settings.
512   * @note   When REFCKON is set, firmware must not write to Shift control register.
513   * @param  hrtc RTC handle
514   * @param  ShiftAdd1S Select to add or not 1 second to the time calendar.
515   *          This parameter can be one of the following values:
516   *             @arg RTC_SHIFTADD1S_SET: Add one second to the clock calendar.
517   *             @arg RTC_SHIFTADD1S_RESET: No effect.
518   * @param  ShiftSubFS Select the number of Second Fractions to substitute.
519   *          This parameter can be one any value from 0 to 0x7FFF.
520   * @retval HAL status
521   */
HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef * hrtc,uint32_t ShiftAdd1S,uint32_t ShiftSubFS)522 HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef *hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS)
523 {
524   uint32_t tickstart;
525 
526   /* Check the parameters */
527   assert_param(IS_RTC_SHIFT_ADD1S(ShiftAdd1S));
528   assert_param(IS_RTC_SHIFT_SUBFS(ShiftSubFS));
529 
530   /* Process Locked */
531   __HAL_LOCK(hrtc);
532 
533   hrtc->State = HAL_RTC_STATE_BUSY;
534 
535   /* Disable the write protection for RTC registers */
536   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
537 
538   tickstart = HAL_GetTick();
539 
540   /* Wait until the shift is completed*/
541   while ((hrtc->Instance->ICSR & RTC_ICSR_SHPF) != 0U)
542   {
543     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
544     {
545       /* New check to avoid false timeout detection in case of preemption */
546       if ((hrtc->Instance->ICSR & RTC_ICSR_SHPF) != 0U)
547       {
548         /* Enable the write protection for RTC registers */
549         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
550 
551         /* Change RTC state */
552         hrtc->State = HAL_RTC_STATE_TIMEOUT;
553 
554         /* Process Unlocked */
555         __HAL_UNLOCK(hrtc);
556 
557         return HAL_TIMEOUT;
558       }
559       else
560       {
561         break;
562       }
563     }
564   }
565 
566   /* Check if the reference clock detection is disabled */
567   if ((hrtc->Instance->CR & RTC_CR_REFCKON) == 0U)
568   {
569     /* Configure the Shift settings */
570     hrtc->Instance->SHIFTR = (uint32_t)(uint32_t)(ShiftSubFS) | (uint32_t)(ShiftAdd1S);
571 
572     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
573     if ((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
574     {
575       if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
576       {
577         /* Enable the write protection for RTC registers */
578         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
579 
580         hrtc->State = HAL_RTC_STATE_ERROR;
581 
582         /* Process Unlocked */
583         __HAL_UNLOCK(hrtc);
584 
585         return HAL_ERROR;
586       }
587     }
588   }
589   else
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_ERROR;
596 
597     /* Process Unlocked */
598     __HAL_UNLOCK(hrtc);
599 
600     return HAL_ERROR;
601   }
602 
603   /* Enable the write protection for RTC registers */
604   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
605 
606   /* Change RTC state */
607   hrtc->State = HAL_RTC_STATE_READY;
608 
609   /* Process Unlocked */
610   __HAL_UNLOCK(hrtc);
611 
612   return HAL_OK;
613 }
614 
615 /**
616   * @brief  Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
617   * @param  hrtc RTC handle
618   * @param  CalibOutput Select the Calibration output Selection .
619   *          This parameter can be one of the following values:
620   *             @arg RTC_CALIBOUTPUT_512HZ: A signal has a regular waveform at 512Hz.
621   *             @arg RTC_CALIBOUTPUT_1HZ: A signal has a regular waveform at 1Hz.
622   * @retval HAL status
623   */
HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef * hrtc,uint32_t CalibOutput)624 HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef *hrtc, uint32_t CalibOutput)
625 {
626   /* Check the parameters */
627   assert_param(IS_RTC_CALIB_OUTPUT(CalibOutput));
628 
629   /* Process Locked */
630   __HAL_LOCK(hrtc);
631 
632   hrtc->State = HAL_RTC_STATE_BUSY;
633 
634   /* Disable the write protection for RTC registers */
635   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
636 
637   /* Clear flags before config */
638   hrtc->Instance->CR &= (uint32_t)~RTC_CR_COSEL;
639 
640   /* Configure the RTC_CR register */
641   hrtc->Instance->CR |= (uint32_t)CalibOutput;
642 
643   __HAL_RTC_CALIBRATION_OUTPUT_ENABLE(hrtc);
644 
645   /* Enable the write protection for RTC registers */
646   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
647 
648   /* Change RTC state */
649   hrtc->State = HAL_RTC_STATE_READY;
650 
651   /* Process Unlocked */
652   __HAL_UNLOCK(hrtc);
653 
654   return HAL_OK;
655 }
656 
657 /**
658   * @brief  Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
659   * @param  hrtc RTC handle
660   * @retval HAL status
661   */
HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef * hrtc)662 HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef *hrtc)
663 {
664   /* Process Locked */
665   __HAL_LOCK(hrtc);
666 
667   hrtc->State = HAL_RTC_STATE_BUSY;
668 
669   /* Disable the write protection for RTC registers */
670   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
671 
672   __HAL_RTC_CALIBRATION_OUTPUT_DISABLE(hrtc);
673 
674   /* Enable the write protection for RTC registers */
675   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
676 
677   /* Change RTC state */
678   hrtc->State = HAL_RTC_STATE_READY;
679 
680   /* Process Unlocked */
681   __HAL_UNLOCK(hrtc);
682 
683   return HAL_OK;
684 }
685 
686 /**
687   * @brief  Enable the RTC reference clock detection.
688   * @param  hrtc RTC handle
689   * @retval HAL status
690   */
HAL_RTCEx_SetRefClock(RTC_HandleTypeDef * hrtc)691 HAL_StatusTypeDef HAL_RTCEx_SetRefClock(RTC_HandleTypeDef *hrtc)
692 {
693   HAL_StatusTypeDef status;
694 
695   /* Process Locked */
696   __HAL_LOCK(hrtc);
697 
698   hrtc->State = HAL_RTC_STATE_BUSY;
699 
700   /* Disable the write protection for RTC registers */
701   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
702 
703   /* Enter Initialization mode */
704   status = RTC_EnterInitMode(hrtc);
705   if (status == HAL_OK)
706   {
707     /* Enable clockref detection */
708     __HAL_RTC_CLOCKREF_DETECTION_ENABLE(hrtc);
709 
710     /* Exit Initialization mode */
711     status = RTC_ExitInitMode(hrtc);
712   }
713 
714   /* Enable the write protection for RTC registers */
715   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
716 
717   if (status == HAL_OK)
718   {
719     hrtc->State = HAL_RTC_STATE_READY;
720   }
721 
722   /* Process Unlocked */
723   __HAL_UNLOCK(hrtc);
724 
725   return status;
726 }
727 
728 /**
729   * @brief  Disable the RTC reference clock detection.
730   * @param  hrtc RTC handle
731   * @retval HAL status
732   */
HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef * hrtc)733 HAL_StatusTypeDef HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef *hrtc)
734 {
735   HAL_StatusTypeDef status;
736 
737   /* Process Locked */
738   __HAL_LOCK(hrtc);
739 
740   hrtc->State = HAL_RTC_STATE_BUSY;
741 
742   /* Disable the write protection for RTC registers */
743   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
744 
745   /* Enter Initialization mode */
746   status = RTC_EnterInitMode(hrtc);
747   if (status == HAL_OK)
748   {
749     /* Disable clockref detection */
750     __HAL_RTC_CLOCKREF_DETECTION_DISABLE(hrtc);
751 
752     /* Exit Initialization mode */
753     status = RTC_ExitInitMode(hrtc);
754   }
755 
756   /* Enable the write protection for RTC registers */
757   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
758 
759   if (status == HAL_OK)
760   {
761     hrtc->State = HAL_RTC_STATE_READY;
762   }
763 
764   /* Process Unlocked */
765   __HAL_UNLOCK(hrtc);
766 
767   return status;
768 }
769 
770 /**
771   * @brief  Enable the Bypass Shadow feature.
772   * @note   When the Bypass Shadow is enabled the calendar value are taken
773   *         directly from the Calendar counter.
774   * @param  hrtc RTC handle
775   * @retval HAL status
776   */
HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef * hrtc)777 HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef *hrtc)
778 {
779   /* Process Locked */
780   __HAL_LOCK(hrtc);
781 
782   hrtc->State = HAL_RTC_STATE_BUSY;
783 
784   /* Disable the write protection for RTC registers */
785   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
786 
787   /* Set the BYPSHAD bit */
788   hrtc->Instance->CR |= (uint8_t)RTC_CR_BYPSHAD;
789 
790   /* Enable the write protection for RTC registers */
791   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
792 
793   /* Change RTC state */
794   hrtc->State = HAL_RTC_STATE_READY;
795 
796   /* Process Unlocked */
797   __HAL_UNLOCK(hrtc);
798 
799   return HAL_OK;
800 }
801 
802 /**
803   * @brief  Disable the Bypass Shadow feature.
804   * @note   When the Bypass Shadow is enabled the calendar value are taken
805   *         directly from the Calendar counter.
806   * @param  hrtc RTC handle
807   * @retval HAL status
808   */
HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef * hrtc)809 HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef *hrtc)
810 {
811   /* Process Locked */
812   __HAL_LOCK(hrtc);
813 
814   hrtc->State = HAL_RTC_STATE_BUSY;
815 
816   /* Disable the write protection for RTC registers */
817   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
818 
819   /* Reset the BYPSHAD bit */
820   hrtc->Instance->CR &= ((uint8_t)~RTC_CR_BYPSHAD);
821 
822   /* Enable the write protection for RTC registers */
823   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
824 
825   /* Change RTC state */
826   hrtc->State = HAL_RTC_STATE_READY;
827 
828   /* Process Unlocked */
829   __HAL_UNLOCK(hrtc);
830 
831   return HAL_OK;
832 }
833 
834 /**
835   * @}
836   */
837 
838 /**
839   * @}
840   */
841 
842 #endif /* HAL_RTC_MODULE_ENABLED */
843 /**
844   * @}
845   */
846 
847 
848 /**
849   * @}
850   */
851 
852