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