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