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