1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Real-Time Clock (RTC) peripheral:
8   *           + Initialization/de-initialization functions
9   *           + Calendar (Time and Date) configuration
10   *           + Alarms (Alarm A and Alarm B) configuration
11   *           + WakeUp Timer configuration
12   *           + TimeStamp configuration
13   *           + Tampers configuration
14   *           + Backup Data Registers configuration
15   *           + RTC Tamper and TimeStamp Pins Selection
16   *           + Interrupts and flags management
17   *
18   @verbatim
19  ===============================================================================
20                           ##### RTC Operating Condition #####
21  ===============================================================================
22   [..] The real-time clock (RTC) and the RTC backup registers can be powered
23        from the VBAT voltage when the main VDD supply is powered off.
24        To retain the content of the RTC backup registers and supply the RTC
25        when VDD is turned off, VBAT pin can be connected to an optional
26        standby voltage supplied by a battery or by another source.
27 
28                    ##### Backup Domain Reset #####
29  ===============================================================================
30   [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
31        to their reset values.
32        A backup domain reset is generated when one of the following events occurs:
33     (#) Software reset, triggered by setting the BDRST bit in the
34         RCC Backup domain control register (RCC_BDCR).
35     (#) VDD or VBAT power on, if both supplies have previously been powered off.
36     (#) Tamper detection event resets all data backup registers.
37 
38                    ##### Backup Domain Access #####
39   ==================================================================
40   [..] After reset, the backup domain (RTC registers and RTC backup data registers)
41        is protected against possible unwanted write accesses.
42   [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
43     (+) Enable the Power Controller (PWR) APB1 interface clock using the
44         __HAL_RCC_PWR_CLK_ENABLE() function.
45     (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
46     (+) Select the RTC clock source using the __HAL_RCC_RTC_CONFIG() function.
47     (+) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() function.
48 
49   [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
50     (#) Call the function HAL_RCCEx_PeriphCLKConfig with RCC_PERIPHCLK_RTC for
51         PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSEdiv32)
52     (#) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() macro.
53 
54                   ##### How to use RTC Driver #####
55  ===================================================================
56   [..]
57     (+) Enable the RTC domain access (see description in the section above).
58     (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour
59         format using the HAL_RTC_Init() function.
60 
61   *** Time and Date configuration ***
62   ===================================
63   [..]
64     (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
65         and HAL_RTC_SetDate() functions.
66     (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions.
67 
68   *** Alarm configuration ***
69   ===========================
70   [..]
71     (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
72             You can also configure the RTC Alarm with interrupt mode using the
73             HAL_RTC_SetAlarm_IT() function.
74     (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
75 
76                   ##### RTC and low power modes #####
77   ==================================================================
78   [..] The MCU can be woken up from a low power mode by an RTC alternate
79        function.
80   [..] The RTC alternate functions are the RTC alarms (Alarm A and Alarm B),
81        RTC wakeup, RTC tamper event detection and RTC time stamp event detection.
82        These RTC alternate functions can wake up the system from the Stop and
83        Standby low power modes.
84   [..] The system can also wake up from low power modes without depending
85        on an external interrupt (Auto-wakeup mode), by using the RTC alarm
86        or the RTC wakeup events.
87   [..] The RTC provides a programmable time base for waking up from the
88        Stop or Standby mode at regular intervals.
89        Wakeup from STOP and STANDBY modes is possible only when the RTC clock source
90        is LSE or LSI.
91 
92   *** Callback registration ***
93   =============================================
94   When The compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or
95   not defined, the callback registration feature is not available and all callbacks
96   are set to the corresponding weak functions. This is the recommended configuration
97   in order to optimize memory/code consumption footprint/performances.
98 
99   The compilation define  USE_RTC_REGISTER_CALLBACKS when set to 1
100   allows the user to configure dynamically the driver callbacks.
101   Use Function @ref HAL_RTC_RegisterCallback() to register an interrupt callback.
102 
103   Function @ref HAL_RTC_RegisterCallback() allows to register following callbacks:
104     (+) AlarmAEventCallback          : RTC Alarm A Event callback.
105     (+) AlarmBEventCallback          : RTC Alarm B Event callback.
106     (+) TimeStampEventCallback       : RTC TimeStamp Event callback.
107     (+) WakeUpTimerEventCallback     : RTC WakeUpTimer Event callback.
108     (+) Tamper1EventCallback         : RTC Tamper 1 Event callback.
109     (+) Tamper2EventCallback         : RTC Tamper 2 Event callback.
110     (+) Tamper3EventCallback         : RTC Tamper 3 Event callback.
111     (+) MspInitCallback              : RTC MspInit callback.
112     (+) MspDeInitCallback            : RTC MspDeInit callback.
113   This function takes as parameters the HAL peripheral handle, the Callback ID
114   and a pointer to the user callback function.
115 
116   Use function @ref HAL_RTC_UnRegisterCallback() to reset a callback to the default
117   weak function.
118   @ref HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
119   and the Callback ID.
120   This function allows to reset following callbacks:
121     (+) AlarmAEventCallback          : RTC Alarm A Event callback.
122     (+) AlarmBEventCallback          : RTC Alarm B Event callback.
123     (+) TimeStampEventCallback       : RTC TimeStamp Event callback.
124     (+) WakeUpTimerEventCallback     : RTC WakeUpTimer Event callback.
125     (+) Tamper1EventCallback         : RTC Tamper 1 Event callback.
126     (+) Tamper2EventCallback         : RTC Tamper 2 Event callback.
127     (+) Tamper3EventCallback         : RTC Tamper 3 Event callback.
128     (+) MspInitCallback              : RTC MspInit callback.
129     (+) MspDeInitCallback            : RTC MspDeInit callback.
130 
131   By default, after the @ref HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET,
132   all callbacks are set to the corresponding weak functions :
133   examples @ref AlarmAEventCallback(), @ref TimeStampEventCallback().
134   Exception done for MspInit and MspDeInit callbacks that are reset to the legacy weak function
135   in the @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit() only when these callbacks are null
136   (not registered beforehand).
137   If not, MspInit or MspDeInit are not null, @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit()
138   keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
139 
140   Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only.
141   Exception done MspInit/MspDeInit that can be registered/unregistered
142   in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state,
143   thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
144   In that case first register the MspInit/MspDeInit user callbacks
145   using @ref HAL_RTC_RegisterCallback() before calling @ref HAL_RTC_DeInit()
146   or @ref HAL_RTC_Init() function.
147 
148   When The compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or
149   not defined, the callback registration feature is not available and all callbacks
150   are set to the corresponding weak functions.
151 
152    @endverbatim
153   ******************************************************************************
154   * @attention
155   *
156   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
157   *
158   * Redistribution and use in source and binary forms, with or without modification,
159   * are permitted provided that the following conditions are met:
160   *   1. Redistributions of source code must retain the above copyright notice,
161   *      this list of conditions and the following disclaimer.
162   *   2. Redistributions in binary form must reproduce the above copyright notice,
163   *      this list of conditions and the following disclaimer in the documentation
164   *      and/or other materials provided with the distribution.
165   *   3. Neither the name of STMicroelectronics nor the names of its contributors
166   *      may be used to endorse or promote products derived from this software
167   *      without specific prior written permission.
168   *
169   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
170   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
172   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
173   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
174   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
175   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
176   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
177   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
178   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
179   *
180   ******************************************************************************
181   */
182 
183 /* Includes ------------------------------------------------------------------*/
184 #include "stm32l4xx_hal.h"
185 
186 /** @addtogroup STM32L4xx_HAL_Driver
187   * @{
188   */
189 
190 
191 /** @addtogroup RTC
192   * @brief RTC HAL module driver
193   * @{
194   */
195 
196 #ifdef HAL_RTC_MODULE_ENABLED
197 
198 /* Private typedef -----------------------------------------------------------*/
199 /* Private define ------------------------------------------------------------*/
200 /* Private macro -------------------------------------------------------------*/
201 /* Private variables ---------------------------------------------------------*/
202 /* Private function prototypes -----------------------------------------------*/
203 /* Exported functions --------------------------------------------------------*/
204 
205 /** @addtogroup RTC_Exported_Functions
206   * @{
207   */
208 
209 /** @addtogroup RTC_Exported_Functions_Group1
210  *  @brief    Initialization and Configuration functions
211  *
212 @verbatim
213  ===============================================================================
214               ##### Initialization and de-initialization functions #####
215  ===============================================================================
216    [..] This section provides functions allowing to initialize and configure the
217          RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable
218          RTC registers Write protection, enter and exit the RTC initialization mode,
219          RTC registers synchronization check and reference clock detection enable.
220          (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base.
221              It is split into 2 programmable prescalers to minimize power consumption.
222              (++) A 7-bit asynchronous prescaler and a 15-bit synchronous prescaler.
223              (++) When both prescalers are used, it is recommended to configure the
224                  asynchronous prescaler to a high value to minimize power consumption.
225          (#) All RTC registers are Write protected. Writing to the RTC registers
226              is enabled by writing a key into the Write Protection register, RTC_WPR.
227          (#) To configure the RTC Calendar, user application should enter
228              initialization mode. In this mode, the calendar counter is stopped
229              and its value can be updated. When the initialization sequence is
230              complete, the calendar restarts counting after 4 RTCCLK cycles.
231          (#) To read the calendar through the shadow registers after Calendar
232              initialization, calendar update or after wakeup from low power modes
233              the software must first clear the RSF flag. The software must then
234              wait until it is set again before reading the calendar, which means
235              that the calendar registers have been correctly copied into the
236              RTC_TR and RTC_DR shadow registers.The HAL_RTC_WaitForSynchro() function
237              implements the above software sequence (RSF clear and RSF check).
238 
239 @endverbatim
240   * @{
241   */
242 
243 /**
244   * @brief  Initialize the RTC peripheral
245   * @param  hrtc RTC handle
246   * @retval HAL status
247   */
HAL_RTC_Init(RTC_HandleTypeDef * hrtc)248 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
249 {
250   HAL_StatusTypeDef status = HAL_ERROR;
251 
252   /* Check the RTC peripheral state */
253   if(hrtc != NULL)
254   {
255     status = HAL_OK;
256     /* Check the parameters */
257     assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
258     assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));
259     assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
260     assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));
261     assert_param(IS_RTC_OUTPUT(hrtc->Init.OutPut));
262     assert_param(IS_RTC_OUTPUT_REMAP(hrtc->Init.OutPutRemap));
263     assert_param(IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));
264     assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType));
265 #if defined(STM32L412xx) || defined(STM32L422xx)
266     assert_param(IS_RTC_OUTPUT_PULLUP(hrtc->Init.OutPutPullUp));
267 #endif
268 
269 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
270     if(hrtc->State == HAL_RTC_STATE_RESET)
271     {
272       /* Allocate lock resource and initialize it */
273       hrtc->Lock = HAL_UNLOCKED;
274       hrtc->AlarmAEventCallback          =  HAL_RTC_AlarmAEventCallback;             /* Legacy weak AlarmAEventCallback      */
275       hrtc->AlarmBEventCallback          =  HAL_RTCEx_AlarmBEventCallback;           /* Legacy weak AlarmBEventCallback      */
276       hrtc->TimeStampEventCallback       =  HAL_RTCEx_TimeStampEventCallback;        /* Legacy weak TimeStampEventCallback   */
277       hrtc->WakeUpTimerEventCallback     =  HAL_RTCEx_WakeUpTimerEventCallback;      /* Legacy weak WakeUpTimerEventCallback */
278 #if defined(RTC_TAMPER1_SUPPORT)
279       hrtc->Tamper1EventCallback         =  HAL_RTCEx_Tamper1EventCallback;          /* Legacy weak Tamper1EventCallback     */
280 #endif /* RTC_TAMPER1_SUPPORT */
281       hrtc->Tamper2EventCallback         =  HAL_RTCEx_Tamper2EventCallback;          /* Legacy weak Tamper2EventCallback     */
282 #if defined(RTC_TAMPER3_SUPPORT)
283       hrtc->Tamper3EventCallback         =  HAL_RTCEx_Tamper3EventCallback;          /* Legacy weak Tamper3EventCallback     */
284 #endif /* RTC_TAMPER3_SUPPORT */
285 
286       if(hrtc->MspInitCallback == NULL)
287       {
288         hrtc->MspInitCallback = HAL_RTC_MspInit;
289       }
290       /* Init the low level hardware */
291       hrtc->MspInitCallback(hrtc);
292 
293       if(hrtc->MspDeInitCallback == NULL)
294       {
295         hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
296       }
297     }
298 #else /* #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
299     if(hrtc->State == HAL_RTC_STATE_RESET)
300     {
301       /* Allocate lock resource and initialize it */
302       hrtc->Lock = HAL_UNLOCKED;
303 
304       /* Initialize RTC MSP */
305       HAL_RTC_MspInit(hrtc);
306     }
307 #endif /* #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
308 
309 #if defined(STM32L412xx) || defined(STM32L422xx)
310     /* Process TAMP ip offset from RTC one */
311     hrtc->TampOffset = (TAMP_BASE - RTC_BASE);
312 #endif
313     /* Set RTC state */
314     hrtc->State = HAL_RTC_STATE_BUSY;
315 
316     /* Disable the write protection for RTC registers */
317     __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
318 
319     /* Set Initialization mode */
320     if(RTC_EnterInitMode(hrtc) != HAL_OK)
321     {
322       /* Enable the write protection for RTC registers */
323       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
324 
325       /* Set RTC state */
326       hrtc->State = HAL_RTC_STATE_ERROR;
327 
328       status = HAL_ERROR;
329     }
330     else
331     {
332 #if defined(STM32L412xx) || defined(STM32L422xx)
333       /* Clear RTC_CR FMT, OSEL, POL and TAMPOE Bits */
334       hrtc->Instance->CR &= ~(RTC_CR_FMT | RTC_CR_POL | RTC_CR_OSEL | RTC_CR_TAMPOE);
335 #else
336       /* Clear RTC_CR FMT, OSEL and POL Bits */
337       hrtc->Instance->CR &= ~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL);
338 #endif
339       /* Set RTC_CR register */
340       hrtc->Instance->CR |= (hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);
341 
342       /* Configure the RTC PRER */
343       hrtc->Instance->PRER = (hrtc->Init.SynchPrediv);
344       hrtc->Instance->PRER |= (hrtc->Init.AsynchPrediv << RTC_PRER_PREDIV_A_Pos);
345 
346       /* Exit Initialization mode */
347 #if defined(STM32L412xx) || defined(STM32L422xx)
348       CLEAR_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
349 #else
350       CLEAR_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
351 #endif
352 
353       /* If  CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
354       if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
355       {
356         if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
357         {
358           /* Enable the write protection for RTC registers */
359           __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
360 
361           hrtc->State = HAL_RTC_STATE_ERROR;
362           status = HAL_ERROR;
363         }
364       }
365 
366       if (status == HAL_OK)
367       {
368 #if defined(STM32L412xx) || defined(STM32L422xx)
369         hrtc->Instance->CR &= ~(RTC_CR_TAMPALRM_PU | RTC_CR_TAMPALRM_TYPE | RTC_CR_OUT2EN);
370         hrtc->Instance->CR |= (hrtc->Init.OutPutPullUp | hrtc->Init.OutPutType | hrtc->Init.OutPutRemap);
371 #else
372         hrtc->Instance->OR &= ~(RTC_OR_ALARMOUTTYPE | RTC_OR_OUT_RMP);
373         hrtc->Instance->OR |= (hrtc->Init.OutPutType | hrtc->Init.OutPutRemap);
374 #endif
375 
376         /* Enable the write protection for RTC registers */
377         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
378 
379         /* Set RTC state */
380         hrtc->State = HAL_RTC_STATE_READY;
381       }
382     }
383   }
384 
385   return status;
386 }
387 
388 /**
389   * @brief  DeInitialize the RTC peripheral.
390   * @note   This function doesn't reset the RTC Backup Data registers.
391   * @param  hrtc RTC handle
392   * @retval HAL status
393   */
HAL_RTC_DeInit(RTC_HandleTypeDef * hrtc)394 HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
395 {
396   HAL_StatusTypeDef status = HAL_ERROR;
397   uint32_t          tickstart;
398 
399   /* Check the RTC peripheral state */
400   if(hrtc != NULL)
401   {
402     status = HAL_OK;
403 
404     /* Check the parameters */
405     assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
406 
407     /* Set RTC state */
408     hrtc->State = HAL_RTC_STATE_BUSY;
409 
410     /* Disable the write protection for RTC registers */
411     __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
412 
413     /* Set Initialization mode */
414     if(RTC_EnterInitMode(hrtc) != HAL_OK)
415     {
416       /* Enable the write protection for RTC registers */
417       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
418 
419       /* Set RTC state */
420       hrtc->State = HAL_RTC_STATE_ERROR;
421 
422       status = HAL_ERROR;
423     }
424     else
425     {
426       /* Reset TR, DR and CR registers */
427       hrtc->Instance->TR = 0x00000000U;
428       hrtc->Instance->DR = ((uint32_t)(RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0));
429       /* Reset All CR bits except CR[2:0] */
430       hrtc->Instance->CR &= RTC_CR_WUCKSEL;
431 
432       tickstart = HAL_GetTick();
433 
434       /* Wait till WUTWF flag is set and if Time out is reached exit */
435 #if defined(STM32L412xx) || defined(STM32L422xx)
436       while(((hrtc->Instance->ICSR) & RTC_ICSR_WUTWF) == 0U)
437 #else
438       while(((hrtc->Instance->ISR) & RTC_ISR_WUTWF) == 0U)
439 #endif
440       {
441         if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
442         {
443           /* Enable the write protection for RTC registers */
444           __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
445 
446           /* Set RTC state */
447           hrtc->State = HAL_RTC_STATE_TIMEOUT;
448 
449           status = HAL_TIMEOUT;
450         }
451       }
452 
453       if(status == HAL_OK)
454       {
455         /* Reset all RTC CR register bits */
456         hrtc->Instance->CR &= 0x00000000U;
457 
458         hrtc->Instance->WUTR = RTC_WUTR_WUT;
459         hrtc->Instance->PRER = ((uint32_t)(RTC_PRER_PREDIV_A | 0x000000FFU));
460         hrtc->Instance->ALRMAR = 0x00000000U;
461         hrtc->Instance->ALRMBR = 0x00000000U;
462         hrtc->Instance->SHIFTR = 0x00000000U;
463         hrtc->Instance->CALR = 0x00000000U;
464         hrtc->Instance->ALRMASSR = 0x00000000U;
465         hrtc->Instance->ALRMBSSR = 0x00000000U;
466 
467 #if defined(STM32L412xx) || defined(STM32L422xx)
468         /* Exit initialization mode */
469         CLEAR_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
470 #else
471         /* Reset ISR register and exit initialization mode */
472         hrtc->Instance->ISR = 0x00000000U;
473 
474         /* Reset Tamper configuration register */
475         hrtc->Instance->TAMPCR = 0x00000000U;
476 
477         /* Reset Option register */
478         hrtc->Instance->OR = 0x00000000U;
479 #endif
480 
481         /* If  RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
482         if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
483         {
484           if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
485           {
486             /* Enable the write protection for RTC registers */
487             __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
488 
489             hrtc->State = HAL_RTC_STATE_ERROR;
490 
491             status = HAL_ERROR;
492           }
493         }
494       }
495     }
496 
497     if(status == HAL_OK)
498     {
499 #if defined(STM32L412xx) || defined(STM32L422xx)
500       /* Reset TAMP registers */
501       ((TAMP_TypeDef *)((uint32_t)hrtc->Instance + hrtc->TampOffset))->CR1 = 0xFFFF0000U;
502       ((TAMP_TypeDef *)((uint32_t)hrtc->Instance + hrtc->TampOffset))->CR2 = 0x00000000U;
503 #endif
504 
505       /* Enable the write protection for RTC registers */
506       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
507 
508 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
509       if(hrtc->MspDeInitCallback == NULL)
510       {
511         hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
512       }
513 
514       /* DeInit the low level hardware: CLOCK, NVIC.*/
515       hrtc->MspDeInitCallback(hrtc);
516 #else
517       /* De-Initialize RTC MSP */
518       HAL_RTC_MspDeInit(hrtc);
519 #endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */
520 
521       hrtc->State = HAL_RTC_STATE_RESET;
522 
523       /* Release Lock */
524       __HAL_UNLOCK(hrtc);
525     }
526   }
527 
528   return status;
529 }
530 
531 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
532 /**
533   * @brief  Register a User RTC Callback
534   *         To be used instead of the weak predefined callback
535   * @param  hrtc RTC handle
536   * @param  CallbackID ID of the callback to be registered
537   *         This parameter can be one of the following values:
538   *          @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID          Alarm A Event Callback ID
539   *          @arg @ref HAL_RTC_ALARM_B_EVENT_CB_ID          Alarm B Event Callback ID
540   *          @arg @ref HAL_RTC_TIMESTAMP_EVENT_CB_ID        TimeStamp Event Callback ID
541   *          @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID      WakeUp Timer Event Callback ID
542   *          @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID          Tamper 1 Callback ID
543   *          @arg @ref HAL_RTC_TAMPER2_EVENT_CB_ID          Tamper 2 Callback ID
544   *          @arg @ref HAL_RTC_TAMPER3_EVENT_CB_ID          Tamper 3 Callback ID
545   *          @arg @ref HAL_RTC_MSPINIT_CB_ID                Msp Init callback ID
546   *          @arg @ref HAL_RTC_MSPDEINIT_CB_ID              Msp DeInit callback ID
547   * @param  pCallback pointer to the Callback function
548   * @retval HAL status
549   */
HAL_RTC_RegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID,pRTC_CallbackTypeDef pCallback)550 HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, pRTC_CallbackTypeDef pCallback)
551 {
552   HAL_StatusTypeDef status = HAL_OK;
553 
554   if(pCallback == NULL)
555   {
556     return HAL_ERROR;
557   }
558 
559   /* Process locked */
560   __HAL_LOCK(hrtc);
561 
562   if(HAL_RTC_STATE_READY == hrtc->State)
563   {
564     switch (CallbackID)
565     {
566     case HAL_RTC_ALARM_A_EVENT_CB_ID :
567       hrtc->AlarmAEventCallback = pCallback;
568       break;
569 
570     case HAL_RTC_ALARM_B_EVENT_CB_ID :
571       hrtc->AlarmBEventCallback = pCallback;
572       break;
573 
574     case HAL_RTC_TIMESTAMP_EVENT_CB_ID :
575       hrtc->TimeStampEventCallback = pCallback;
576       break;
577 
578     case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID :
579       hrtc->WakeUpTimerEventCallback = pCallback;
580       break;
581 
582 #if defined(RTC_TAMPER1_SUPPORT)
583     case HAL_RTC_TAMPER1_EVENT_CB_ID :
584       hrtc->Tamper1EventCallback = pCallback;
585       break;
586 #endif /* RTC_TAMPER1_SUPPORT */
587 
588     case HAL_RTC_TAMPER2_EVENT_CB_ID :
589       hrtc->Tamper2EventCallback = pCallback;
590       break;
591 
592 #if defined(RTC_TAMPER3_SUPPORT)
593     case HAL_RTC_TAMPER3_EVENT_CB_ID :
594       hrtc->Tamper3EventCallback = pCallback;
595       break;
596 #endif /* RTC_TAMPER3_SUPPORT */
597 
598    case HAL_RTC_MSPINIT_CB_ID :
599       hrtc->MspInitCallback = pCallback;
600       break;
601 
602    case HAL_RTC_MSPDEINIT_CB_ID :
603       hrtc->MspDeInitCallback = pCallback;
604       break;
605 
606     default :
607      /* Return error status */
608       status =  HAL_ERROR;
609       break;
610     }
611   }
612   else if(HAL_RTC_STATE_RESET == hrtc->State)
613   {
614     switch (CallbackID)
615     {
616     case HAL_RTC_MSPINIT_CB_ID :
617       hrtc->MspInitCallback = pCallback;
618       break;
619 
620    case HAL_RTC_MSPDEINIT_CB_ID :
621       hrtc->MspDeInitCallback = pCallback;
622       break;
623 
624     default :
625      /* Return error status */
626       status =  HAL_ERROR;
627       break;
628     }
629   }
630   else
631   {
632     /* Return error status */
633     status =  HAL_ERROR;
634   }
635 
636   /* Release Lock */
637   __HAL_UNLOCK(hrtc);
638 
639   return status;
640 }
641 
642 /**
643   * @brief  Unregister an RTC Callback
644   *         RTC callabck is redirected to the weak predefined callback
645   * @param  hrtc RTC handle
646   * @param  CallbackID ID of the callback to be unregistered
647   *         This parameter can be one of the following values:
648   *          @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID          Alarm A Event Callback ID
649   *          @arg @ref HAL_RTC_ALARM_B_EVENT_CB_ID          Alarm B Event Callback ID
650   *          @arg @ref HAL_RTC_TIMESTAMP_EVENT_CB_ID        TimeStamp Event Callback ID
651   *          @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID      WakeUp Timer Event Callback ID
652   *          @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID          Tamper 1 Callback ID
653   *          @arg @ref HAL_RTC_TAMPER2_EVENT_CB_ID          Tamper 2 Callback ID
654   *          @arg @ref HAL_RTC_TAMPER3_EVENT_CB_ID          Tamper 3 Callback ID
655   *          @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID
656   *          @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID
657   * @retval HAL status
658   */
HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID)659 HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID)
660 {
661   HAL_StatusTypeDef status = HAL_OK;
662 
663   /* Process locked */
664   __HAL_LOCK(hrtc);
665 
666   if(HAL_RTC_STATE_READY == hrtc->State)
667   {
668     switch (CallbackID)
669     {
670     case HAL_RTC_ALARM_A_EVENT_CB_ID :
671       hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback;         /* Legacy weak AlarmAEventCallback    */
672       break;
673 
674     case HAL_RTC_ALARM_B_EVENT_CB_ID :
675       hrtc->AlarmBEventCallback = HAL_RTCEx_AlarmBEventCallback;          /* Legacy weak AlarmBEventCallback */
676       break;
677 
678     case HAL_RTC_TIMESTAMP_EVENT_CB_ID :
679       hrtc->TimeStampEventCallback = HAL_RTCEx_TimeStampEventCallback;    /* Legacy weak TimeStampEventCallback    */
680       break;
681 
682     case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID :
683       hrtc->WakeUpTimerEventCallback = HAL_RTCEx_WakeUpTimerEventCallback; /* Legacy weak WakeUpTimerEventCallback */
684       break;
685 
686 #if defined(RTC_TAMPER1_SUPPORT)
687     case HAL_RTC_TAMPER1_EVENT_CB_ID :
688       hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback;         /* Legacy weak Tamper1EventCallback   */
689       break;
690 #endif /* RTC_TAMPER1_SUPPORT */
691 
692     case HAL_RTC_TAMPER2_EVENT_CB_ID :
693       hrtc->Tamper2EventCallback = HAL_RTCEx_Tamper2EventCallback;         /* Legacy weak Tamper2EventCallback         */
694       break;
695 
696 #if defined(RTC_TAMPER3_SUPPORT)
697     case HAL_RTC_TAMPER3_EVENT_CB_ID :
698       hrtc->Tamper3EventCallback = HAL_RTCEx_Tamper3EventCallback;         /* Legacy weak Tamper3EventCallback         */
699       break;
700 #endif /* RTC_TAMPER3_SUPPORT */
701 
702     case HAL_RTC_MSPINIT_CB_ID :
703       hrtc->MspInitCallback = HAL_RTC_MspInit;
704       break;
705 
706     case HAL_RTC_MSPDEINIT_CB_ID :
707       hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
708       break;
709 
710     default :
711      /* Return error status */
712       status =  HAL_ERROR;
713       break;
714     }
715   }
716   else if(HAL_RTC_STATE_RESET == hrtc->State)
717   {
718     switch (CallbackID)
719     {
720     case HAL_RTC_MSPINIT_CB_ID :
721       hrtc->MspInitCallback = HAL_RTC_MspInit;
722       break;
723 
724     case HAL_RTC_MSPDEINIT_CB_ID :
725       hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
726       break;
727 
728     default :
729      /* Return error status */
730       status =  HAL_ERROR;
731       break;
732     }
733   }
734   else
735   {
736     /* Return error status */
737     status =  HAL_ERROR;
738   }
739 
740   /* Release Lock */
741   __HAL_UNLOCK(hrtc);
742 
743   return status;
744 }
745 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
746 
747 /**
748   * @brief  Initialize the RTC MSP.
749   * @param  hrtc RTC handle
750   * @retval None
751   */
HAL_RTC_MspInit(RTC_HandleTypeDef * hrtc)752 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
753 {
754   /* Prevent unused argument(s) compilation warning */
755   UNUSED(hrtc);
756 
757   /* NOTE : This function should not be modified, when the callback is needed,
758             the HAL_RTC_MspInit could be implemented in the user file
759    */
760 }
761 
762 /**
763   * @brief  DeInitialize the RTC MSP.
764   * @param  hrtc RTC handle
765   * @retval None
766   */
HAL_RTC_MspDeInit(RTC_HandleTypeDef * hrtc)767 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
768 {
769   /* Prevent unused argument(s) compilation warning */
770   UNUSED(hrtc);
771 
772   /* NOTE : This function should not be modified, when the callback is needed,
773             the HAL_RTC_MspDeInit could be implemented in the user file
774    */
775 }
776 
777 /**
778   * @}
779   */
780 
781 /** @addtogroup RTC_Exported_Functions_Group2
782  *  @brief   RTC Time and Date functions
783  *
784 @verbatim
785  ===============================================================================
786                  ##### RTC Time and Date functions #####
787  ===============================================================================
788 
789  [..] This section provides functions allowing to configure Time and Date features
790 
791 @endverbatim
792   * @{
793   */
794 
795 /**
796   * @brief  Set RTC current time.
797   * @param  hrtc RTC handle
798   * @param  sTime Pointer to Time structure
799   * @param  Format Specifies the format of the entered parameters.
800   *          This parameter can be one of the following values:
801   *            @arg RTC_FORMAT_BIN: Binary data format
802   *            @arg RTC_FORMAT_BCD: BCD data format
803   * @retval HAL status
804   */
HAL_RTC_SetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)805 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
806 {
807   uint32_t tmpreg;
808 
809  /* Check the parameters */
810   assert_param(IS_RTC_FORMAT(Format));
811   assert_param(IS_RTC_DAYLIGHT_SAVING(sTime->DayLightSaving));
812   assert_param(IS_RTC_STORE_OPERATION(sTime->StoreOperation));
813 
814   /* Process Locked */
815   __HAL_LOCK(hrtc);
816 
817   hrtc->State = HAL_RTC_STATE_BUSY;
818 
819   /* Disable the write protection for RTC registers */
820   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
821 
822   /* Set Initialization mode */
823   if(RTC_EnterInitMode(hrtc) != HAL_OK)
824   {
825     /* Enable the write protection for RTC registers */
826     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
827 
828     /* Set RTC state */
829     hrtc->State = HAL_RTC_STATE_ERROR;
830 
831     /* Process Unlocked */
832     __HAL_UNLOCK(hrtc);
833 
834     return HAL_ERROR;
835   }
836   else
837   {
838     if(Format == RTC_FORMAT_BIN)
839     {
840       if((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
841       {
842         assert_param(IS_RTC_HOUR12(sTime->Hours));
843         assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
844       }
845       else
846       {
847         sTime->TimeFormat = 0x00U;
848         assert_param(IS_RTC_HOUR24(sTime->Hours));
849       }
850       assert_param(IS_RTC_MINUTES(sTime->Minutes));
851       assert_param(IS_RTC_SECONDS(sTime->Seconds));
852 
853       tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(sTime->Hours) << RTC_TR_HU_Pos) | \
854                           ((uint32_t)RTC_ByteToBcd2(sTime->Minutes) << RTC_TR_MNU_Pos) | \
855                           ((uint32_t)RTC_ByteToBcd2(sTime->Seconds) << RTC_TR_SU_Pos ) | \
856                           (((uint32_t)sTime->TimeFormat) << RTC_TR_PM_Pos));
857     }
858     else
859     {
860       if((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
861       {
862         tmpreg = RTC_Bcd2ToByte(sTime->Hours);
863         assert_param(IS_RTC_HOUR12(tmpreg));
864         assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
865       }
866       else
867       {
868         sTime->TimeFormat = 0x00U;
869         assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
870       }
871       assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
872       assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
873       tmpreg = (((uint32_t)(sTime->Hours) << RTC_TR_HU_Pos) | \
874                 ((uint32_t)(sTime->Minutes) << RTC_TR_MNU_Pos) | \
875                 ((uint32_t)(sTime->Seconds) << RTC_TR_SU_Pos) | \
876                 ((uint32_t)(sTime->TimeFormat) << RTC_TR_PM_Pos));
877     }
878 
879     /* Set the RTC_TR register */
880     hrtc->Instance->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
881 
882     /* Clear the bits to be configured */
883     hrtc->Instance->CR &= ((uint32_t)~RTC_CR_BKP);
884 
885     /* Configure the RTC_CR register */
886     hrtc->Instance->CR |= (uint32_t)(sTime->DayLightSaving | sTime->StoreOperation);
887 
888     /* Exit Initialization mode */
889 #if defined(STM32L412xx) || defined(STM32L422xx)
890     CLEAR_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
891 #else
892     CLEAR_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
893 #endif
894 
895     /* If  CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
896     if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
897     {
898       if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
899       {
900         /* Enable the write protection for RTC registers */
901         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
902 
903         hrtc->State = HAL_RTC_STATE_ERROR;
904 
905         /* Process Unlocked */
906         __HAL_UNLOCK(hrtc);
907 
908         return HAL_ERROR;
909       }
910     }
911 
912     /* Enable the write protection for RTC registers */
913     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
914 
915    hrtc->State = HAL_RTC_STATE_READY;
916 
917    __HAL_UNLOCK(hrtc);
918 
919    return HAL_OK;
920   }
921 }
922 
923 /**
924   * @brief  Get RTC current time.
925   * @note  You can use SubSeconds and SecondFraction (sTime structure fields returned) to convert SubSeconds
926   *        value in second fraction ratio with time unit following generic formula:
927   *        Second fraction ratio * time_unit= [(SecondFraction-SubSeconds)/(SecondFraction+1)] * time_unit
928   *        This conversion can be performed only if no shift operation is pending (ie. SHFP=0) when PREDIV_S >= SS
929   * @note  You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values
930   *        in the higher-order calendar shadow registers to ensure consistency between the time and date values.
931   *        Reading RTC current time locks the values in calendar shadow registers until Current date is read
932   *        to ensure consistency between the time and date values.
933   * @param  hrtc RTC handle
934   * @param  sTime Pointer to Time structure with Hours, Minutes and Seconds fields returned
935   *                with input format (BIN or BCD), also SubSeconds field returning the
936   *                RTC_SSR register content and SecondFraction field the Synchronous pre-scaler
937   *                factor to be used for second fraction ratio computation.
938   * @param  Format Specifies the format of the entered parameters.
939   *          This parameter can be one of the following values:
940   *            @arg RTC_FORMAT_BIN: Binary data format
941   *            @arg RTC_FORMAT_BCD: BCD data format
942   * @retval HAL status
943   */
HAL_RTC_GetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)944 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
945 {
946   uint32_t tmpreg;
947 
948   /* Check the parameters */
949   assert_param(IS_RTC_FORMAT(Format));
950 
951   /* Get subseconds structure field from the corresponding register*/
952   sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR);
953 
954   /* Get SecondFraction structure field from the corresponding register field*/
955   sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S);
956 
957   /* Get the TR register */
958   tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);
959 
960   /* Fill the structure fields with the read parameters */
961   sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos);
962   sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos);
963   sTime->Seconds = (uint8_t)((tmpreg & (RTC_TR_ST | RTC_TR_SU)) >> RTC_TR_SU_Pos);
964   sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> RTC_TR_PM_Pos);
965 
966   /* Check the input parameters format */
967   if(Format == RTC_FORMAT_BIN)
968   {
969     /* Convert the time structure parameters to Binary format */
970     sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours);
971     sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes);
972     sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds);
973   }
974 
975   return HAL_OK;
976 }
977 
978 /**
979   * @brief  Set RTC current date.
980   * @param  hrtc RTC handle
981   * @param  sDate Pointer to date structure
982   * @param  Format specifies the format of the entered parameters.
983   *          This parameter can be one of the following values:
984   *            @arg RTC_FORMAT_BIN: Binary data format
985   *            @arg RTC_FORMAT_BCD: BCD data format
986   * @retval HAL status
987   */
HAL_RTC_SetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)988 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
989 {
990   uint32_t datetmpreg;
991 
992  /* Check the parameters */
993   assert_param(IS_RTC_FORMAT(Format));
994 
995  /* Process Locked */
996  __HAL_LOCK(hrtc);
997 
998   hrtc->State = HAL_RTC_STATE_BUSY;
999 
1000   if((Format == RTC_FORMAT_BIN) && ((sDate->Month & 0x10U) == 0x10U))
1001   {
1002     sDate->Month = (uint8_t)((sDate->Month & (uint8_t)~(0x10U)) + (uint8_t)0x0AU);
1003   }
1004 
1005   assert_param(IS_RTC_WEEKDAY(sDate->WeekDay));
1006 
1007   if(Format == RTC_FORMAT_BIN)
1008   {
1009     assert_param(IS_RTC_YEAR(sDate->Year));
1010     assert_param(IS_RTC_MONTH(sDate->Month));
1011     assert_param(IS_RTC_DATE(sDate->Date));
1012 
1013    datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year) << RTC_DR_YU_Pos) | \
1014                  ((uint32_t)RTC_ByteToBcd2(sDate->Month) << RTC_DR_MU_Pos) | \
1015                  ((uint32_t)RTC_ByteToBcd2(sDate->Date) << RTC_DR_DU_Pos) | \
1016                  ((uint32_t)sDate->WeekDay << RTC_DR_WDU_Pos));
1017   }
1018   else
1019   {
1020     assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
1021     assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
1022     assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
1023 
1024     datetmpreg = ((((uint32_t)sDate->Year) << RTC_DR_YU_Pos) | \
1025                   (((uint32_t)sDate->Month) << RTC_DR_MU_Pos) | \
1026                   (((uint32_t)sDate->Date) << RTC_DR_DU_Pos) | \
1027                   (((uint32_t)sDate->WeekDay) << RTC_DR_WDU_Pos));
1028   }
1029 
1030   /* Disable the write protection for RTC registers */
1031   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1032 
1033   /* Set Initialization mode */
1034   if(RTC_EnterInitMode(hrtc) != HAL_OK)
1035   {
1036     /* Enable the write protection for RTC registers */
1037     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1038 
1039     /* Set RTC state*/
1040     hrtc->State = HAL_RTC_STATE_ERROR;
1041 
1042     /* Process Unlocked */
1043     __HAL_UNLOCK(hrtc);
1044 
1045     return HAL_ERROR;
1046   }
1047   else
1048   {
1049     /* Set the RTC_DR register */
1050     hrtc->Instance->DR = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK);
1051 
1052     /* Exit Initialization mode */
1053 #if defined(STM32L412xx) || defined(STM32L422xx)
1054     CLEAR_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
1055 #else
1056     CLEAR_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
1057 #endif
1058 
1059     /* If  CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
1060     if((hrtc->Instance->CR & RTC_CR_BYPSHAD) == 0U)
1061     {
1062       if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
1063       {
1064         /* Enable the write protection for RTC registers */
1065         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1066 
1067         hrtc->State = HAL_RTC_STATE_ERROR;
1068 
1069         /* Process Unlocked */
1070         __HAL_UNLOCK(hrtc);
1071 
1072         return HAL_ERROR;
1073       }
1074     }
1075 
1076     /* Enable the write protection for RTC registers */
1077     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1078 
1079     hrtc->State = HAL_RTC_STATE_READY ;
1080 
1081     /* Process Unlocked */
1082     __HAL_UNLOCK(hrtc);
1083 
1084     return HAL_OK;
1085   }
1086 }
1087 
1088 /**
1089   * @brief  Get RTC current date.
1090   * @note  You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values
1091   *        in the higher-order calendar shadow registers to ensure consistency between the time and date values.
1092   *        Reading RTC current time locks the values in calendar shadow registers until Current date is read.
1093   * @param  hrtc RTC handle
1094   * @param  sDate Pointer to Date structure
1095   * @param  Format Specifies the format of the entered parameters.
1096   *          This parameter can be one of the following values:
1097   *            @arg RTC_FORMAT_BIN:  Binary data format
1098   *            @arg RTC_FORMAT_BCD:  BCD data format
1099   * @retval HAL status
1100   */
HAL_RTC_GetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)1101 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
1102 {
1103   uint32_t datetmpreg;
1104 
1105   /* Check the parameters */
1106   assert_param(IS_RTC_FORMAT(Format));
1107 
1108   /* Get the DR register */
1109   datetmpreg = (uint32_t)(hrtc->Instance->DR & RTC_DR_RESERVED_MASK);
1110 
1111   /* Fill the structure fields with the read parameters */
1112   sDate->Year =  (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos);
1113   sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos);
1114   sDate->Date =  (uint8_t)((datetmpreg & (RTC_DR_DT | RTC_DR_DU)) >> RTC_DR_DU_Pos);
1115   sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> RTC_DR_WDU_Pos);
1116 
1117   /* Check the input parameters format */
1118   if(Format == RTC_FORMAT_BIN)
1119   {
1120     /* Convert the date structure parameters to Binary format */
1121     sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year);
1122     sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month);
1123     sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date);
1124   }
1125   return HAL_OK;
1126 }
1127 
1128 /**
1129   * @}
1130   */
1131 
1132 /** @addtogroup RTC_Exported_Functions_Group3
1133  *  @brief   RTC Alarm functions
1134  *
1135 @verbatim
1136  ===============================================================================
1137                  ##### RTC Alarm functions #####
1138  ===============================================================================
1139 
1140  [..] This section provides functions allowing to configure Alarm feature
1141 
1142 @endverbatim
1143   * @{
1144   */
1145 /**
1146   * @brief  Set the specified RTC Alarm.
1147   * @param  hrtc RTC handle
1148   * @param  sAlarm Pointer to Alarm structure
1149   * @param  Format Specifies the format of the entered parameters.
1150   *          This parameter can be one of the following values:
1151   *             @arg RTC_FORMAT_BIN: Binary data format
1152   *             @arg RTC_FORMAT_BCD: BCD data format
1153   * @retval HAL status
1154   */
HAL_RTC_SetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1155 HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1156 {
1157   uint32_t tickstart;
1158   uint32_t tmpreg, subsecondtmpreg;
1159 
1160   /* Check the parameters */
1161   assert_param(IS_RTC_FORMAT(Format));
1162   assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1163   assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask));
1164   assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel));
1165   assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds));
1166   assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask));
1167 
1168   /* Process Locked */
1169   __HAL_LOCK(hrtc);
1170 
1171   hrtc->State = HAL_RTC_STATE_BUSY;
1172 
1173   if(Format == RTC_FORMAT_BIN)
1174   {
1175     if((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1176     {
1177       assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours));
1178       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1179     }
1180     else
1181     {
1182       sAlarm->AlarmTime.TimeFormat = 0x00U;
1183       assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1184     }
1185     assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1186     assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1187 
1188     if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1189     {
1190       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay));
1191     }
1192     else
1193     {
1194       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay));
1195     }
1196     tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1197               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1198               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \
1199               ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \
1200               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay ) << RTC_ALRMAR_DU_Pos) | \
1201               ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \
1202               ((uint32_t)sAlarm->AlarmMask));
1203   }
1204   else
1205   {
1206     if((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1207     {
1208       tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours);
1209       assert_param(IS_RTC_HOUR12(tmpreg));
1210       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1211     }
1212     else
1213     {
1214       sAlarm->AlarmTime.TimeFormat = 0x00U;
1215       assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1216     }
1217 
1218     assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1219     assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1220 
1221     if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1222     {
1223       tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1224       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg));
1225     }
1226     else
1227     {
1228       tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1229       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg));
1230     }
1231 
1232     tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1233               ((uint32_t)(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1234               ((uint32_t)(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \
1235               ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \
1236               ((uint32_t)(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \
1237               ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \
1238               ((uint32_t)sAlarm->AlarmMask));
1239   }
1240 
1241   /* Configure the Alarm A or Alarm B Sub Second registers */
1242   subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | (uint32_t)(sAlarm->AlarmSubSecondMask));
1243 
1244   /* Disable the write protection for RTC registers */
1245   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1246 
1247   /* Configure the Alarm register */
1248   if(sAlarm->Alarm == RTC_ALARM_A)
1249   {
1250     /* Disable the Alarm A interrupt */
1251     __HAL_RTC_ALARMA_DISABLE(hrtc);
1252     /* Clear flag alarm A */
1253     __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1254     /* In case of interrupt mode is used, the interrupt source must disabled */
1255     __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1256 
1257     tickstart = HAL_GetTick();
1258     /* Wait till RTC ALRAWF flag is set and if Time out is reached exit */
1259     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1260     {
1261       if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1262       {
1263         /* Enable the write protection for RTC registers */
1264         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1265 
1266         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1267 
1268         /* Process Unlocked */
1269         __HAL_UNLOCK(hrtc);
1270 
1271         return HAL_TIMEOUT;
1272       }
1273     }
1274 
1275     hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
1276     /* Configure the Alarm A Sub Second register */
1277     hrtc->Instance->ALRMASSR = subsecondtmpreg;
1278     /* Configure the Alarm state: Enable Alarm */
1279     __HAL_RTC_ALARMA_ENABLE(hrtc);
1280   }
1281   else
1282   {
1283     /* Disable the Alarm B interrupt */
1284     __HAL_RTC_ALARMB_DISABLE(hrtc);
1285     /* Clear flag alarm B */
1286     __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF);
1287     /* In case of interrupt mode is used, the interrupt source must disabled */
1288     __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRB);
1289 
1290     tickstart = HAL_GetTick();
1291     /* Wait till RTC ALRBWF flag is set and if Time out is reached exit */
1292     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == 0U)
1293     {
1294       if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1295       {
1296         /* Enable the write protection for RTC registers */
1297         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1298 
1299         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1300 
1301         /* Process Unlocked */
1302         __HAL_UNLOCK(hrtc);
1303 
1304         return HAL_TIMEOUT;
1305       }
1306     }
1307 
1308     hrtc->Instance->ALRMBR = (uint32_t)tmpreg;
1309     /* Configure the Alarm B Sub Second register */
1310     hrtc->Instance->ALRMBSSR = subsecondtmpreg;
1311     /* Configure the Alarm state: Enable Alarm */
1312     __HAL_RTC_ALARMB_ENABLE(hrtc);
1313   }
1314 
1315   /* Enable the write protection for RTC registers */
1316   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1317 
1318   /* Change RTC state */
1319   hrtc->State = HAL_RTC_STATE_READY;
1320 
1321   /* Process Unlocked */
1322   __HAL_UNLOCK(hrtc);
1323 
1324   return HAL_OK;
1325 }
1326 
1327 /**
1328   * @brief  Set the specified RTC Alarm with Interrupt.
1329   * @note   The Alarm register can only be written when the corresponding Alarm
1330   *         is disabled (Use the HAL_RTC_DeactivateAlarm()).
1331   * @note   The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
1332   * @param  hrtc RTC handle
1333   * @param  sAlarm Pointer to Alarm structure
1334   * @param  Format Specifies the format of the entered parameters.
1335   *          This parameter can be one of the following values:
1336   *             @arg RTC_FORMAT_BIN: Binary data format
1337   *             @arg RTC_FORMAT_BCD: BCD data format
1338   * @retval HAL status
1339   */
HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1340 HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1341 {
1342   uint32_t tickstart;
1343   uint32_t tmpreg, subsecondtmpreg;
1344 
1345   /* Check the parameters */
1346   assert_param(IS_RTC_FORMAT(Format));
1347   assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1348   assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask));
1349   assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel));
1350   assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds));
1351   assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask));
1352 
1353   /* Process Locked */
1354   __HAL_LOCK(hrtc);
1355 
1356   hrtc->State = HAL_RTC_STATE_BUSY;
1357 
1358   if(Format == RTC_FORMAT_BIN)
1359   {
1360     if((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1361     {
1362       assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours));
1363       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1364     }
1365     else
1366     {
1367       sAlarm->AlarmTime.TimeFormat = 0x00U;
1368       assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1369     }
1370     assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1371     assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1372 
1373     if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1374     {
1375       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay));
1376     }
1377     else
1378     {
1379       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay));
1380     }
1381 
1382     tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1383               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1384               ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \
1385               ((uint32_t)(sAlarm->AlarmTime.TimeFormat << RTC_ALRMAR_PM_Pos)) | \
1386               ((uint32_t)(RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos)) | \
1387               ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \
1388               ((uint32_t)sAlarm->AlarmMask));
1389   }
1390   else
1391   {
1392     if((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1393     {
1394       tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours);
1395       assert_param(IS_RTC_HOUR12(tmpreg));
1396       assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1397     }
1398     else
1399     {
1400       sAlarm->AlarmTime.TimeFormat = 0x00U;
1401       assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1402     }
1403 
1404     assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1405     assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1406 
1407     if(sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1408     {
1409       tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1410       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(tmpreg));
1411     }
1412     else
1413     {
1414       tmpreg = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1415       assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(tmpreg));
1416     }
1417 
1418     tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1419               ((uint32_t)(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1420               ((uint32_t)(sAlarm->AlarmTime.Seconds) << RTC_ALRMAR_SU_Pos) | \
1421               ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_ALRMAR_PM_Pos) | \
1422               ((uint32_t)(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \
1423               ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \
1424               ((uint32_t)sAlarm->AlarmMask));
1425   }
1426   /* Configure the Alarm A or Alarm B Sub Second registers */
1427   subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | (uint32_t)(sAlarm->AlarmSubSecondMask));
1428 
1429   /* Disable the write protection for RTC registers */
1430   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1431 
1432   /* Configure the Alarm register */
1433   if(sAlarm->Alarm == RTC_ALARM_A)
1434   {
1435     /* Disable the Alarm A interrupt */
1436     __HAL_RTC_ALARMA_DISABLE(hrtc);
1437 
1438     /* Clear flag alarm A */
1439     __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1440 
1441     tickstart = HAL_GetTick();
1442     /* Wait till RTC ALRAWF flag is set and if Time out is reached exit */
1443     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1444     {
1445       if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1446       {
1447         /* Enable the write protection for RTC registers */
1448         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1449 
1450         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1451 
1452         /* Process Unlocked */
1453         __HAL_UNLOCK(hrtc);
1454 
1455         return HAL_TIMEOUT;
1456       }
1457     }
1458 
1459     hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
1460     /* Configure the Alarm A Sub Second register */
1461     hrtc->Instance->ALRMASSR = subsecondtmpreg;
1462     /* Configure the Alarm state: Enable Alarm */
1463     __HAL_RTC_ALARMA_ENABLE(hrtc);
1464     /* Configure the Alarm interrupt */
1465     __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA);
1466   }
1467   else
1468   {
1469     /* Disable the Alarm B interrupt */
1470     __HAL_RTC_ALARMB_DISABLE(hrtc);
1471 
1472     /* Clear flag alarm B */
1473     __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF);
1474 
1475     tickstart = HAL_GetTick();
1476     /* Wait till RTC ALRBWF flag is set and if Time out is reached exit */
1477     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == 0U)
1478     {
1479       if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1480       {
1481         /* Enable the write protection for RTC registers */
1482         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1483 
1484         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1485 
1486         /* Process Unlocked */
1487         __HAL_UNLOCK(hrtc);
1488 
1489         return HAL_TIMEOUT;
1490       }
1491     }
1492 
1493     hrtc->Instance->ALRMBR = (uint32_t)tmpreg;
1494     /* Configure the Alarm B Sub Second register */
1495     hrtc->Instance->ALRMBSSR = subsecondtmpreg;
1496     /* Configure the Alarm state: Enable Alarm */
1497     __HAL_RTC_ALARMB_ENABLE(hrtc);
1498     /* Configure the Alarm interrupt */
1499     __HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRB);
1500   }
1501 
1502   /* RTC Alarm Interrupt Configuration: EXTI configuration */
1503   __HAL_RTC_ALARM_EXTI_ENABLE_IT();
1504   __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
1505 
1506   /* Enable the write protection for RTC registers */
1507   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1508 
1509   hrtc->State = HAL_RTC_STATE_READY;
1510 
1511   /* Process Unlocked */
1512   __HAL_UNLOCK(hrtc);
1513 
1514   return HAL_OK;
1515 }
1516 
1517 /**
1518   * @brief  Deactivate the specified RTC Alarm.
1519   * @param  hrtc RTC handle
1520   * @param  Alarm Specifies the Alarm.
1521   *          This parameter can be one of the following values:
1522   *            @arg RTC_ALARM_A:  AlarmA
1523   *            @arg RTC_ALARM_B:  AlarmB
1524   * @retval HAL status
1525   */
HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef * hrtc,uint32_t Alarm)1526 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
1527 {
1528   uint32_t tickstart;
1529 
1530   /* Check the parameters */
1531   assert_param(IS_RTC_ALARM(Alarm));
1532 
1533   /* Process Locked */
1534   __HAL_LOCK(hrtc);
1535 
1536   hrtc->State = HAL_RTC_STATE_BUSY;
1537 
1538   /* Disable the write protection for RTC registers */
1539   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1540 
1541   if(Alarm == RTC_ALARM_A)
1542   {
1543     /* AlarmA */
1544     __HAL_RTC_ALARMA_DISABLE(hrtc);
1545 
1546     /* In case of interrupt mode is used, the interrupt source must disabled */
1547     __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1548 
1549     tickstart = HAL_GetTick();
1550 
1551     /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */
1552     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1553     {
1554       if( (HAL_GetTick()  - tickstart ) > RTC_TIMEOUT_VALUE)
1555       {
1556         /* Enable the write protection for RTC registers */
1557         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1558 
1559         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1560 
1561         /* Process Unlocked */
1562         __HAL_UNLOCK(hrtc);
1563 
1564         return HAL_TIMEOUT;
1565       }
1566     }
1567   }
1568   else
1569   {
1570     /* AlarmB */
1571     __HAL_RTC_ALARMB_DISABLE(hrtc);
1572 
1573     /* In case of interrupt mode is used, the interrupt source must disabled */
1574     __HAL_RTC_ALARM_DISABLE_IT(hrtc,RTC_IT_ALRB);
1575 
1576     tickstart = HAL_GetTick();
1577 
1578     /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */
1579     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == 0U)
1580     {
1581       if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1582       {
1583         /* Enable the write protection for RTC registers */
1584         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1585 
1586         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1587 
1588         /* Process Unlocked */
1589         __HAL_UNLOCK(hrtc);
1590 
1591         return HAL_TIMEOUT;
1592       }
1593     }
1594   }
1595   /* Enable the write protection for RTC registers */
1596   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1597 
1598   hrtc->State = HAL_RTC_STATE_READY;
1599 
1600   /* Process Unlocked */
1601   __HAL_UNLOCK(hrtc);
1602 
1603   return HAL_OK;
1604 }
1605 
1606 /**
1607   * @brief  Get the RTC Alarm value and masks.
1608   * @param  hrtc RTC handle
1609   * @param  sAlarm Pointer to Date structure
1610   * @param  Alarm Specifies the Alarm.
1611   *          This parameter can be one of the following values:
1612   *             @arg RTC_ALARM_A: AlarmA
1613   *             @arg RTC_ALARM_B: AlarmB
1614   * @param  Format Specifies the format of the entered parameters.
1615   *          This parameter can be one of the following values:
1616   *             @arg RTC_FORMAT_BIN: Binary data format
1617   *             @arg RTC_FORMAT_BCD: BCD data format
1618   * @retval HAL status
1619   */
HAL_RTC_GetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Alarm,uint32_t Format)1620 HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
1621 {
1622   uint32_t tmpreg, subsecondtmpreg;
1623 
1624   /* Check the parameters */
1625   assert_param(IS_RTC_FORMAT(Format));
1626   assert_param(IS_RTC_ALARM(Alarm));
1627 
1628   if(Alarm == RTC_ALARM_A)
1629   {
1630     /* AlarmA */
1631     sAlarm->Alarm = RTC_ALARM_A;
1632 
1633     tmpreg = (uint32_t)(hrtc->Instance->ALRMAR);
1634     subsecondtmpreg = (uint32_t)((hrtc->Instance->ALRMASSR ) & RTC_ALRMASSR_SS);
1635 
1636     /* Fill the structure with the read parameters */
1637     sAlarm->AlarmTime.Hours = (uint8_t)((tmpreg & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> RTC_ALRMAR_HU_Pos);
1638     sAlarm->AlarmTime.Minutes = (uint8_t)((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> RTC_ALRMAR_MNU_Pos);
1639     sAlarm->AlarmTime.Seconds = (uint8_t)((tmpreg & (RTC_ALRMAR_ST | RTC_ALRMAR_SU)) >> RTC_ALRMAR_SU_Pos);
1640     sAlarm->AlarmTime.TimeFormat = (uint8_t)((tmpreg & RTC_ALRMAR_PM) >> RTC_ALRMAR_PM_Pos);
1641     sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg;
1642     sAlarm->AlarmDateWeekDay = (uint8_t)((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> RTC_ALRMAR_DU_Pos);
1643     sAlarm->AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMAR_WDSEL);
1644     sAlarm->AlarmMask = (uint32_t)(tmpreg & RTC_ALARMMASK_ALL);
1645   }
1646   else
1647   {
1648     sAlarm->Alarm = RTC_ALARM_B;
1649 
1650     tmpreg = (uint32_t)(hrtc->Instance->ALRMBR);
1651     subsecondtmpreg = (uint32_t)((hrtc->Instance->ALRMBSSR) & RTC_ALRMBSSR_SS);
1652 
1653     /* Fill the structure with the read parameters */
1654     sAlarm->AlarmTime.Hours = (uint8_t)((tmpreg & (RTC_ALRMBR_HT | RTC_ALRMBR_HU)) >> RTC_ALRMBR_HU_Pos);
1655     sAlarm->AlarmTime.Minutes = (uint8_t)((tmpreg & (RTC_ALRMBR_MNT | RTC_ALRMBR_MNU)) >> RTC_ALRMBR_MNU_Pos);
1656     sAlarm->AlarmTime.Seconds = (uint8_t)((tmpreg & (RTC_ALRMBR_ST | RTC_ALRMBR_SU)) >> RTC_ALRMBR_SU_Pos);
1657     sAlarm->AlarmTime.TimeFormat = (uint8_t)((tmpreg & RTC_ALRMBR_PM) >> RTC_ALRMBR_PM_Pos);
1658     sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg;
1659     sAlarm->AlarmDateWeekDay = (uint32_t)((tmpreg & (RTC_ALRMBR_DT | RTC_ALRMBR_DU)) >> RTC_ALRMBR_DU_Pos);
1660     sAlarm->AlarmDateWeekDaySel = (uint32_t)(tmpreg & RTC_ALRMBR_WDSEL);
1661     sAlarm->AlarmMask = (uint32_t)(tmpreg & RTC_ALARMMASK_ALL);
1662   }
1663 
1664   if(Format == RTC_FORMAT_BIN)
1665   {
1666     sAlarm->AlarmTime.Hours = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours);
1667     sAlarm->AlarmTime.Minutes = RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes);
1668     sAlarm->AlarmTime.Seconds = RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds);
1669     sAlarm->AlarmDateWeekDay = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1670   }
1671 
1672   return HAL_OK;
1673 }
1674 
1675 /**
1676   * @brief  Handle Alarm interrupt request.
1677   * @param  hrtc RTC handle
1678   * @retval None
1679   */
HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef * hrtc)1680 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc)
1681 {
1682   /* Clear the EXTI's line Flag for RTC Alarm */
1683   __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
1684 
1685 #if defined(STM32L412xx) || defined(STM32L422xx)
1686   /* Get interrupt status */
1687   uint32_t tmp = hrtc->Instance->MISR;
1688 
1689   if ((tmp & RTC_MISR_ALRAMF) != 0u)
1690   {
1691     /* Clear the AlarmA interrupt pending bit */
1692     hrtc->Instance->SCR = RTC_SCR_CALRAF;
1693 
1694 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1695     /* Call Compare Match registered Callback */
1696     hrtc->AlarmAEventCallback(hrtc);
1697   #else  /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
1698     HAL_RTC_AlarmAEventCallback(hrtc);
1699   #endif /* (USE_HAL_RTC_REGISTER_CALLBACKS == 1) */
1700   }
1701 
1702   if ((tmp & RTC_MISR_ALRBMF) != 0u)
1703   {
1704     /* Clear the AlarmB interrupt pending bit */
1705     hrtc->Instance->SCR = RTC_SCR_CALRBF;
1706 
1707 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1708     /* Call Compare Match registered Callback */
1709     hrtc->AlarmBEventCallback(hrtc);
1710 #else
1711     HAL_RTCEx_AlarmBEventCallback(hrtc);
1712 #endif
1713   }
1714 
1715 #else /* #if defined(STM32L412xx) || defined(STM32L422xx) */
1716 
1717   /* Get the AlarmA interrupt source enable status */
1718   if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA) != 0U)
1719   {
1720     /* Get the pending status of the AlarmA Interrupt */
1721     if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != 0U)
1722     {
1723       /* Clear the AlarmA interrupt pending bit */
1724       __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1725 
1726 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1727       hrtc->AlarmAEventCallback(hrtc);
1728 #else
1729       HAL_RTC_AlarmAEventCallback(hrtc);
1730 #endif
1731     }
1732   }
1733 
1734   /* Get the AlarmB interrupt source enable status */
1735   if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRB) != 0U)
1736   {
1737     /* Get the pending status of the AlarmB Interrupt */
1738     if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBF) != 0U)
1739     {
1740       /* Clear the AlarmB interrupt pending bit */
1741       __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF);
1742 
1743 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1744       hrtc->AlarmBEventCallback(hrtc);
1745 #else
1746       HAL_RTCEx_AlarmBEventCallback(hrtc);
1747 #endif
1748     }
1749   }
1750 #endif /* #if defined(STM32L412xx) || defined(STM32L422xx) */
1751 
1752   /* Change RTC state */
1753   hrtc->State = HAL_RTC_STATE_READY;
1754 }
1755 
1756 /**
1757   * @brief  Alarm A callback.
1758   * @param  hrtc RTC handle
1759   * @retval None
1760   */
HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef * hrtc)1761 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
1762 {
1763   /* Prevent unused argument(s) compilation warning */
1764   UNUSED(hrtc);
1765 
1766   /* NOTE : This function should not be modified, when the callback is needed,
1767             the HAL_RTC_AlarmAEventCallback could be implemented in the user file
1768    */
1769 }
1770 
1771 /**
1772   * @brief  Handle AlarmA Polling request.
1773   * @param  hrtc RTC handle
1774   * @param  Timeout Timeout duration
1775   * @retval HAL status
1776   */
HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)1777 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
1778 {
1779 
1780   uint32_t tickstart = HAL_GetTick();
1781 
1782   while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == 0U)
1783   {
1784     if(Timeout != HAL_MAX_DELAY)
1785     {
1786       if(((HAL_GetTick() - tickstart ) > Timeout) || (Timeout == 0U))
1787       {
1788         hrtc->State = HAL_RTC_STATE_TIMEOUT;
1789         return HAL_TIMEOUT;
1790       }
1791     }
1792   }
1793 
1794   /* Clear the Alarm interrupt pending bit */
1795   __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1796 
1797   /* Change RTC state */
1798   hrtc->State = HAL_RTC_STATE_READY;
1799 
1800   return HAL_OK;
1801 }
1802 
1803 /**
1804   * @}
1805   */
1806 
1807 /** @addtogroup RTC_Exported_Functions_Group4
1808  *  @brief   Peripheral Control functions
1809  *
1810 @verbatim
1811  ===============================================================================
1812                      ##### Peripheral Control functions #####
1813  ===============================================================================
1814     [..]
1815     This subsection provides functions allowing to
1816       (+) Wait for RTC Time and Date Synchronization
1817 
1818 @endverbatim
1819   * @{
1820   */
1821 
1822 /**
1823   * @brief  Wait until the RTC Time and Date registers (RTC_TR and RTC_DR) are
1824   *         synchronized with RTC APB clock.
1825   * @note   The RTC Resynchronization mode is write protected, use the
1826   *         __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
1827   * @note   To read the calendar through the shadow registers after Calendar
1828   *         initialization, calendar update or after wakeup from low power modes
1829   *         the software must first clear the RSF flag.
1830   *         The software must then wait until it is set again before reading
1831   *         the calendar, which means that the calendar registers have been
1832   *         correctly copied into the RTC_TR and RTC_DR shadow registers.
1833   * @param  hrtc RTC handle
1834   * @retval HAL status
1835   */
HAL_RTC_WaitForSynchro(RTC_HandleTypeDef * hrtc)1836 HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc)
1837 {
1838   uint32_t tickstart;
1839 
1840   /* Clear RSF flag */
1841 #if defined(STM32L412xx) || defined(STM32L422xx)
1842   hrtc->Instance->ICSR &= (uint32_t)RTC_RSF_MASK;
1843 #else
1844   hrtc->Instance->ISR &= (uint32_t)RTC_RSF_MASK;
1845 #endif
1846 
1847   tickstart = HAL_GetTick();
1848 
1849   /* Wait the registers to be synchronised */
1850 #if defined(STM32L412xx) || defined(STM32L422xx)
1851   while((hrtc->Instance->ICSR & RTC_ICSR_RSF) == 0U)
1852 #else
1853   while((hrtc->Instance->ISR & RTC_ISR_RSF) == 0U)
1854 #endif
1855   {
1856     if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1857     {
1858       return HAL_TIMEOUT;
1859     }
1860   }
1861 
1862   return HAL_OK;
1863 }
1864 
1865 /**
1866   * @}
1867   */
1868 
1869 /** @addtogroup RTC_Exported_Functions_Group5
1870  *  @brief   Peripheral State functions
1871  *
1872 @verbatim
1873  ===============================================================================
1874                      ##### Peripheral State functions #####
1875  ===============================================================================
1876     [..]
1877     This subsection provides functions allowing to
1878       (+) Get RTC state
1879 
1880 @endverbatim
1881   * @{
1882   */
1883 /**
1884   * @brief  Return the RTC handle state.
1885   * @param  hrtc RTC handle
1886   * @retval HAL state
1887   */
HAL_RTC_GetState(RTC_HandleTypeDef * hrtc)1888 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc)
1889 {
1890   /* Return RTC handle state */
1891   return hrtc->State;
1892 }
1893 
1894 /**
1895   * @}
1896   */
1897 
1898 /**
1899   * @}
1900   */
1901 
1902 /** @addtogroup RTC_Private_Functions
1903   * @{
1904   */
1905 /**
1906   * @brief  Enter the RTC Initialization mode.
1907   * @note   The RTC Initialization mode is write protected, use the
1908   *         __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
1909   * @param  hrtc RTC handle
1910   * @retval HAL status
1911   */
RTC_EnterInitMode(RTC_HandleTypeDef * hrtc)1912 HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
1913 {
1914   uint32_t tickstart;
1915 
1916   /* Check if the Initialization mode is set */
1917 #if defined(STM32L412xx) || defined(STM32L422xx)
1918   if((hrtc->Instance->ICSR & RTC_ICSR_INITF) == 0U)
1919   {
1920     /* Set the Initialization mode */
1921     SET_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
1922 
1923     tickstart = HAL_GetTick();
1924     /* Wait till RTC is in INIT state and if Time out is reached exit */
1925     while((hrtc->Instance->ICSR & RTC_ICSR_INITF) == 0U)
1926     {
1927       if((HAL_GetTick()  - tickstart ) > RTC_TIMEOUT_VALUE)
1928       {
1929         return HAL_TIMEOUT;
1930       }
1931     }
1932   }
1933 #else /* #if defined(STM32L412xx) || defined(STM32L422xx) */
1934   if((hrtc->Instance->ISR & RTC_ISR_INITF) == 0U)
1935   {
1936     /* Set the Initialization mode */
1937     hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK;
1938 
1939     tickstart = HAL_GetTick();
1940     /* Wait till RTC is in INIT state and if Time out is reached exit */
1941     while((hrtc->Instance->ISR & RTC_ISR_INITF) == 0U)
1942     {
1943       if((HAL_GetTick()  - tickstart ) > RTC_TIMEOUT_VALUE)
1944       {
1945         return HAL_TIMEOUT;
1946       }
1947     }
1948   }
1949 #endif /* #if defined(STM32L412xx) || defined(STM32L422xx) */
1950 
1951   return HAL_OK;
1952 }
1953 
1954 
1955 /**
1956   * @brief  Convert a 2 digit decimal to BCD format.
1957   * @param  Value Byte to be converted
1958   * @retval Converted byte
1959   */
RTC_ByteToBcd2(uint8_t Value)1960 uint8_t RTC_ByteToBcd2(uint8_t Value)
1961 {
1962   uint32_t bcdhigh = 0U;
1963   uint8_t temp = Value;
1964 
1965   while(temp >= 10U)
1966   {
1967     bcdhigh++;
1968     temp -= 10U;
1969   }
1970 
1971   return  ((uint8_t)(bcdhigh << 4U) | temp);
1972 }
1973 
1974 /**
1975   * @brief  Convert from 2 digit BCD to Binary.
1976   * @param  Value BCD value to be converted
1977   * @retval Converted word
1978   */
RTC_Bcd2ToByte(uint8_t Value)1979 uint8_t RTC_Bcd2ToByte(uint8_t Value)
1980 {
1981   uint8_t tmp;
1982   tmp = ((Value & 0xF0U) >> 4U) * 10U;
1983   return (tmp + (Value & 0x0FU));
1984 }
1985 
1986 /**
1987   * @}
1988   */
1989 
1990 #endif /* HAL_RTC_MODULE_ENABLED */
1991 /**
1992   * @}
1993   */
1994 
1995 /**
1996   * @}
1997   */
1998 
1999 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2000