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;
274   uint32_t tmpdate;
275 
276   /* Check the parameters */
277   assert_param(IS_RTC_FORMAT(Format));
278 
279   /* Get the TimeStamp time and date registers values */
280   tmptime = (uint32_t)(hrtc->Instance->TSTR & RTC_TR_RESERVED_MASK);
281   tmpdate = (uint32_t)(hrtc->Instance->TSDR & RTC_DR_RESERVED_MASK);
282 
283   /* Fill the Time structure fields with the read parameters */
284   sTimeStamp->Hours = (uint8_t)((tmptime & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TSTR_HU_Pos);
285   sTimeStamp->Minutes = (uint8_t)((tmptime & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TSTR_MNU_Pos);
286   sTimeStamp->Seconds = (uint8_t)((tmptime & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TSTR_SU_Pos);
287   sTimeStamp->TimeFormat = (uint8_t)((tmptime & (RTC_TR_PM)) >> RTC_TSTR_PM_Pos);
288   sTimeStamp->SubSeconds = (uint32_t) hrtc->Instance->TSSSR;
289 
290   /* Fill the Date structure fields with the read parameters */
291   sTimeStampDate->Year = 0U;
292   sTimeStampDate->Month = (uint8_t)((tmpdate & (RTC_DR_MT | RTC_DR_MU)) >> RTC_TSDR_MU_Pos);
293   sTimeStampDate->Date = (uint8_t)(tmpdate & (RTC_DR_DT | RTC_DR_DU));
294   sTimeStampDate->WeekDay = (uint8_t)((tmpdate & (RTC_DR_WDU)) >> RTC_TSDR_WDU_Pos);
295 
296   /* Check the input parameters format */
297   if (Format == RTC_FORMAT_BIN)
298   {
299     /* Convert the TimeStamp structure parameters to Binary format */
300     sTimeStamp->Hours = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Hours);
301     sTimeStamp->Minutes = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Minutes);
302     sTimeStamp->Seconds = (uint8_t)RTC_Bcd2ToByte(sTimeStamp->Seconds);
303 
304     /* Convert the DateTimeStamp structure parameters to Binary format */
305     sTimeStampDate->Month = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Month);
306     sTimeStampDate->Date = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->Date);
307     sTimeStampDate->WeekDay = (uint8_t)RTC_Bcd2ToByte(sTimeStampDate->WeekDay);
308   }
309 
310   /* Clear the TIMESTAMP Flags */
311   __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc, RTC_FLAG_TSF);
312 
313   return HAL_OK;
314 }
315 
316 /**
317   * @brief  TimeStamp callback.
318   * @param  hrtc RTC handle
319   * @retval None
320   */
HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef * hrtc)321 __weak void HAL_RTCEx_TimeStampEventCallback(RTC_HandleTypeDef *hrtc)
322 {
323   /* Prevent unused argument(s) compilation warning */
324   UNUSED(hrtc);
325 
326   /* NOTE : This function should not be modified, when the callback is needed,
327             the HAL_RTCEx_TimeStampEventCallback could be implemented in the user file
328   */
329 }
330 
331 
332 /**
333   * @brief  Handle TimeStamp interrupt request.
334   * @param  hrtc RTC handle
335   * @retval None
336   */
HAL_RTCEx_TimeStampIRQHandler(RTC_HandleTypeDef * hrtc)337 void HAL_RTCEx_TimeStampIRQHandler(RTC_HandleTypeDef *hrtc)
338 {
339   /* Get the TimeStamp interrupt source enable status */
340   if (READ_BIT(RTC->MISR, RTC_MISR_TSMF) != 0U)
341   {
342 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
343     /* Call TimeStampEvent registered Callback */
344     hrtc->TimeStampEventCallback(hrtc);
345 #else
346     /* TIMESTAMP callback */
347     HAL_RTCEx_TimeStampEventCallback(hrtc);
348 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
349 
350     /* Clearing flags after the Callback because the RTC_TSTR and RTC_TSDR contents are cleared when TSF bit is reset.*/
351     WRITE_REG(RTC->SCR, RTC_SCR_CTSF);
352   }
353 
354   /* Change RTC state */
355   hrtc->State = HAL_RTC_STATE_READY;
356 }
357 
358 
359 /**
360   * @brief  Handle TimeStamp polling request.
361   * @param  hrtc RTC handle
362   * @param  Timeout Timeout duration
363   * @retval HAL status
364   */
HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)365 HAL_StatusTypeDef HAL_RTCEx_PollForTimeStampEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
366 {
367   uint32_t tickstart = HAL_GetTick();
368 
369   while (__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSF) == 0U)
370   {
371     if (__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSOVF) != 0U)
372     {
373       /* Clear the TIMESTAMP OverRun Flag */
374       __HAL_RTC_TIMESTAMP_CLEAR_FLAG(hrtc, RTC_FLAG_TSOVF);
375 
376       return HAL_ERROR;
377     }
378 
379     if (Timeout != HAL_MAX_DELAY)
380     {
381       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
382       {
383         /* New check to avoid false timeout detection in case of preemption */
384         if (__HAL_RTC_TIMESTAMP_GET_FLAG(hrtc, RTC_FLAG_TSF) == 0U)
385         {
386           return HAL_TIMEOUT;
387         }
388         else
389         {
390           break;
391         }
392       }
393     }
394   }
395 
396   return HAL_OK;
397 }
398 
399 /**
400   * @}
401   */
402 
403 
404 /** @addtogroup RTCEx_Exported_Functions_Group3
405   * @brief    Extended Peripheral Control functions
406   *
407 @verbatim
408  ===============================================================================
409               ##### Extended Peripheral Control functions #####
410  ===============================================================================
411     [..]
412     This subsection provides functions allowing to
413       (+) Set the Coarse calibration parameters.
414       (+) Deactivate the Coarse calibration parameters
415       (+) Set the Smooth calibration parameters.
416       (+) Configure the Synchronization Shift Control Settings.
417       (+) Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
418       (+) Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
419       (+) Enable the RTC reference clock detection.
420       (+) Disable the RTC reference clock detection.
421       (+) Enable the Bypass Shadow feature.
422       (+) Disable the Bypass Shadow feature.
423 
424 @endverbatim
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 | \
497                                     (uint32_t)SmoothCalibMinusPulsesValue);
498 
499   /* Enable the write protection for RTC registers */
500   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
501 
502   /* Change RTC state */
503   hrtc->State = HAL_RTC_STATE_READY;
504 
505   /* Process Unlocked */
506   __HAL_UNLOCK(hrtc);
507 
508   return HAL_OK;
509 }
510 
511 /**
512   * @brief  Configure the Synchronization Shift Control Settings.
513   * @note   When REFCKON is set, firmware must not write to Shift control register.
514   * @param  hrtc RTC handle
515   * @param  ShiftAdd1S Select to add or not 1 second to the time calendar.
516   *          This parameter can be one of the following values:
517   *             @arg RTC_SHIFTADD1S_SET: Add one second to the clock calendar.
518   *             @arg RTC_SHIFTADD1S_RESET: No effect.
519   * @param  ShiftSubFS Select the number of Second Fractions to substitute.
520   *          This parameter can be one any value from 0 to 0x7FFF.
521   * @retval HAL status
522   */
HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef * hrtc,uint32_t ShiftAdd1S,uint32_t ShiftSubFS)523 HAL_StatusTypeDef HAL_RTCEx_SetSynchroShift(RTC_HandleTypeDef *hrtc, uint32_t ShiftAdd1S, uint32_t ShiftSubFS)
524 {
525   uint32_t tickstart;
526 
527   /* Check the parameters */
528   assert_param(IS_RTC_SHIFT_ADD1S(ShiftAdd1S));
529   assert_param(IS_RTC_SHIFT_SUBFS(ShiftSubFS));
530 
531   /* Process Locked */
532   __HAL_LOCK(hrtc);
533 
534   hrtc->State = HAL_RTC_STATE_BUSY;
535 
536   /* Disable the write protection for RTC registers */
537   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
538 
539   tickstart = HAL_GetTick();
540 
541   /* Wait until the shift is completed*/
542   while ((hrtc->Instance->ICSR & RTC_ICSR_SHPF) != 0U)
543   {
544     if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
545     {
546       /* New check to avoid false timeout detection in case of preemption */
547       if ((hrtc->Instance->ICSR & RTC_ICSR_SHPF) != 0U)
548       {
549         /* Enable the write protection for RTC registers */
550         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
551 
552         /* Change RTC state */
553         hrtc->State = HAL_RTC_STATE_TIMEOUT;
554 
555         /* Process Unlocked */
556         __HAL_UNLOCK(hrtc);
557 
558         return HAL_TIMEOUT;
559       }
560       else
561       {
562         break;
563       }
564     }
565   }
566 
567   /* Check if the reference clock detection is disabled */
568   if ((hrtc->Instance->CR & RTC_CR_REFCKON) == 0U)
569   {
570     /* Configure the Shift settings */
571     hrtc->Instance->SHIFTR = (uint32_t)(uint32_t)(ShiftSubFS) | (uint32_t)(ShiftAdd1S);
572 
573     /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
574     if ((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
575     {
576       if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
577       {
578         /* Enable the write protection for RTC registers */
579         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
580 
581         hrtc->State = HAL_RTC_STATE_ERROR;
582 
583         /* Process Unlocked */
584         __HAL_UNLOCK(hrtc);
585 
586         return HAL_ERROR;
587       }
588     }
589   }
590   else
591   {
592     /* Enable the write protection for RTC registers */
593     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
594 
595     /* Change RTC state */
596     hrtc->State = HAL_RTC_STATE_ERROR;
597 
598     /* Process Unlocked */
599     __HAL_UNLOCK(hrtc);
600 
601     return HAL_ERROR;
602   }
603 
604   /* Enable the write protection for RTC registers */
605   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
606 
607   /* Change RTC state */
608   hrtc->State = HAL_RTC_STATE_READY;
609 
610   /* Process Unlocked */
611   __HAL_UNLOCK(hrtc);
612 
613   return HAL_OK;
614 }
615 
616 /**
617   * @brief  Configure the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
618   * @param  hrtc RTC handle
619   * @param  CalibOutput Select the Calibration output Selection .
620   *          This parameter can be one of the following values:
621   *             @arg RTC_CALIBOUTPUT_512HZ: A signal has a regular waveform at 512Hz.
622   *             @arg RTC_CALIBOUTPUT_1HZ: A signal has a regular waveform at 1Hz.
623   * @retval HAL status
624   */
HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef * hrtc,uint32_t CalibOutput)625 HAL_StatusTypeDef HAL_RTCEx_SetCalibrationOutPut(RTC_HandleTypeDef *hrtc, uint32_t CalibOutput)
626 {
627   /* Check the parameters */
628   assert_param(IS_RTC_CALIB_OUTPUT(CalibOutput));
629 
630   /* Process Locked */
631   __HAL_LOCK(hrtc);
632 
633   hrtc->State = HAL_RTC_STATE_BUSY;
634 
635   /* Disable the write protection for RTC registers */
636   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
637 
638   /* Clear flags before config */
639   hrtc->Instance->CR &= (uint32_t)~RTC_CR_COSEL;
640 
641   /* Configure the RTC_CR register */
642   hrtc->Instance->CR |= (uint32_t)CalibOutput;
643 
644   __HAL_RTC_CALIBRATION_OUTPUT_ENABLE(hrtc);
645 
646   /* Enable the write protection for RTC registers */
647   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
648 
649   /* Change RTC state */
650   hrtc->State = HAL_RTC_STATE_READY;
651 
652   /* Process Unlocked */
653   __HAL_UNLOCK(hrtc);
654 
655   return HAL_OK;
656 }
657 
658 /**
659   * @brief  Deactivate the Calibration Pinout (RTC_CALIB) Selection (1Hz or 512Hz).
660   * @param  hrtc RTC handle
661   * @retval HAL status
662   */
HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef * hrtc)663 HAL_StatusTypeDef HAL_RTCEx_DeactivateCalibrationOutPut(RTC_HandleTypeDef *hrtc)
664 {
665   /* Process Locked */
666   __HAL_LOCK(hrtc);
667 
668   hrtc->State = HAL_RTC_STATE_BUSY;
669 
670   /* Disable the write protection for RTC registers */
671   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
672 
673   __HAL_RTC_CALIBRATION_OUTPUT_DISABLE(hrtc);
674 
675   /* Enable the write protection for RTC registers */
676   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
677 
678   /* Change RTC state */
679   hrtc->State = HAL_RTC_STATE_READY;
680 
681   /* Process Unlocked */
682   __HAL_UNLOCK(hrtc);
683 
684   return HAL_OK;
685 }
686 
687 /**
688   * @brief  Enable the RTC reference clock detection.
689   * @param  hrtc RTC handle
690   * @retval HAL status
691   */
HAL_RTCEx_SetRefClock(RTC_HandleTypeDef * hrtc)692 HAL_StatusTypeDef HAL_RTCEx_SetRefClock(RTC_HandleTypeDef *hrtc)
693 {
694   HAL_StatusTypeDef status;
695 
696   /* Process Locked */
697   __HAL_LOCK(hrtc);
698 
699   hrtc->State = HAL_RTC_STATE_BUSY;
700 
701   /* Disable the write protection for RTC registers */
702   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
703 
704   /* Enter Initialization mode */
705   status = RTC_EnterInitMode(hrtc);
706   if (status == HAL_OK)
707   {
708     /* Enable clockref detection */
709     __HAL_RTC_CLOCKREF_DETECTION_ENABLE(hrtc);
710 
711     /* Exit Initialization mode */
712     status = RTC_ExitInitMode(hrtc);
713   }
714 
715   /* Enable the write protection for RTC registers */
716   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
717 
718   if (status == HAL_OK)
719   {
720     hrtc->State = HAL_RTC_STATE_READY;
721   }
722 
723   /* Process Unlocked */
724   __HAL_UNLOCK(hrtc);
725 
726   return status;
727 }
728 
729 /**
730   * @brief  Disable the RTC reference clock detection.
731   * @param  hrtc RTC handle
732   * @retval HAL status
733   */
HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef * hrtc)734 HAL_StatusTypeDef HAL_RTCEx_DeactivateRefClock(RTC_HandleTypeDef *hrtc)
735 {
736   HAL_StatusTypeDef status;
737 
738   /* Process Locked */
739   __HAL_LOCK(hrtc);
740 
741   hrtc->State = HAL_RTC_STATE_BUSY;
742 
743   /* Disable the write protection for RTC registers */
744   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
745 
746   /* Enter Initialization mode */
747   status = RTC_EnterInitMode(hrtc);
748   if (status == HAL_OK)
749   {
750     /* Disable clockref detection */
751     __HAL_RTC_CLOCKREF_DETECTION_DISABLE(hrtc);
752 
753     /* Exit Initialization mode */
754     status = RTC_ExitInitMode(hrtc);
755   }
756 
757   /* Enable the write protection for RTC registers */
758   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
759 
760   if (status == HAL_OK)
761   {
762     hrtc->State = HAL_RTC_STATE_READY;
763   }
764 
765   /* Process Unlocked */
766   __HAL_UNLOCK(hrtc);
767 
768   return status;
769 }
770 
771 /**
772   * @brief  Enable the Bypass Shadow feature.
773   * @note   When the Bypass Shadow is enabled the calendar value are taken
774   *         directly from the Calendar counter.
775   * @param  hrtc RTC handle
776   * @retval HAL status
777   */
HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef * hrtc)778 HAL_StatusTypeDef HAL_RTCEx_EnableBypassShadow(RTC_HandleTypeDef *hrtc)
779 {
780   /* Process Locked */
781   __HAL_LOCK(hrtc);
782 
783   hrtc->State = HAL_RTC_STATE_BUSY;
784 
785   /* Disable the write protection for RTC registers */
786   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
787 
788   /* Set the BYPSHAD bit */
789   hrtc->Instance->CR |= (uint8_t)RTC_CR_BYPSHAD;
790 
791   /* Enable the write protection for RTC registers */
792   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
793 
794   /* Change RTC state */
795   hrtc->State = HAL_RTC_STATE_READY;
796 
797   /* Process Unlocked */
798   __HAL_UNLOCK(hrtc);
799 
800   return HAL_OK;
801 }
802 
803 /**
804   * @brief  Disable the Bypass Shadow feature.
805   * @note   When the Bypass Shadow is enabled the calendar value are taken
806   *         directly from the Calendar counter.
807   * @param  hrtc RTC handle
808   * @retval HAL status
809   */
HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef * hrtc)810 HAL_StatusTypeDef HAL_RTCEx_DisableBypassShadow(RTC_HandleTypeDef *hrtc)
811 {
812   /* Process Locked */
813   __HAL_LOCK(hrtc);
814 
815   hrtc->State = HAL_RTC_STATE_BUSY;
816 
817   /* Disable the write protection for RTC registers */
818   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
819 
820   /* Reset the BYPSHAD bit */
821   hrtc->Instance->CR &= ((uint8_t)~RTC_CR_BYPSHAD);
822 
823   /* Enable the write protection for RTC registers */
824   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
825 
826   /* Change RTC state */
827   hrtc->State = HAL_RTC_STATE_READY;
828 
829   /* Process Unlocked */
830   __HAL_UNLOCK(hrtc);
831 
832   return HAL_OK;
833 }
834 
835 /**
836   * @}
837   */
838 
839 /**
840   * @}
841   */
842 
843 #endif /* HAL_RTC_MODULE_ENABLED */
844 /**
845   * @}
846   */
847 
848 
849 /**
850   * @}
851   */
852 
853