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