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