1 /**
2 ******************************************************************************
3 * @file stm32wb0x_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 and de-initialization functions
9 * + Calendar (Time and Date) configuration functions
10 * + Alarm (Alarm A) configuration functions
11 * + Peripheral Control functions
12 * + Peripheral State functions
13 *
14 ******************************************************************************
15 * @attention
16 *
17 * Copyright (c) 2024 STMicroelectronics.
18 * All rights reserved.
19 *
20 * This software is licensed under terms that can be found in the LICENSE file
21 * in the root directory of this software component.
22 * If no LICENSE file comes with this software, it is provided AS-IS.
23 *
24 ******************************************************************************
25 @verbatim
26 ==============================================================================
27 ##### RTC and Backup Domain Operating Condition #####
28 ==============================================================================
29 [..] The real-time clock (RTC) and the RTC backup registers can be powered
30 from the VBAT voltage when the main VDD supply is powered off.
31 To retain the content of the RTC backup registers and supply the RTC when
32 VDD is turned off, VBAT pin can be connected to an optional standby
33 voltage supplied by a battery or by another source.
34
35 [..] To allow the RTC operating even when the main digital supply (VDD) is turned
36 off, the VBAT pin powers the following blocks:
37 (#) The RTC
38 (#) The LSE oscillator
39
40 [..] When the backup domain is supplied by VDD (analog switch connected to VDD),
41 the following pins are available:
42 (#) PC14 and PC15 can be used as either GPIO or LSE pins
43 (#) PC13 can be used as a GPIO or as the RTC_AF1 pin
44
45 [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
46 because VDD is not present), the following pins are available:
47 (#) PC14 and PC15 can be used as LSE pins only
48 (#) PC13 can be used as the RTC_AF1 pin
49
50 ##### Backup Domain Reset #####
51 ==================================================================
52 [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
53 to their reset values.
54 [..] A backup domain reset is generated when one of the following events occurs:
55 (#) Software reset, triggered by setting the BDRST bit in the
56 RCC Backup domain control register (RCC_BDCR).
57 (#) VDD or VBAT power on, if both supplies have previously been powered off.
58
59 ##### Backup Domain Access #####
60 ==================================================================
61 [..] After reset, the backup domain (RTC registers and RTC backup data registers)
62 is protected against possible unwanted write accesses.
63 [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
64 (+) Enable the Power Controller (PWR) APB1 interface clock using the
65 __HAL_RCC_PWR_CLK_ENABLE() macro.
66 (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
67 (+) Select the RTC clock source using the __HAL_RCC_RTC_CONFIG() macro.
68 (+) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() macro.
69
70 ==============================================================================
71 ##### How to use this driver #####
72 ==============================================================================
73 [..]
74 (+) Enable the RTC domain access (see description in the section above).
75 (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour
76 format using the HAL_RTC_Init() function.
77
78 *** Time and Date configuration ***
79 ===================================
80 [..]
81 (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
82 and HAL_RTC_SetDate() functions.
83 (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate()
84 functions.
85 (+) To manage the RTC summer or winter time change, use the following
86 functions:
87 (++) HAL_RTC_DST_Add1Hour() or HAL_RTC_DST_Sub1Hour to add or subtract
88 1 hour from the calendar time.
89 (++) HAL_RTC_DST_SetStoreOperation() or HAL_RTC_DST_ClearStoreOperation
90 to memorize whether the time change has been performed or not.
91
92 *** Alarm configuration ***
93 ===========================
94 [..]
95 (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
96 You can also configure the RTC Alarm with interrupt mode using the
97 HAL_RTC_SetAlarm_IT() function.
98 (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
99
100 ##### RTC and low power modes #####
101 ==================================================================
102 [..] The MCU can be woken up from a low power mode by an RTC alternate
103 function.
104 [..] The RTC alternate functions are the RTC alarm (Alarm A),
105 and RTC wakeup.
106 These RTC alternate functions can wake up the system from the Stop and
107 Standby low power modes.
108 [..] The system can also wake up from low power modes without depending
109 on an external interrupt (Auto-wakeup mode), by using the RTC alarm
110 or the RTC wakeup events.
111 [..] The RTC provides a programmable time base for waking up from the
112 Stop or Standby mode at regular intervals.
113 Wakeup from STOP and STANDBY modes is possible only when the RTC clock
114 source is LSE or LSI.
115
116 *** Callback registration ***
117 =============================================
118 [..]
119 When the compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or
120 not defined, the callback registration feature is not available and all
121 callbacks are set to the corresponding weak functions.
122 This is the recommended configuration in order to optimize memory/code
123 consumption footprint/performances.
124 [..]
125 The compilation define USE_HAL_RTC_REGISTER_CALLBACKS when set to 1
126 allows the user to configure dynamically the driver callbacks.
127 Use Function HAL_RTC_RegisterCallback() to register an interrupt callback.
128 [..]
129 Function HAL_RTC_RegisterCallback() allows to register following callbacks:
130 (+) AlarmAEventCallback : RTC Alarm A Event callback.
131 (+) WakeUpTimerEventCallback : RTC WakeUpTimer Event callback.
132 (+) MspInitCallback : RTC MspInit callback.
133 (+) MspDeInitCallback : RTC MspDeInit callback.
134 [..]
135 This function takes as parameters the HAL peripheral handle, the Callback ID
136 and a pointer to the user callback function.
137 [..]
138 Use function HAL_RTC_UnRegisterCallback() to reset a callback to the default
139 weak function.
140 HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
141 and the Callback ID.
142 This function allows to reset following callbacks:
143 (+) AlarmAEventCallback : RTC Alarm A Event callback.
144 (+) WakeUpTimerEventCallback : RTC WakeUpTimer Event callback.
145 (+) MspInitCallback : RTC MspInit callback.
146 (+) MspDeInitCallback : RTC MspDeInit callback.
147 [..]
148 By default, after the HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET,
149 all callbacks are set to the corresponding weak functions:
150 examples AlarmAEventCallback(), TimeStampEventCallback().
151 Exception done for MspInit() and MspDeInit() callbacks that are reset to the
152 legacy weak function in the HAL_RTC_Init()/HAL_RTC_DeInit() only when these
153 callbacks are null (not registered beforehand).
154 If not, MspInit() or MspDeInit() are not null, HAL_RTC_Init()/HAL_RTC_DeInit()
155 keep and use the user MspInit()/MspDeInit() callbacks (registered beforehand).
156 [..]
157 Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only.
158 Exception done for MspInit() and MspDeInit() that can be registered/unregistered
159 in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state.
160 Thus registered (user) MspInit()/MspDeInit() callbacks can be used during the
161 Init/DeInit.
162 In that case first register the MspInit()/MspDeInit() user callbacks using
163 HAL_RTC_RegisterCallback() before calling HAL_RTC_DeInit() or HAL_RTC_Init()
164 functions.
165
166 @endverbatim
167 ******************************************************************************
168 */
169
170 /* Includes ------------------------------------------------------------------*/
171 #include "stm32wb0x_hal.h"
172
173 /** @addtogroup STM32WB0x_HAL_Driver
174 * @{
175 */
176
177 /** @defgroup RTC RTC
178 * @brief RTC HAL module driver
179 * @{
180 */
181
182 #ifdef HAL_RTC_MODULE_ENABLED
183
184 /* Private typedef -----------------------------------------------------------*/
185 /* Private define ------------------------------------------------------------*/
186 /* Private macro -------------------------------------------------------------*/
187 /* Private variables ---------------------------------------------------------*/
188 /* Private function prototypes -----------------------------------------------*/
189 /* Exported functions --------------------------------------------------------*/
190
191 /** @defgroup RTC_Exported_Functions RTC Exported Functions
192 * @{
193 */
194
195 /** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
196 * @brief Initialization and Configuration functions
197 *
198 @verbatim
199 ===============================================================================
200 ##### Initialization and de-initialization functions #####
201 ===============================================================================
202 [..] This section provides functions allowing to initialize and configure the
203 RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable
204 RTC registers Write protection, enter and exit the RTC initialization mode,
205 RTC registers synchronization check and reference clock detection enable.
206 (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base.
207 It is split into 2 programmable prescalers to minimize power consumption.
208 (++) A 7-bit asynchronous prescaler and a 15-bit synchronous prescaler.
209 (++) When both prescalers are used, it is recommended to configure the
210 asynchronous prescaler to a high value to minimize power consumption.
211 (#) All RTC registers are Write protected. Writing to the RTC registers
212 is enabled by writing a key into the Write Protection register, RTC_WPR.
213 (#) To configure the RTC Calendar, user application should enter
214 initialization mode. In this mode, the calendar counter is stopped
215 and its value can be updated. When the initialization sequence is
216 complete, the calendar restarts counting after 4 RTCCLK cycles.
217 (#) To read the calendar through the shadow registers after Calendar
218 initialization, calendar update or after wakeup from low power modes
219 the software must first clear the RSF flag. The software must then
220 wait until it is set again before reading the calendar, which means
221 that the calendar registers have been correctly copied into the
222 RTC_TR and RTC_DR shadow registers. The HAL_RTC_WaitForSynchro() function
223 implements the above software sequence (RSF clear and RSF check).
224
225 @endverbatim
226 * @{
227 */
228
229 /**
230 * @brief Initializes the RTC peripheral
231 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
232 * the configuration information for RTC.
233 * @retval HAL status
234 */
HAL_RTC_Init(RTC_HandleTypeDef * hrtc)235 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
236 {
237 HAL_StatusTypeDef status = HAL_ERROR;
238
239 /* Check RTC handler validity */
240 if (hrtc == NULL)
241 {
242 return HAL_ERROR;
243 }
244
245 /* Check the parameters */
246 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
247 assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));
248 assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
249 assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));
250 assert_param(IS_RTC_OUTPUT(hrtc->Init.OutPut));
251 assert_param(IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));
252
253 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
254 if (hrtc->State == HAL_RTC_STATE_RESET)
255 {
256 /* Allocate lock resource and initialize it */
257 hrtc->Lock = HAL_UNLOCKED;
258
259 hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */
260 hrtc->WakeUpTimerEventCallback = HAL_RTCEx_WakeUpTimerEventCallback; /* Legacy weak WakeUpTimerEventCallback */
261
262 if (hrtc->MspInitCallback == NULL)
263 {
264 hrtc->MspInitCallback = HAL_RTC_MspInit;
265 }
266 /* Init the low level hardware */
267 hrtc->MspInitCallback(hrtc);
268
269 if (hrtc->MspDeInitCallback == NULL)
270 {
271 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
272 }
273 }
274 #else /* USE_HAL_RTC_REGISTER_CALLBACKS */
275 if (hrtc->State == HAL_RTC_STATE_RESET)
276 {
277 /* Allocate lock resource and initialize it */
278 hrtc->Lock = HAL_UNLOCKED;
279
280 /* Initialize RTC MSP */
281 HAL_RTC_MspInit(hrtc);
282 }
283 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
284
285 /* Set RTC state */
286 hrtc->State = HAL_RTC_STATE_BUSY;
287
288 /* Check whether the calendar needs to be initialized */
289 if (__HAL_RTC_IS_CALENDAR_INITIALIZED(hrtc) == 0U)
290 {
291 /* Disable the write protection for RTC registers */
292 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
293
294 /* Enter Initialization mode */
295 status = RTC_EnterInitMode(hrtc);
296
297 if (status == HAL_OK)
298 {
299 /* Clear RTC_CR FMT, OSEL and POL Bits */
300 hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
301 /* Set RTC_CR register */
302 hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);
303
304 /* Configure the RTC PRER */
305 hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);
306 hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << RTC_PRER_PREDIV_A_Pos);
307
308 /* Exit Initialization mode */
309 status = RTC_ExitInitMode(hrtc);
310 }
311
312 /* Enable the write protection for RTC registers */
313 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
314 }
315 else
316 {
317 /* The calendar is already initialized */
318 status = HAL_OK;
319 }
320
321 if (status == HAL_OK)
322 {
323 hrtc->State = HAL_RTC_STATE_READY;
324 }
325
326 return status;
327 }
328
329 /**
330 * @brief DeInitializes the RTC peripheral
331 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
332 * the configuration information for RTC.
333 * @note This function does not reset the RTC Backup Data registers.
334 * @retval HAL status
335 */
HAL_RTC_DeInit(RTC_HandleTypeDef * hrtc)336 HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
337 {
338 HAL_StatusTypeDef status = HAL_ERROR;
339
340 /* Check the parameters */
341 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
342
343 /* Set RTC state */
344 hrtc->State = HAL_RTC_STATE_BUSY;
345
346 /* Disable the write protection for RTC registers */
347 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
348
349 /* Enter Initialization mode */
350 status = RTC_EnterInitMode(hrtc);
351
352 if (status == HAL_OK)
353 {
354 /* Reset RTC registers */
355 hrtc->Instance->TR = 0x00000000U;
356 hrtc->Instance->DR = (RTC_DR_WDU_0 | RTC_DR_MU_0 | RTC_DR_DU_0);
357 hrtc->Instance->CR &= 0x00000000U;
358 hrtc->Instance->WUTR = RTC_WUTR_WUT;
359 hrtc->Instance->PRER = (uint32_t)(RTC_PRER_PREDIV_A | 0x000000FFU);
360 hrtc->Instance->ALRMAR = 0x00000000U;
361 hrtc->Instance->CALR = 0x00000000U;
362 hrtc->Instance->SHIFTR = 0x00000000U;
363 hrtc->Instance->ALRMASSR = 0x00000000U;
364
365 /* Exit Initialization mode */
366 status = RTC_ExitInitMode(hrtc);
367 }
368
369 /* Enable the write protection for RTC registers */
370 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
371
372 if (status == HAL_OK)
373 {
374 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
375 if (hrtc->MspDeInitCallback == NULL)
376 {
377 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
378 }
379
380 /* DeInit the low level hardware: CLOCK, NVIC.*/
381 hrtc->MspDeInitCallback(hrtc);
382 #else /* USE_HAL_RTC_REGISTER_CALLBACKS */
383 /* De-Initialize RTC MSP */
384 HAL_RTC_MspDeInit(hrtc);
385 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
386
387 hrtc->State = HAL_RTC_STATE_RESET;
388 }
389
390 /* Release Lock */
391 __HAL_UNLOCK(hrtc);
392
393 return status;
394 }
395
396 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
397 /**
398 * @brief Registers a User RTC Callback
399 * To be used instead of the weak predefined callback
400 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
401 * the configuration information for RTC.
402 * @param CallbackID ID of the callback to be registered
403 * This parameter can be one of the following values:
404 * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID
405 * @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID Wakeup Timer Event Callback ID
406 * @arg @ref HAL_RTC_MSPINIT_CB_ID MSP Init callback ID
407 * @arg @ref HAL_RTC_MSPDEINIT_CB_ID MSP DeInit callback ID
408 * @param pCallback pointer to the Callback function
409 * @retval HAL status
410 */
HAL_RTC_RegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID,pRTC_CallbackTypeDef pCallback)411 HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, pRTC_CallbackTypeDef pCallback)
412 {
413 HAL_StatusTypeDef status = HAL_OK;
414
415 if (pCallback == NULL)
416 {
417 return HAL_ERROR;
418 }
419
420 /* Process locked */
421 __HAL_LOCK(hrtc);
422
423 if (HAL_RTC_STATE_READY == hrtc->State)
424 {
425 switch (CallbackID)
426 {
427 case HAL_RTC_ALARM_A_EVENT_CB_ID :
428 hrtc->AlarmAEventCallback = pCallback;
429 break;
430
431 case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID :
432 hrtc->WakeUpTimerEventCallback = pCallback;
433 break;
434
435 case HAL_RTC_MSPINIT_CB_ID :
436 hrtc->MspInitCallback = pCallback;
437 break;
438
439 case HAL_RTC_MSPDEINIT_CB_ID :
440 hrtc->MspDeInitCallback = pCallback;
441 break;
442
443 default :
444 /* Return error status */
445 status = HAL_ERROR;
446 break;
447 }
448 }
449 else if (HAL_RTC_STATE_RESET == hrtc->State)
450 {
451 switch (CallbackID)
452 {
453 case HAL_RTC_MSPINIT_CB_ID :
454 hrtc->MspInitCallback = pCallback;
455 break;
456
457 case HAL_RTC_MSPDEINIT_CB_ID :
458 hrtc->MspDeInitCallback = pCallback;
459 break;
460
461 default :
462 /* Return error status */
463 status = HAL_ERROR;
464 break;
465 }
466 }
467 else
468 {
469 /* Return error status */
470 status = HAL_ERROR;
471 }
472
473 /* Release Lock */
474 __HAL_UNLOCK(hrtc);
475
476 return status;
477 }
478
479 /**
480 * @brief Unregisters an RTC Callback
481 * RTC callback is redirected to the weak predefined callback
482 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
483 * the configuration information for RTC.
484 * @param CallbackID ID of the callback to be unregistered
485 * This parameter can be one of the following values:
486 * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID
487 * @arg @ref HAL_RTC_WAKEUPTIMER_EVENT_CB_ID Wakeup Timer Event Callback ID
488 * @arg @ref HAL_RTC_MSPINIT_CB_ID MSP Init callback ID
489 * @arg @ref HAL_RTC_MSPDEINIT_CB_ID MSP DeInit callback ID
490 * @retval HAL status
491 */
HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID)492 HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID)
493 {
494 HAL_StatusTypeDef status = HAL_OK;
495
496 /* Process locked */
497 __HAL_LOCK(hrtc);
498
499 if (HAL_RTC_STATE_READY == hrtc->State)
500 {
501 switch (CallbackID)
502 {
503 case HAL_RTC_ALARM_A_EVENT_CB_ID :
504 hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */
505 break;
506
507 case HAL_RTC_WAKEUPTIMER_EVENT_CB_ID :
508 hrtc->WakeUpTimerEventCallback = HAL_RTCEx_WakeUpTimerEventCallback; /* Legacy weak WakeUpTimerEventCallback */
509 break;
510
511 case HAL_RTC_MSPINIT_CB_ID :
512 hrtc->MspInitCallback = HAL_RTC_MspInit;
513 break;
514
515 case HAL_RTC_MSPDEINIT_CB_ID :
516 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
517 break;
518
519 default :
520 /* Return error status */
521 status = HAL_ERROR;
522 break;
523 }
524 }
525 else if (HAL_RTC_STATE_RESET == hrtc->State)
526 {
527 switch (CallbackID)
528 {
529 case HAL_RTC_MSPINIT_CB_ID :
530 hrtc->MspInitCallback = HAL_RTC_MspInit;
531 break;
532
533 case HAL_RTC_MSPDEINIT_CB_ID :
534 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
535 break;
536
537 default :
538 /* Return error status */
539 status = HAL_ERROR;
540 break;
541 }
542 }
543 else
544 {
545 /* Return error status */
546 status = HAL_ERROR;
547 }
548
549 /* Release Lock */
550 __HAL_UNLOCK(hrtc);
551
552 return status;
553 }
554 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
555
556 /**
557 * @brief Initializes the RTC MSP.
558 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
559 * the configuration information for RTC.
560 * @retval None
561 */
HAL_RTC_MspInit(RTC_HandleTypeDef * hrtc)562 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
563 {
564 /* Prevent unused argument(s) compilation warning */
565 UNUSED(hrtc);
566
567 /* NOTE: This function should not be modified, when the callback is needed,
568 the HAL_RTC_MspInit could be implemented in the user file
569 */
570 }
571
572 /**
573 * @brief DeInitializes the RTC MSP.
574 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
575 * the configuration information for RTC.
576 * @retval None
577 */
HAL_RTC_MspDeInit(RTC_HandleTypeDef * hrtc)578 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
579 {
580 /* Prevent unused argument(s) compilation warning */
581 UNUSED(hrtc);
582
583 /* NOTE: This function should not be modified, when the callback is needed,
584 the HAL_RTC_MspDeInit could be implemented in the user file
585 */
586 }
587
588 /**
589 * @}
590 */
591
592 /** @defgroup RTC_Exported_Functions_Group2 RTC Time and Date functions
593 * @brief RTC Time and Date functions
594 *
595 @verbatim
596 ===============================================================================
597 ##### RTC Time and Date functions #####
598 ===============================================================================
599
600 [..] This section provides functions allowing to configure Time and Date features
601
602 @endverbatim
603 * @{
604 */
605
606 /**
607 * @brief Sets RTC current time.
608 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
609 * the configuration information for RTC.
610 * @param sTime Pointer to Time structure
611 * @note DayLightSaving and StoreOperation interfaces are deprecated.
612 * To manage Daylight Saving Time, please use HAL_RTC_DST_xxx functions.
613 * @param Format Specifies the format of the entered parameters.
614 * This parameter can be one of the following values:
615 * @arg RTC_FORMAT_BIN: Binary data format
616 * @arg RTC_FORMAT_BCD: BCD data format
617 * @retval HAL status
618 */
HAL_RTC_SetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)619 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
620 {
621 uint32_t tmpreg = 0U;
622 HAL_StatusTypeDef status;
623
624 /* Check the parameters */
625 assert_param(IS_RTC_FORMAT(Format));
626 assert_param(IS_RTC_DAYLIGHT_SAVING(sTime->DayLightSaving));
627 assert_param(IS_RTC_STORE_OPERATION(sTime->StoreOperation));
628
629 /* Process Locked */
630 __HAL_LOCK(hrtc);
631
632 hrtc->State = HAL_RTC_STATE_BUSY;
633
634 if (Format == RTC_FORMAT_BIN)
635 {
636 if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
637 {
638 assert_param(IS_RTC_HOUR12(sTime->Hours));
639 assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
640 }
641 else
642 {
643 sTime->TimeFormat = 0x00U;
644 assert_param(IS_RTC_HOUR24(sTime->Hours));
645 }
646 assert_param(IS_RTC_MINUTES(sTime->Minutes));
647 assert_param(IS_RTC_SECONDS(sTime->Seconds));
648
649 tmpreg = (uint32_t)(( (uint32_t)RTC_ByteToBcd2(sTime->Hours) << RTC_TR_HU_Pos) | \
650 ( (uint32_t)RTC_ByteToBcd2(sTime->Minutes) << RTC_TR_MNU_Pos) | \
651 ( (uint32_t)RTC_ByteToBcd2(sTime->Seconds)) | \
652 (((uint32_t)sTime->TimeFormat) << RTC_TR_PM_Pos));
653 }
654 else
655 {
656 if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
657 {
658 assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sTime->Hours)));
659 assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
660 }
661 else
662 {
663 sTime->TimeFormat = 0x00U;
664 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
665 }
666 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
667 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
668 tmpreg = (((uint32_t)(sTime->Hours) << RTC_TR_HU_Pos) | \
669 ((uint32_t)(sTime->Minutes) << RTC_TR_MNU_Pos) | \
670 ((uint32_t) sTime->Seconds) | \
671 ((uint32_t)(sTime->TimeFormat) << RTC_TR_PM_Pos));
672 }
673
674 /* Disable the write protection for RTC registers */
675 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
676
677 /* Enter Initialization mode */
678 status = RTC_EnterInitMode(hrtc);
679
680 if (status == HAL_OK)
681 {
682 /* Set the RTC_TR register */
683 hrtc->Instance->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
684
685 /* Clear the bits to be configured (Deprecated. Use HAL_RTC_DST_xxx functions instead) */
686 hrtc->Instance->CR &= (uint32_t)~RTC_CR_BKP;
687
688 /* Configure the RTC_CR register (Deprecated. Use HAL_RTC_DST_xxx functions instead) */
689 hrtc->Instance->CR |= (uint32_t)(sTime->DayLightSaving | sTime->StoreOperation);
690
691 /* Exit Initialization mode */
692 status = RTC_ExitInitMode(hrtc);
693 }
694
695 if (status == HAL_OK)
696 {
697 hrtc->State = HAL_RTC_STATE_READY;
698 }
699
700 /* Enable the write protection for RTC registers */
701 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
702
703 /* Process Unlocked */
704 __HAL_UNLOCK(hrtc);
705
706 return status;
707 }
708
709 /**
710 * @brief Gets RTC current time.
711 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
712 * the configuration information for RTC.
713 * @param sTime Pointer to Time structure
714 * @param Format Specifies the format of the entered parameters.
715 * This parameter can be one of the following values:
716 * @arg RTC_FORMAT_BIN: Binary data format
717 * @arg RTC_FORMAT_BCD: BCD data format
718 * @note You can use SubSeconds and SecondFraction (sTime structure fields
719 * returned) to convert SubSeconds value in second fraction ratio with
720 * time unit following generic formula:
721 * Second fraction ratio * time_unit =
722 * [(SecondFraction - SubSeconds) / (SecondFraction + 1)] * time_unit
723 * This conversion can be performed only if no shift operation is pending
724 * (ie. SHFP=0) when PREDIV_S >= SS
725 * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the
726 * values in the higher-order calendar shadow registers to ensure
727 * consistency between the time and date values.
728 * Reading RTC current time locks the values in calendar shadow registers
729 * until current date is read to ensure consistency between the time and
730 * date values.
731 * @retval HAL status
732 */
HAL_RTC_GetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)733 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
734 {
735 uint32_t tmpreg = 0U;
736
737 /* Check the parameters */
738 assert_param(IS_RTC_FORMAT(Format));
739
740 /* Get subseconds value from the corresponding register */
741 sTime->SubSeconds = (uint32_t)(hrtc->Instance->SSR);
742
743 /* Get SecondFraction structure field from the corresponding register field*/
744 sTime->SecondFraction = (uint32_t)(hrtc->Instance->PRER & RTC_PRER_PREDIV_S);
745
746 /* Get the TR register */
747 tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);
748
749 /* Fill the structure fields with the read parameters */
750 sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> RTC_TR_HU_Pos);
751 sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >> RTC_TR_MNU_Pos);
752 sTime->Seconds = (uint8_t)( tmpreg & (RTC_TR_ST | RTC_TR_SU));
753 sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> RTC_TR_PM_Pos);
754
755 /* Check the input parameters format */
756 if (Format == RTC_FORMAT_BIN)
757 {
758 /* Convert the time structure parameters to Binary format */
759 sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours);
760 sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes);
761 sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds);
762 }
763
764 return HAL_OK;
765 }
766
767 /**
768 * @brief Sets RTC current date.
769 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
770 * the configuration information for RTC.
771 * @param sDate Pointer to date structure
772 * @param Format specifies the format of the entered parameters.
773 * This parameter can be one of the following values:
774 * @arg RTC_FORMAT_BIN: Binary data format
775 * @arg RTC_FORMAT_BCD: BCD data format
776 * @retval HAL status
777 */
HAL_RTC_SetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)778 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
779 {
780 uint32_t datetmpreg = 0U;
781 HAL_StatusTypeDef status;
782
783 /* Check the parameters */
784 assert_param(IS_RTC_FORMAT(Format));
785
786 /* Process Locked */
787 __HAL_LOCK(hrtc);
788
789 hrtc->State = HAL_RTC_STATE_BUSY;
790
791 if ((Format == RTC_FORMAT_BIN) && ((sDate->Month & 0x10U) == 0x10U))
792 {
793 sDate->Month = (uint8_t)((sDate->Month & (uint8_t)~(0x10U)) + (uint8_t)0x0AU);
794 }
795
796 assert_param(IS_RTC_WEEKDAY(sDate->WeekDay));
797
798 if (Format == RTC_FORMAT_BIN)
799 {
800 assert_param(IS_RTC_YEAR(sDate->Year));
801 assert_param(IS_RTC_MONTH(sDate->Month));
802 assert_param(IS_RTC_DATE(sDate->Date));
803
804 datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year) << RTC_DR_YU_Pos) | \
805 ((uint32_t)RTC_ByteToBcd2(sDate->Month) << RTC_DR_MU_Pos) | \
806 ((uint32_t)RTC_ByteToBcd2(sDate->Date)) | \
807 ((uint32_t)sDate->WeekDay << RTC_DR_WDU_Pos));
808 }
809 else
810 {
811 assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
812 assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
813 assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
814
815 datetmpreg = ((((uint32_t)sDate->Year) << RTC_DR_YU_Pos) | \
816 (((uint32_t)sDate->Month) << RTC_DR_MU_Pos) | \
817 ((uint32_t) sDate->Date) | \
818 (((uint32_t)sDate->WeekDay) << RTC_DR_WDU_Pos));
819 }
820
821 /* Disable the write protection for RTC registers */
822 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
823
824 /* Enter Initialization mode */
825 status = RTC_EnterInitMode(hrtc);
826
827 if (status == HAL_OK)
828 {
829 /* Set the RTC_DR register */
830 hrtc->Instance->DR = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK);
831
832 /* Exit Initialization mode */
833 status = RTC_ExitInitMode(hrtc);
834 }
835
836 if (status == HAL_OK)
837 {
838 hrtc->State = HAL_RTC_STATE_READY;
839 }
840
841 /* Enable the write protection for RTC registers */
842 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
843
844 /* Process Unlocked */
845 __HAL_UNLOCK(hrtc);
846
847 return status;
848 }
849
850 /**
851 * @brief Gets RTC current date.
852 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
853 * the configuration information for RTC.
854 * @param sDate Pointer to Date structure
855 * @param Format Specifies the format of the entered parameters.
856 * This parameter can be one of the following values:
857 * @arg RTC_FORMAT_BIN: Binary data format
858 * @arg RTC_FORMAT_BCD: BCD data format
859 * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the
860 * values in the higher-order calendar shadow registers to ensure
861 * consistency between the time and date values.
862 * Reading RTC current time locks the values in calendar shadow registers
863 * until current date is read to ensure consistency between the time and
864 * date values.
865 * @retval HAL status
866 */
HAL_RTC_GetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)867 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
868 {
869 uint32_t datetmpreg = 0U;
870
871 /* Check the parameters */
872 assert_param(IS_RTC_FORMAT(Format));
873
874 /* Get the DR register */
875 datetmpreg = (uint32_t)(hrtc->Instance->DR & RTC_DR_RESERVED_MASK);
876
877 /* Fill the structure fields with the read parameters */
878 sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> RTC_DR_YU_Pos);
879 sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> RTC_DR_MU_Pos);
880 sDate->Date = (uint8_t) (datetmpreg & (RTC_DR_DT | RTC_DR_DU));
881 sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> RTC_DR_WDU_Pos);
882
883 /* Check the input parameters format */
884 if (Format == RTC_FORMAT_BIN)
885 {
886 /* Convert the date structure parameters to Binary format */
887 sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year);
888 sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month);
889 sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date);
890 }
891 return HAL_OK;
892 }
893
894 /**
895 * @}
896 */
897
898 /** @defgroup RTC_Exported_Functions_Group3 RTC Alarm functions
899 * @brief RTC Alarm functions
900 *
901 @verbatim
902 ===============================================================================
903 ##### RTC Alarm functions #####
904 ===============================================================================
905
906 [..] This section provides functions allowing to configure Alarm feature
907
908 @endverbatim
909 * @{
910 */
911 /**
912 * @brief Sets the specified RTC Alarm.
913 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
914 * the configuration information for RTC.
915 * @param sAlarm Pointer to Alarm structure
916 * @param Format Specifies the format of the entered parameters.
917 * This parameter can be one of the following values:
918 * @arg RTC_FORMAT_BIN: Binary data format
919 * @arg RTC_FORMAT_BCD: BCD data format
920 * @note The Alarm register can only be written when the corresponding Alarm
921 * is disabled (Use the HAL_RTC_DeactivateAlarm()).
922 * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
923 * @retval HAL status
924 */
HAL_RTC_SetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)925 HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
926 {
927 uint32_t tickstart = 0U;
928 uint32_t tmpreg = 0U;
929 uint32_t subsecondtmpreg = 0U;
930
931 /* Check the parameters */
932 assert_param(IS_RTC_FORMAT(Format));
933 assert_param(IS_RTC_ALARM(sAlarm->Alarm));
934 assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask));
935 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel));
936 assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds));
937 assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask));
938
939 /* Process Locked */
940 __HAL_LOCK(hrtc);
941
942 /* Change RTC state to BUSY */
943 hrtc->State = HAL_RTC_STATE_BUSY;
944
945 /* Check the data format (binary or BCD) and store the Alarm time and date
946 configuration accordingly */
947 if (Format == RTC_FORMAT_BIN)
948 {
949 if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
950 {
951 assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours));
952 assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
953 }
954 else
955 {
956 sAlarm->AlarmTime.TimeFormat = 0x00U;
957 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
958 }
959 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
960 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
961
962 if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
963 {
964 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay));
965 }
966 else
967 {
968 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay));
969 }
970
971 tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
972 ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
973 ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds)) | \
974 ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_TR_PM_Pos) | \
975 ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \
976 ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \
977 ((uint32_t)sAlarm->AlarmMask));
978 }
979 else
980 {
981 if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
982 {
983 assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
984 assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
985 }
986 else
987 {
988 sAlarm->AlarmTime.TimeFormat = 0x00U;
989 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
990 }
991
992 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
993 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
994
995 if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
996 {
997 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
998 }
999 else
1000 {
1001 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1002 }
1003
1004 tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1005 ((uint32_t)(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1006 ((uint32_t) sAlarm->AlarmTime.Seconds) | \
1007 ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_TR_PM_Pos) | \
1008 ((uint32_t)(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \
1009 ((uint32_t) sAlarm->AlarmDateWeekDaySel) | \
1010 ((uint32_t) sAlarm->AlarmMask));
1011 }
1012
1013 /* Store the Alarm subseconds configuration */
1014 subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | \
1015 (uint32_t)(sAlarm->AlarmSubSecondMask));
1016
1017 /* Disable the write protection for RTC registers */
1018 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1019
1020 /* Disable the Alarm A */
1021 __HAL_RTC_ALARMA_DISABLE(hrtc);
1022
1023 /* In case interrupt mode is used, the interrupt source must be disabled */
1024 __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1025
1026 /* Clear the Alarm flag */
1027 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1028
1029 /* Get tick */
1030 tickstart = HAL_GetTick();
1031
1032 /* Wait till RTC ALRAWF flag is set and if timeout is reached exit */
1033 while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1034 {
1035 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1036 {
1037 /* Enable the write protection for RTC registers */
1038 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1039
1040 hrtc->State = HAL_RTC_STATE_TIMEOUT;
1041
1042 /* Process Unlocked */
1043 __HAL_UNLOCK(hrtc);
1044
1045 return HAL_TIMEOUT;
1046 }
1047 }
1048
1049 hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
1050 /* Configure the Alarm A Subseconds register */
1051 hrtc->Instance->ALRMASSR = subsecondtmpreg;
1052 /* Configure the Alarm state: Enable Alarm */
1053 __HAL_RTC_ALARMA_ENABLE(hrtc);
1054
1055 /* Enable the write protection for RTC registers */
1056 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1057
1058 /* Change RTC state back to READY */
1059 hrtc->State = HAL_RTC_STATE_READY;
1060
1061 /* Process Unlocked */
1062 __HAL_UNLOCK(hrtc);
1063
1064 return HAL_OK;
1065 }
1066
1067 /**
1068 * @brief Sets the specified RTC Alarm with Interrupt.
1069 * @note The application must ensure that the RTC interrupt line is configured via HAL SYSCFG services and the PWR_WAKEUP_PIN_RTC bit is set.
1070 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1071 * the configuration information for RTC.
1072 * @param sAlarm Pointer to Alarm structure
1073 * @param Format Specifies the format of the entered parameters.
1074 * This parameter can be one of the following values:
1075 * @arg RTC_FORMAT_BIN: Binary data format
1076 * @arg RTC_FORMAT_BCD: BCD data format
1077 * @note The Alarm register can only be written when the corresponding Alarm
1078 * is disabled (Use the HAL_RTC_DeactivateAlarm()).
1079 * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
1080 * @retval HAL status
1081 */
HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1082 HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1083 {
1084 __IO uint32_t count = RTC_TIMEOUT_VALUE * (SystemCoreClock / 32U / 1000U);
1085 uint32_t tmpreg = 0U;
1086 uint32_t subsecondtmpreg = 0U;
1087
1088 /* Check the parameters */
1089 assert_param(IS_RTC_FORMAT(Format));
1090 assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1091 assert_param(IS_RTC_ALARM_MASK(sAlarm->AlarmMask));
1092 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_SEL(sAlarm->AlarmDateWeekDaySel));
1093 assert_param(IS_RTC_ALARM_SUB_SECOND_VALUE(sAlarm->AlarmTime.SubSeconds));
1094 assert_param(IS_RTC_ALARM_SUB_SECOND_MASK(sAlarm->AlarmSubSecondMask));
1095
1096 /* Process Locked */
1097 __HAL_LOCK(hrtc);
1098
1099 /* Change RTC state to BUSY */
1100 hrtc->State = HAL_RTC_STATE_BUSY;
1101
1102 /* Check the data format (binary or BCD) and store the Alarm time and date
1103 configuration accordingly */
1104 if (Format == RTC_FORMAT_BIN)
1105 {
1106 if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1107 {
1108 assert_param(IS_RTC_HOUR12(sAlarm->AlarmTime.Hours));
1109 assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1110 }
1111 else
1112 {
1113 sAlarm->AlarmTime.TimeFormat = 0x00U;
1114 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1115 }
1116 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1117 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1118
1119 if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1120 {
1121 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(sAlarm->AlarmDateWeekDay));
1122 }
1123 else
1124 {
1125 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(sAlarm->AlarmDateWeekDay));
1126 }
1127
1128 tmpreg = (((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1129 ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1130 ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds)) | \
1131 ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_TR_PM_Pos) | \
1132 ((uint32_t)RTC_ByteToBcd2(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \
1133 ((uint32_t)sAlarm->AlarmDateWeekDaySel) | \
1134 ((uint32_t)sAlarm->AlarmMask));
1135 }
1136 else
1137 {
1138 if ((hrtc->Instance->CR & RTC_CR_FMT) != 0U)
1139 {
1140 assert_param(IS_RTC_HOUR12(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1141 assert_param(IS_RTC_HOURFORMAT12(sAlarm->AlarmTime.TimeFormat));
1142 }
1143 else
1144 {
1145 sAlarm->AlarmTime.TimeFormat = 0x00U;
1146 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1147 }
1148
1149 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1150 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1151
1152 if (sAlarm->AlarmDateWeekDaySel == RTC_ALARMDATEWEEKDAYSEL_DATE)
1153 {
1154 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_DATE(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1155 }
1156 else
1157 {
1158 assert_param(IS_RTC_ALARM_DATE_WEEKDAY_WEEKDAY(RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay)));
1159 }
1160
1161 tmpreg = (((uint32_t)(sAlarm->AlarmTime.Hours) << RTC_ALRMAR_HU_Pos) | \
1162 ((uint32_t)(sAlarm->AlarmTime.Minutes) << RTC_ALRMAR_MNU_Pos) | \
1163 ((uint32_t) sAlarm->AlarmTime.Seconds) | \
1164 ((uint32_t)(sAlarm->AlarmTime.TimeFormat) << RTC_TR_PM_Pos) | \
1165 ((uint32_t)(sAlarm->AlarmDateWeekDay) << RTC_ALRMAR_DU_Pos) | \
1166 ((uint32_t) sAlarm->AlarmDateWeekDaySel) | \
1167 ((uint32_t) sAlarm->AlarmMask));
1168 }
1169
1170 /* Store the Alarm subseconds configuration */
1171 subsecondtmpreg = (uint32_t)((uint32_t)(sAlarm->AlarmTime.SubSeconds) | \
1172 (uint32_t)(sAlarm->AlarmSubSecondMask));
1173
1174 /* Disable the write protection for RTC registers */
1175 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1176
1177 /* Disable the Alarm A */
1178 __HAL_RTC_ALARMA_DISABLE(hrtc);
1179
1180 /* Clear the Alarm flag */
1181 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1182
1183 /* Wait till RTC ALRAWF flag is set and if timeout is reached exit */
1184 do
1185 {
1186 count = count - 1U;
1187 if (count == 0U)
1188 {
1189 /* Enable the write protection for RTC registers */
1190 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1191
1192 hrtc->State = HAL_RTC_STATE_TIMEOUT;
1193
1194 /* Process Unlocked */
1195 __HAL_UNLOCK(hrtc);
1196
1197 return HAL_TIMEOUT;
1198 }
1199 } while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U);
1200
1201 hrtc->Instance->ALRMAR = (uint32_t)tmpreg;
1202 /* Configure the Alarm A Subseconds register */
1203 hrtc->Instance->ALRMASSR = subsecondtmpreg;
1204 /* Configure the Alarm state: Enable Alarm */
1205 __HAL_RTC_ALARMA_ENABLE(hrtc);
1206 /* Configure the Alarm interrupt */
1207 __HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRA);
1208
1209 /* Enable the write protection for RTC registers */
1210 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1211
1212 /* Change RTC state back to READY */
1213 hrtc->State = HAL_RTC_STATE_READY;
1214
1215 /* Process Unlocked */
1216 __HAL_UNLOCK(hrtc);
1217
1218 return HAL_OK;
1219 }
1220
1221 /**
1222 * @brief Deactivates the specified RTC Alarm.
1223 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1224 * the configuration information for RTC.
1225 * @param Alarm Specifies the Alarm.
1226 * This parameter can be:
1227 * @arg RTC_ALARM_A: Alarm A
1228 * @retval HAL status
1229 */
HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef * hrtc,uint32_t Alarm)1230 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
1231 {
1232 uint32_t tickstart = 0U;
1233
1234 /* Check the parameters */
1235 assert_param(IS_RTC_ALARM(Alarm));
1236
1237 /* Process Locked */
1238 __HAL_LOCK(hrtc);
1239
1240 hrtc->State = HAL_RTC_STATE_BUSY;
1241
1242 /* Disable the write protection for RTC registers */
1243 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1244
1245 /* Disable Alarm A */
1246 __HAL_RTC_ALARMA_DISABLE(hrtc);
1247
1248 /* In case interrupt mode is used, the interrupt source must be disabled */
1249 __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1250
1251 /* Get tick */
1252 tickstart = HAL_GetTick();
1253
1254 /* Wait till RTC ALRxWF flag is set and if timeout is reached exit */
1255 while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == 0U)
1256 {
1257 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1258 {
1259 /* Enable the write protection for RTC registers */
1260 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1261
1262 hrtc->State = HAL_RTC_STATE_TIMEOUT;
1263
1264 /* Process Unlocked */
1265 __HAL_UNLOCK(hrtc);
1266
1267 return HAL_TIMEOUT;
1268 }
1269 }
1270
1271 /* Enable the write protection for RTC registers */
1272 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1273
1274 hrtc->State = HAL_RTC_STATE_READY;
1275
1276 /* Process Unlocked */
1277 __HAL_UNLOCK(hrtc);
1278
1279 return HAL_OK;
1280 }
1281
1282 /**
1283 * @brief Gets the RTC Alarm value and masks.
1284 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1285 * the configuration information for RTC.
1286 * @param sAlarm Pointer to Date structure
1287 * @param Alarm Specifies the Alarm.
1288 * This parameter can be:
1289 * @arg RTC_ALARM_A: Alarm A
1290 * @param Format Specifies the format of the entered parameters.
1291 * This parameter can be one of the following values:
1292 * @arg RTC_FORMAT_BIN: Binary data format
1293 * @arg RTC_FORMAT_BCD: BCD data format
1294 * @retval HAL status
1295 */
HAL_RTC_GetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Alarm,uint32_t Format)1296 HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
1297 {
1298 uint32_t tmpreg = 0U;
1299 uint32_t subsecondtmpreg = 0U;
1300
1301 /* Check the parameters */
1302 assert_param(IS_RTC_FORMAT(Format));
1303 assert_param(IS_RTC_ALARM(Alarm));
1304
1305 sAlarm->Alarm = RTC_ALARM_A;
1306
1307 tmpreg = (uint32_t)(hrtc->Instance->ALRMAR);
1308 subsecondtmpreg = (uint32_t)((hrtc->Instance->ALRMASSR) & RTC_ALRMASSR_SS);
1309
1310 /* Fill the structure with the read parameters */
1311 sAlarm->AlarmTime.Hours = (uint8_t) ((tmpreg & (RTC_ALRMAR_HT | RTC_ALRMAR_HU)) >> RTC_ALRMAR_HU_Pos);
1312 sAlarm->AlarmTime.Minutes = (uint8_t) ((tmpreg & (RTC_ALRMAR_MNT | RTC_ALRMAR_MNU)) >> RTC_ALRMAR_MNU_Pos);
1313 sAlarm->AlarmTime.Seconds = (uint8_t) ( tmpreg & (RTC_ALRMAR_ST | RTC_ALRMAR_SU));
1314 sAlarm->AlarmTime.TimeFormat = (uint8_t) ((tmpreg & RTC_ALRMAR_PM) >> RTC_TR_PM_Pos);
1315 sAlarm->AlarmTime.SubSeconds = (uint32_t) subsecondtmpreg;
1316 sAlarm->AlarmDateWeekDay = (uint8_t) ((tmpreg & (RTC_ALRMAR_DT | RTC_ALRMAR_DU)) >> RTC_ALRMAR_DU_Pos);
1317 sAlarm->AlarmDateWeekDaySel = (uint32_t) (tmpreg & RTC_ALRMAR_WDSEL);
1318 sAlarm->AlarmMask = (uint32_t) (tmpreg & RTC_ALARMMASK_ALL);
1319
1320 if (Format == RTC_FORMAT_BIN)
1321 {
1322 sAlarm->AlarmTime.Hours = RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours);
1323 sAlarm->AlarmTime.Minutes = RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes);
1324 sAlarm->AlarmTime.Seconds = RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds);
1325 sAlarm->AlarmDateWeekDay = RTC_Bcd2ToByte(sAlarm->AlarmDateWeekDay);
1326 }
1327
1328 return HAL_OK;
1329 }
1330
1331 /**
1332 * @brief Handles Alarm interrupt request.
1333 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1334 * the configuration information for RTC.
1335 * @retval None
1336 */
HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef * hrtc)1337 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc)
1338 {
1339 /* Get the Alarm A interrupt source enable status */
1340 if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA) != 0U)
1341 {
1342 /* Get the pending status of the Alarm A Interrupt */
1343 if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != 0U)
1344 {
1345 /* Clear the Alarm A interrupt pending bit */
1346 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1347
1348 /* Alarm A callback */
1349 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1350 hrtc->AlarmAEventCallback(hrtc);
1351 #else
1352 HAL_RTC_AlarmAEventCallback(hrtc);
1353 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
1354 }
1355 }
1356
1357 /* Change RTC state */
1358 hrtc->State = HAL_RTC_STATE_READY;
1359 }
1360
1361 /**
1362 * @brief Alarm A callback.
1363 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1364 * the configuration information for RTC.
1365 * @retval None
1366 */
HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef * hrtc)1367 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
1368 {
1369 /* Prevent unused argument(s) compilation warning */
1370 UNUSED(hrtc);
1371
1372 /* NOTE: This function should not be modified, when the callback is needed,
1373 the HAL_RTC_AlarmAEventCallback could be implemented in the user file
1374 */
1375 }
1376
1377 /**
1378 * @brief Handles Alarm A Polling request.
1379 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1380 * the configuration information for RTC.
1381 * @param Timeout Timeout duration
1382 * @retval HAL status
1383 */
HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)1384 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
1385 {
1386 uint32_t tickstart = 0U;
1387
1388 /* Get tick */
1389 tickstart = HAL_GetTick();
1390
1391 /* Wait till RTC ALRAF flag is set and if timeout is reached exit */
1392 while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == 0U)
1393 {
1394 if (Timeout != HAL_MAX_DELAY)
1395 {
1396 if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
1397 {
1398 hrtc->State = HAL_RTC_STATE_TIMEOUT;
1399 return HAL_TIMEOUT;
1400 }
1401 }
1402 }
1403
1404 /* Clear the Alarm flag */
1405 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1406
1407 /* Change RTC state */
1408 hrtc->State = HAL_RTC_STATE_READY;
1409
1410 return HAL_OK;
1411 }
1412
1413 /**
1414 * @}
1415 */
1416
1417 /** @defgroup RTC_Exported_Functions_Group4 Peripheral Control functions
1418 * @brief Peripheral Control functions
1419 *
1420 @verbatim
1421 ===============================================================================
1422 ##### Peripheral Control functions #####
1423 ===============================================================================
1424 [..]
1425 This subsection provides functions allowing to
1426 (+) Wait for RTC Time and Date Synchronization
1427 (+) Manage RTC Summer or Winter time change
1428
1429 @endverbatim
1430 * @{
1431 */
1432
1433 /**
1434 * @brief Waits until the RTC Time and Date registers (RTC_TR and RTC_DR) are
1435 * synchronized with RTC APB clock.
1436 * @note The RTC Resynchronization mode is write protected, use the
1437 * __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
1438 * @note To read the calendar through the shadow registers after Calendar
1439 * initialization, calendar update or after wakeup from low power modes
1440 * the software must first clear the RSF flag.
1441 * The software must then wait until it is set again before reading
1442 * the calendar, which means that the calendar registers have been
1443 * correctly copied into the RTC_TR and RTC_DR shadow registers.
1444 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1445 * the configuration information for RTC.
1446 * @retval HAL status
1447 */
HAL_RTC_WaitForSynchro(RTC_HandleTypeDef * hrtc)1448 HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc)
1449 {
1450 uint32_t tickstart = 0U;
1451
1452 /* Clear RSF flag, keep reserved bits at reset values (setting other flags has no effect) */
1453 hrtc->Instance->ISR = ((uint32_t)(RTC_RSF_MASK & RTC_ISR_RESERVED_MASK));
1454
1455 /* Get tick */
1456 tickstart = HAL_GetTick();
1457
1458 /* Wait the registers to be synchronised */
1459 while ((hrtc->Instance->ISR & RTC_ISR_RSF) == 0U)
1460 {
1461 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1462 {
1463 return HAL_TIMEOUT;
1464 }
1465 }
1466
1467 return HAL_OK;
1468 }
1469
1470 /**
1471 * @brief Daylight Saving Time, adds one hour to the calendar in one
1472 * single operation without going through the initialization procedure.
1473 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1474 * the configuration information for RTC.
1475 * @retval None
1476 */
HAL_RTC_DST_Add1Hour(RTC_HandleTypeDef * hrtc)1477 void HAL_RTC_DST_Add1Hour(RTC_HandleTypeDef *hrtc)
1478 {
1479 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1480 SET_BIT(hrtc->Instance->CR, RTC_CR_ADD1H);
1481 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1482 }
1483
1484 /**
1485 * @brief Daylight Saving Time, subtracts one hour from the calendar in one
1486 * single operation without going through the initialization procedure.
1487 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1488 * the configuration information for RTC.
1489 * @retval None
1490 */
HAL_RTC_DST_Sub1Hour(RTC_HandleTypeDef * hrtc)1491 void HAL_RTC_DST_Sub1Hour(RTC_HandleTypeDef *hrtc)
1492 {
1493 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1494 SET_BIT(hrtc->Instance->CR, RTC_CR_SUB1H);
1495 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1496 }
1497
1498 /**
1499 * @brief Daylight Saving Time, sets the store operation bit.
1500 * @note It can be used by the software in order to memorize the DST status.
1501 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1502 * the configuration information for RTC.
1503 * @retval None
1504 */
HAL_RTC_DST_SetStoreOperation(RTC_HandleTypeDef * hrtc)1505 void HAL_RTC_DST_SetStoreOperation(RTC_HandleTypeDef *hrtc)
1506 {
1507 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1508 SET_BIT(hrtc->Instance->CR, RTC_CR_BKP);
1509 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1510 }
1511
1512 /**
1513 * @brief Daylight Saving Time, clears the store operation bit.
1514 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1515 * the configuration information for RTC.
1516 * @retval None
1517 */
HAL_RTC_DST_ClearStoreOperation(RTC_HandleTypeDef * hrtc)1518 void HAL_RTC_DST_ClearStoreOperation(RTC_HandleTypeDef *hrtc)
1519 {
1520 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1521 CLEAR_BIT(hrtc->Instance->CR, RTC_CR_BKP);
1522 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1523 }
1524
1525 /**
1526 * @brief Daylight Saving Time, reads the store operation bit.
1527 * @param hrtc RTC handle
1528 * @retval operation see RTC_StoreOperation_Definitions
1529 */
HAL_RTC_DST_ReadStoreOperation(RTC_HandleTypeDef * hrtc)1530 uint32_t HAL_RTC_DST_ReadStoreOperation(RTC_HandleTypeDef *hrtc)
1531 {
1532 return READ_BIT(hrtc->Instance->CR, RTC_CR_BKP);
1533 }
1534
1535 /**
1536 * @}
1537 */
1538
1539 /** @defgroup RTC_Exported_Functions_Group5 Peripheral State functions
1540 * @brief Peripheral State functions
1541 *
1542 @verbatim
1543 ===============================================================================
1544 ##### Peripheral State functions #####
1545 ===============================================================================
1546 [..]
1547 This subsection provides functions allowing to
1548 (+) Get RTC state
1549
1550 @endverbatim
1551 * @{
1552 */
1553 /**
1554 * @brief Returns the RTC state.
1555 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1556 * the configuration information for RTC.
1557 * @retval HAL state
1558 */
HAL_RTC_GetState(RTC_HandleTypeDef * hrtc)1559 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc)
1560 {
1561 return hrtc->State;
1562 }
1563
1564 /**
1565 * @}
1566 */
1567
1568
1569 /**
1570 * @}
1571 */
1572
1573 /** @addtogroup RTC_Private_Functions
1574 * @{
1575 */
1576
1577 /**
1578 * @brief Enters the RTC Initialization mode.
1579 * @note The RTC Initialization mode is write protected, use the
1580 * __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
1581 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1582 * the configuration information for RTC.
1583 * @retval HAL status
1584 */
RTC_EnterInitMode(RTC_HandleTypeDef * hrtc)1585 HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
1586 {
1587 uint32_t tickstart = 0U;
1588 HAL_StatusTypeDef status = HAL_OK;
1589
1590 /* Check that Initialization mode is not already set */
1591 if (READ_BIT(hrtc->Instance->ISR, RTC_ISR_INITF) == 0U)
1592 {
1593 /* Set INIT bit to enter Initialization mode */
1594 SET_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
1595
1596 /* Get tick */
1597 tickstart = HAL_GetTick();
1598
1599 /* Wait till RTC is in INIT state and if timeout is reached exit */
1600 while ((READ_BIT(hrtc->Instance->ISR, RTC_ISR_INITF) == 0U) && (status != HAL_ERROR))
1601 {
1602 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1603 {
1604 /* Set RTC state */
1605 hrtc->State = HAL_RTC_STATE_ERROR;
1606 status = HAL_ERROR;
1607 }
1608 }
1609 }
1610
1611 return status;
1612 }
1613
1614 /**
1615 * @brief Exits the RTC Initialization mode.
1616 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1617 * the configuration information for RTC.
1618 * @retval HAL status
1619 */
RTC_ExitInitMode(RTC_HandleTypeDef * hrtc)1620 HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc)
1621 {
1622 HAL_StatusTypeDef status = HAL_OK;
1623
1624 /* Clear INIT bit to exit Initialization mode */
1625 CLEAR_BIT(hrtc->Instance->ISR, RTC_ISR_INIT);
1626
1627 /* If CR_BYPSHAD bit = 0, wait for synchro */
1628 if (READ_BIT(hrtc->Instance->CR, RTC_CR_BYPSHAD) == 0U)
1629 {
1630 if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
1631 {
1632 /* Set RTC state */
1633 hrtc->State = HAL_RTC_STATE_ERROR;
1634 status = HAL_ERROR;
1635 }
1636 }
1637
1638 return status;
1639 }
1640
1641 /**
1642 * @brief Converts a 2-digit number from decimal to BCD format.
1643 * @param number decimal-formatted number (from 0 to 99) to be converted
1644 * @retval Converted byte
1645 */
RTC_ByteToBcd2(uint8_t number)1646 uint8_t RTC_ByteToBcd2(uint8_t number)
1647 {
1648 uint32_t bcdhigh = 0U;
1649
1650 while (number >= 10U)
1651 {
1652 bcdhigh++;
1653 number -= 10U;
1654 }
1655
1656 return ((uint8_t)(bcdhigh << 4U) | number);
1657 }
1658
1659 /**
1660 * @brief Converts a 2-digit number from BCD to decimal format.
1661 * @param number BCD-formatted number (from 00 to 99) to be converted
1662 * @retval Converted word
1663 */
RTC_Bcd2ToByte(uint8_t number)1664 uint8_t RTC_Bcd2ToByte(uint8_t number)
1665 {
1666 uint32_t tens = 0U;
1667 tens = (((uint32_t)number & 0xF0U) >> 4U) * 10U;
1668 return (uint8_t)(tens + ((uint32_t)number & 0x0FU));
1669 }
1670
1671 /**
1672 * @}
1673 */
1674
1675 #endif /* HAL_RTC_MODULE_ENABLED */
1676 /**
1677 * @}
1678 */
1679
1680 /**
1681 * @}
1682 */
1683