1 /**
2 ******************************************************************************
3 * @file stm32f1xx_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 * + RTC Time and Date functions
10 * + RTC Alarm functions
11 * + Peripheral Control functions
12 * + Peripheral State functions
13 *
14 @verbatim
15 ==============================================================================
16 ##### How to use this driver #####
17 ==================================================================
18 [..]
19 (+) Enable the RTC domain access (see description in the section above).
20 (+) Configure the RTC Prescaler (Asynchronous prescaler to generate RTC 1Hz time base)
21 using the HAL_RTC_Init() function.
22
23 *** Time and Date configuration ***
24 ===================================
25 [..]
26 (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
27 and HAL_RTC_SetDate() functions.
28 (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions.
29
30 *** Alarm configuration ***
31 ===========================
32 [..]
33 (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
34 You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function.
35 (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
36
37 *** Tamper configuration ***
38 ============================
39 [..]
40 (+) Enable the RTC Tamper and configure the Tamper Level using the
41 HAL_RTCEx_SetTamper() function. You can configure RTC Tamper with interrupt
42 mode using HAL_RTCEx_SetTamper_IT() function.
43 (+) The TAMPER1 alternate function can be mapped to PC13
44
45 *** Backup Data Registers configuration ***
46 ===========================================
47 [..]
48 (+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite()
49 function.
50 (+) To read the RTC Backup Data registers, use the HAL_RTCEx_BKUPRead()
51 function.
52
53 ##### WARNING: Drivers Restrictions #####
54 ==================================================================
55 [..] RTC version used on STM32F1 families is version V1. All the features supported by V2
56 (other families) will be not supported on F1.
57 [..] As on V2, main RTC features are managed by HW. But on F1, date feature is completely
58 managed by SW.
59 [..] Then, there are some restrictions compared to other families:
60 (+) Only format 24 hours supported in HAL (format 12 hours not supported)
61 (+) Date is saved in SRAM. Then, when MCU is in STOP or STANDBY mode, date will be lost.
62 User should implement a way to save date before entering in low power mode (an
63 example is provided with firmware package based on backup registers)
64 (+) Date is automatically updated each time a HAL_RTC_GetTime or HAL_RTC_GetDate is called.
65 (+) Alarm detection is limited to 1 day. It will expire only 1 time (no alarm repetition, need
66 to program a new alarm)
67
68 ##### Backup Domain Operating Condition #####
69 ==============================================================================
70 [..] The real-time clock (RTC) and the RTC backup registers can be powered
71 from the VBAT voltage when the main VDD supply is powered off.
72 To retain the content of the RTC backup registers and supply the RTC
73 when VDD is turned off, VBAT pin can be connected to an optional
74 standby voltage supplied by a battery or by another source.
75
76 [..] To allow the RTC operating even when the main digital supply (VDD) is turned
77 off, the VBAT pin powers the following blocks:
78 (#) The RTC
79 (#) The LSE oscillator
80 (#) The backup SRAM when the low power backup regulator is enabled
81 (#) PC13 to PC15 I/Os, plus PI8 I/O (when available)
82
83 [..] When the backup domain is supplied by VDD (analog switch connected to VDD),
84 the following pins are available:
85 (+) PC13 can be used as a Tamper pin
86
87 [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
88 because VDD is not present), the following pins are available:
89 (+) PC13 can be used as the Tamper pin
90
91 ##### Backup Domain Reset #####
92 ==================================================================
93 [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
94 to their reset values.
95 [..] A backup domain reset is generated when one of the following events occurs:
96 (#) Software reset, triggered by setting the BDRST bit in the
97 RCC Backup domain control register (RCC_BDCR).
98 (#) VDD or VBAT power on, if both supplies have previously been powered off.
99 (#) Tamper detection event resets all data backup registers.
100
101 ##### Backup Domain Access #####
102 ==================================================================
103 [..] After reset, the backup domain (RTC registers, RTC backup data
104 registers and backup SRAM) is protected against possible unwanted write
105 accesses.
106 [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
107 (+) Call the function HAL_RCCEx_PeriphCLKConfig in using RCC_PERIPHCLK_RTC for
108 PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSE)
109 (+) Enable the BKP clock in using __HAL_RCC_BKP_CLK_ENABLE()
110
111 ##### RTC and low power modes #####
112 ==================================================================
113 [..] The MCU can be woken up from a low power mode by an RTC alternate
114 function.
115 [..] The RTC alternate functions are the RTC alarms (Alarm A),
116 and RTC tamper event detection.
117 These RTC alternate functions can wake up the system from the Stop and
118 Standby low power modes.
119 [..] The system can also wake up from low power modes without depending
120 on an external interrupt (Auto-wakeup mode), by using the RTC alarm.
121
122 *** Callback registration ***
123 =============================================
124 [..]
125 The compilation define USE_HAL_RTC_REGISTER_CALLBACKS when set to 1
126 allows the user to configure dynamically the driver callbacks.
127 Use Function @ref HAL_RTC_RegisterCallback() to register an interrupt callback.
128
129 [..]
130 Function @ref HAL_RTC_RegisterCallback() allows to register following callbacks:
131 (+) AlarmAEventCallback : RTC Alarm A Event callback.
132 (+) Tamper1EventCallback : RTC Tamper 1 Event callback.
133 (+) MspInitCallback : RTC MspInit callback.
134 (+) MspDeInitCallback : RTC MspDeInit callback.
135 [..]
136 This function takes as parameters the HAL peripheral handle, the Callback ID
137 and a pointer to the user callback function.
138
139 [..]
140 Use function @ref HAL_RTC_UnRegisterCallback() to reset a callback to the default
141 weak function.
142 @ref HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
143 and the Callback ID.
144 This function allows to reset following callbacks:
145 (+) AlarmAEventCallback : RTC Alarm A Event callback.
146 (+) Tamper1EventCallback : RTC Tamper 1 Event callback.
147 (+) MspInitCallback : RTC MspInit callback.
148 (+) MspDeInitCallback : RTC MspDeInit callback.
149 [..]
150 By default, after the @ref HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET,
151 all callbacks are set to the corresponding weak functions :
152 example @ref AlarmAEventCallback().
153 Exception done for MspInit and MspDeInit callbacks that are reset to the legacy weak function
154 in the @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit() only when these callbacks are null
155 (not registered beforehand).
156 If not, MspInit or MspDeInit are not null, @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit()
157 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
158 [..]
159 Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only.
160 Exception done MspInit/MspDeInit that can be registered/unregistered
161 in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state,
162 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
163 In that case first register the MspInit/MspDeInit user callbacks
164 using @ref HAL_RTC_RegisterCallback() before calling @ref HAL_RTC_DeInit()
165 or @ref HAL_RTC_Init() function.
166 [..]
167 When The compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or
168 not defined, the callback registration feature is not available and all callbacks
169 are set to the corresponding weak functions.
170 @endverbatim
171 ******************************************************************************
172 * @attention
173 *
174 * <h2><center>© Copyright (c) 2016 STMicroelectronics.
175 * All rights reserved.</center></h2>
176 *
177 * This software component is licensed by ST under BSD 3-Clause license,
178 * the "License"; You may not use this file except in compliance with the
179 * License. You may obtain a copy of the License at:
180 * opensource.org/licenses/BSD-3-Clause
181 *
182 ******************************************************************************
183 */
184
185 /* Includes ------------------------------------------------------------------*/
186 #include "stm32f1xx_hal.h"
187
188 /** @addtogroup STM32F1xx_HAL_Driver
189 * @{
190 */
191
192 /** @defgroup RTC RTC
193 * @brief RTC HAL module driver
194 * @{
195 */
196
197 #ifdef HAL_RTC_MODULE_ENABLED
198
199 /* Private typedef -----------------------------------------------------------*/
200 /* Private define ------------------------------------------------------------*/
201 /** @defgroup RTC_Private_Constants RTC Private Constants
202 * @{
203 */
204 #define RTC_ALARM_RESETVALUE_REGISTER (uint16_t)0xFFFF
205 #define RTC_ALARM_RESETVALUE 0xFFFFFFFFU
206
207 /**
208 * @}
209 */
210
211 /* Private macro -------------------------------------------------------------*/
212 /** @defgroup RTC_Private_Macros RTC Private Macros
213 * @{
214 */
215 /**
216 * @}
217 */
218
219 /* Private variables ---------------------------------------------------------*/
220 /* Private function prototypes -----------------------------------------------*/
221 /** @defgroup RTC_Private_Functions RTC Private Functions
222 * @{
223 */
224 static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef *hrtc);
225 static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter);
226 static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef *hrtc);
227 static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef *hrtc, uint32_t AlarmCounter);
228 static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc);
229 static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc);
230 static uint8_t RTC_ByteToBcd2(uint8_t Value);
231 static uint8_t RTC_Bcd2ToByte(uint8_t Value);
232 static uint8_t RTC_IsLeapYear(uint16_t nYear);
233 static void RTC_DateUpdate(RTC_HandleTypeDef *hrtc, uint32_t DayElapsed);
234 static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay);
235
236 /**
237 * @}
238 */
239
240 /* Private functions ---------------------------------------------------------*/
241 /** @defgroup RTC_Exported_Functions RTC Exported Functions
242 * @{
243 */
244
245 /** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
246 * @brief Initialization and Configuration functions
247 *
248 @verbatim
249 ===============================================================================
250 ##### Initialization and de-initialization functions #####
251 ===============================================================================
252 [..] This section provides functions allowing to initialize and configure the
253 RTC Prescaler (Asynchronous), disable RTC registers Write protection,
254 enter and exit the RTC initialization mode,
255 RTC registers synchronization check and reference clock detection enable.
256 (#) The RTC Prescaler should be programmed to generate the RTC 1Hz time base.
257 (#) All RTC registers are Write protected. Writing to the RTC registers
258 is enabled by setting the CNF bit in the RTC_CRL register.
259 (#) To read the calendar after wakeup from low power modes (Standby or Stop)
260 the software must first wait for the RSF bit (Register Synchronized Flag)
261 in the RTC_CRL register to be set by hardware.
262 The HAL_RTC_WaitForSynchro() function implements the above software
263 sequence (RSF clear and RSF check).
264
265 @endverbatim
266 * @{
267 */
268
269 /**
270 * @brief Initializes the RTC peripheral
271 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
272 * the configuration information for RTC.
273 * @retval HAL status
274 */
HAL_RTC_Init(RTC_HandleTypeDef * hrtc)275 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
276 {
277 uint32_t prescaler = 0U;
278 /* Check input parameters */
279 if (hrtc == NULL)
280 {
281 return HAL_ERROR;
282 }
283
284 /* Check the parameters */
285 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
286 assert_param(IS_RTC_CALIB_OUTPUT(hrtc->Init.OutPut));
287 assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
288
289 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
290 if (hrtc->State == HAL_RTC_STATE_RESET)
291 {
292 /* Allocate lock resource and initialize it */
293 hrtc->Lock = HAL_UNLOCKED;
294
295 hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */
296 hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback; /* Legacy weak Tamper1EventCallback */
297
298 if (hrtc->MspInitCallback == NULL)
299 {
300 hrtc->MspInitCallback = HAL_RTC_MspInit;
301 }
302 /* Init the low level hardware */
303 hrtc->MspInitCallback(hrtc);
304
305 if (hrtc->MspDeInitCallback == NULL)
306 {
307 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
308 }
309 }
310 #else
311 if (hrtc->State == HAL_RTC_STATE_RESET)
312 {
313 /* Allocate lock resource and initialize it */
314 hrtc->Lock = HAL_UNLOCKED;
315
316 /* Initialize RTC MSP */
317 HAL_RTC_MspInit(hrtc);
318 }
319 #endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */
320
321 /* Set RTC state */
322 hrtc->State = HAL_RTC_STATE_BUSY;
323
324 /* Waiting for synchro */
325 if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
326 {
327 /* Set RTC state */
328 hrtc->State = HAL_RTC_STATE_ERROR;
329
330 return HAL_ERROR;
331 }
332
333 /* Set Initialization mode */
334 if (RTC_EnterInitMode(hrtc) != HAL_OK)
335 {
336 /* Set RTC state */
337 hrtc->State = HAL_RTC_STATE_ERROR;
338
339 return HAL_ERROR;
340 }
341 else
342 {
343 /* Clear Flags Bits */
344 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_OW | RTC_FLAG_ALRAF | RTC_FLAG_SEC));
345
346 if (hrtc->Init.OutPut != RTC_OUTPUTSOURCE_NONE)
347 {
348 /* Disable the selected Tamper pin */
349 CLEAR_BIT(BKP->CR, BKP_CR_TPE);
350 }
351
352 /* Set the signal which will be routed to RTC Tamper pin*/
353 MODIFY_REG(BKP->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), hrtc->Init.OutPut);
354
355 if (hrtc->Init.AsynchPrediv != RTC_AUTO_1_SECOND)
356 {
357 /* RTC Prescaler provided directly by end-user*/
358 prescaler = hrtc->Init.AsynchPrediv;
359 }
360 else
361 {
362 /* RTC Prescaler will be automatically calculated to get 1 second timebase */
363 /* Get the RTCCLK frequency */
364 prescaler = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC);
365
366 /* Check that RTC clock is enabled*/
367 if (prescaler == 0U)
368 {
369 /* Should not happen. Frequency is not available*/
370 hrtc->State = HAL_RTC_STATE_ERROR;
371 return HAL_ERROR;
372 }
373 else
374 {
375 /* RTC period = RTCCLK/(RTC_PR + 1) */
376 prescaler = prescaler - 1U;
377 }
378 }
379
380 /* Configure the RTC_PRLH / RTC_PRLL */
381 MODIFY_REG(hrtc->Instance->PRLH, RTC_PRLH_PRL, (prescaler >> 16U));
382 MODIFY_REG(hrtc->Instance->PRLL, RTC_PRLL_PRL, (prescaler & RTC_PRLL_PRL));
383
384 /* Wait for synchro */
385 if (RTC_ExitInitMode(hrtc) != HAL_OK)
386 {
387 hrtc->State = HAL_RTC_STATE_ERROR;
388
389 return HAL_ERROR;
390 }
391
392 /* Initialize date to 1st of January 2000 */
393 hrtc->DateToUpdate.Year = 0x00U;
394 hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY;
395 hrtc->DateToUpdate.Date = 0x01U;
396
397 /* Set RTC state */
398 hrtc->State = HAL_RTC_STATE_READY;
399
400 return HAL_OK;
401 }
402 }
403
404 /**
405 * @brief DeInitializes the RTC peripheral
406 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
407 * the configuration information for RTC.
408 * @note This function does not reset the RTC Backup Data registers.
409 * @retval HAL status
410 */
HAL_RTC_DeInit(RTC_HandleTypeDef * hrtc)411 HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
412 {
413 /* Check input parameters */
414 if (hrtc == NULL)
415 {
416 return HAL_ERROR;
417 }
418
419 /* Check the parameters */
420 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
421
422 /* Set RTC state */
423 hrtc->State = HAL_RTC_STATE_BUSY;
424
425 /* Set Initialization mode */
426 if (RTC_EnterInitMode(hrtc) != HAL_OK)
427 {
428 /* Set RTC state */
429 hrtc->State = HAL_RTC_STATE_ERROR;
430
431 /* Release Lock */
432 __HAL_UNLOCK(hrtc);
433
434 return HAL_ERROR;
435 }
436 else
437 {
438 CLEAR_REG(hrtc->Instance->CNTL);
439 CLEAR_REG(hrtc->Instance->CNTH);
440 WRITE_REG(hrtc->Instance->PRLL, 0x00008000U);
441 CLEAR_REG(hrtc->Instance->PRLH);
442
443 /* Reset All CRH/CRL bits */
444 CLEAR_REG(hrtc->Instance->CRH);
445 CLEAR_REG(hrtc->Instance->CRL);
446
447 if (RTC_ExitInitMode(hrtc) != HAL_OK)
448 {
449 hrtc->State = HAL_RTC_STATE_ERROR;
450
451 /* Process Unlocked */
452 __HAL_UNLOCK(hrtc);
453
454 return HAL_ERROR;
455 }
456 }
457
458 /* Wait for synchro*/
459 HAL_RTC_WaitForSynchro(hrtc);
460
461 /* Clear RSF flag */
462 CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
463
464 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
465 if (hrtc->MspDeInitCallback == NULL)
466 {
467 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
468 }
469
470 /* DeInit the low level hardware: CLOCK, NVIC.*/
471 hrtc->MspDeInitCallback(hrtc);
472
473 #else
474 /* De-Initialize RTC MSP */
475 HAL_RTC_MspDeInit(hrtc);
476 #endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */
477
478 hrtc->State = HAL_RTC_STATE_RESET;
479
480 /* Release Lock */
481 __HAL_UNLOCK(hrtc);
482
483 return HAL_OK;
484 }
485
486 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
487 /**
488 * @brief Register a User RTC Callback
489 * To be used instead of the weak predefined callback
490 * @param hrtc RTC handle
491 * @param CallbackID ID of the callback to be registered
492 * This parameter can be one of the following values:
493 * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID
494 * @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID
495 * @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID
496 * @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID
497 * @param pCallback pointer to the Callback function
498 * @retval HAL status
499 */
HAL_RTC_RegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID,pRTC_CallbackTypeDef pCallback)500 HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, pRTC_CallbackTypeDef pCallback)
501 {
502 HAL_StatusTypeDef status = HAL_OK;
503
504 if (pCallback == NULL)
505 {
506 return HAL_ERROR;
507 }
508
509 /* Process locked */
510 __HAL_LOCK(hrtc);
511
512 if (HAL_RTC_STATE_READY == hrtc->State)
513 {
514 switch (CallbackID)
515 {
516 case HAL_RTC_ALARM_A_EVENT_CB_ID :
517 hrtc->AlarmAEventCallback = pCallback;
518 break;
519
520 case HAL_RTC_TAMPER1_EVENT_CB_ID :
521 hrtc->Tamper1EventCallback = pCallback;
522 break;
523
524 case HAL_RTC_MSPINIT_CB_ID :
525 hrtc->MspInitCallback = pCallback;
526 break;
527
528 case HAL_RTC_MSPDEINIT_CB_ID :
529 hrtc->MspDeInitCallback = pCallback;
530 break;
531
532 default :
533 /* Return error status */
534 status = HAL_ERROR;
535 break;
536 }
537 }
538 else if (HAL_RTC_STATE_RESET == hrtc->State)
539 {
540 switch (CallbackID)
541 {
542 case HAL_RTC_MSPINIT_CB_ID :
543 hrtc->MspInitCallback = pCallback;
544 break;
545
546 case HAL_RTC_MSPDEINIT_CB_ID :
547 hrtc->MspDeInitCallback = pCallback;
548 break;
549
550 default :
551 /* Return error status */
552 status = HAL_ERROR;
553 break;
554 }
555 }
556 else
557 {
558 /* Return error status */
559 status = HAL_ERROR;
560 }
561
562 /* Release Lock */
563 __HAL_UNLOCK(hrtc);
564
565 return status;
566 }
567
568 /**
569 * @brief Unregister an RTC Callback
570 * RTC callabck is redirected to the weak predefined callback
571 * @param hrtc RTC handle
572 * @param CallbackID ID of the callback to be unregistered
573 * This parameter can be one of the following values:
574 * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID
575 * @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID
576 * @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID
577 * @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID
578 * @retval HAL status
579 */
HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef * hrtc,HAL_RTC_CallbackIDTypeDef CallbackID)580 HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID)
581 {
582 HAL_StatusTypeDef status = HAL_OK;
583
584 /* Process locked */
585 __HAL_LOCK(hrtc);
586
587 if (HAL_RTC_STATE_READY == hrtc->State)
588 {
589 switch (CallbackID)
590 {
591 case HAL_RTC_ALARM_A_EVENT_CB_ID :
592 hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */
593 break;
594
595 case HAL_RTC_TAMPER1_EVENT_CB_ID :
596 hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback; /* Legacy weak Tamper1EventCallback */
597 break;
598
599 case HAL_RTC_MSPINIT_CB_ID :
600 hrtc->MspInitCallback = HAL_RTC_MspInit;
601 break;
602
603 case HAL_RTC_MSPDEINIT_CB_ID :
604 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
605 break;
606
607 default :
608 /* Return error status */
609 status = HAL_ERROR;
610 break;
611 }
612 }
613 else if (HAL_RTC_STATE_RESET == hrtc->State)
614 {
615 switch (CallbackID)
616 {
617 case HAL_RTC_MSPINIT_CB_ID :
618 hrtc->MspInitCallback = HAL_RTC_MspInit;
619 break;
620
621 case HAL_RTC_MSPDEINIT_CB_ID :
622 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
623 break;
624
625 default :
626 /* Return error status */
627 status = HAL_ERROR;
628 break;
629 }
630 }
631 else
632 {
633 /* Return error status */
634 status = HAL_ERROR;
635 }
636
637 /* Release Lock */
638 __HAL_UNLOCK(hrtc);
639
640 return status;
641 }
642 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
643
644 /**
645 * @brief Initializes the RTC MSP.
646 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
647 * the configuration information for RTC.
648 * @retval None
649 */
HAL_RTC_MspInit(RTC_HandleTypeDef * hrtc)650 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
651 {
652 /* Prevent unused argument(s) compilation warning */
653 UNUSED(hrtc);
654 /* NOTE : This function Should not be modified, when the callback is needed,
655 the HAL_RTC_MspInit could be implemented in the user file
656 */
657 }
658
659 /**
660 * @brief DeInitializes the RTC MSP.
661 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
662 * the configuration information for RTC.
663 * @retval None
664 */
HAL_RTC_MspDeInit(RTC_HandleTypeDef * hrtc)665 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
666 {
667 /* Prevent unused argument(s) compilation warning */
668 UNUSED(hrtc);
669 /* NOTE : This function Should not be modified, when the callback is needed,
670 the HAL_RTC_MspDeInit could be implemented in the user file
671 */
672 }
673
674 /**
675 * @}
676 */
677
678 /** @defgroup RTC_Exported_Functions_Group2 Time and Date functions
679 * @brief RTC Time and Date functions
680 *
681 @verbatim
682 ===============================================================================
683 ##### RTC Time and Date functions #####
684 ===============================================================================
685
686 [..] This section provides functions allowing to configure Time and Date features
687
688 @endverbatim
689 * @{
690 */
691
692 /**
693 * @brief Sets RTC current time.
694 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
695 * the configuration information for RTC.
696 * @param sTime: Pointer to Time structure
697 * @param Format: Specifies the format of the entered parameters.
698 * This parameter can be one of the following values:
699 * @arg RTC_FORMAT_BIN: Binary data format
700 * @arg RTC_FORMAT_BCD: BCD data format
701 * @retval HAL status
702 */
HAL_RTC_SetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)703 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
704 {
705 uint32_t counter_time = 0U, counter_alarm = 0U;
706
707 /* Check input parameters */
708 if ((hrtc == NULL) || (sTime == NULL))
709 {
710 return HAL_ERROR;
711 }
712
713 /* Check the parameters */
714 assert_param(IS_RTC_FORMAT(Format));
715
716 /* Process Locked */
717 __HAL_LOCK(hrtc);
718
719 hrtc->State = HAL_RTC_STATE_BUSY;
720
721 if (Format == RTC_FORMAT_BIN)
722 {
723 assert_param(IS_RTC_HOUR24(sTime->Hours));
724 assert_param(IS_RTC_MINUTES(sTime->Minutes));
725 assert_param(IS_RTC_SECONDS(sTime->Seconds));
726
727 counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600U) + \
728 ((uint32_t)sTime->Minutes * 60U) + \
729 ((uint32_t)sTime->Seconds));
730 }
731 else
732 {
733 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
734 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
735 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
736
737 counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600U) + \
738 ((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60U) + \
739 ((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds))));
740 }
741
742 /* Write time counter in RTC registers */
743 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
744 {
745 /* Set RTC state */
746 hrtc->State = HAL_RTC_STATE_ERROR;
747
748 /* Process Unlocked */
749 __HAL_UNLOCK(hrtc);
750
751 return HAL_ERROR;
752 }
753 else
754 {
755 /* Clear Second and overflow flags */
756 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
757
758 /* Read current Alarm counter in RTC registers */
759 counter_alarm = RTC_ReadAlarmCounter(hrtc);
760
761 /* Set again alarm to match with new time if enabled */
762 if (counter_alarm != RTC_ALARM_RESETVALUE)
763 {
764 if (counter_alarm < counter_time)
765 {
766 /* Add 1 day to alarm counter*/
767 counter_alarm += (uint32_t)(24U * 3600U);
768
769 /* Write new Alarm counter in RTC registers */
770 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
771 {
772 /* Set RTC state */
773 hrtc->State = HAL_RTC_STATE_ERROR;
774
775 /* Process Unlocked */
776 __HAL_UNLOCK(hrtc);
777
778 return HAL_ERROR;
779 }
780 }
781 }
782
783 hrtc->State = HAL_RTC_STATE_READY;
784
785 __HAL_UNLOCK(hrtc);
786
787 return HAL_OK;
788 }
789 }
790
791 /**
792 * @brief Gets RTC current time.
793 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
794 * the configuration information for RTC.
795 * @param sTime: Pointer to Time structure
796 * @param Format: Specifies the format of the entered parameters.
797 * This parameter can be one of the following values:
798 * @arg RTC_FORMAT_BIN: Binary data format
799 * @arg RTC_FORMAT_BCD: BCD data format
800 * @retval HAL status
801 */
HAL_RTC_GetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)802 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
803 {
804 uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U;
805
806 /* Check input parameters */
807 if ((hrtc == NULL) || (sTime == NULL))
808 {
809 return HAL_ERROR;
810 }
811
812 /* Check the parameters */
813 assert_param(IS_RTC_FORMAT(Format));
814
815 /* Check if counter overflow occurred */
816 if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW))
817 {
818 return HAL_ERROR;
819 }
820
821 /* Read the time counter*/
822 counter_time = RTC_ReadTimeCounter(hrtc);
823
824 /* Fill the structure fields with the read parameters */
825 hours = counter_time / 3600U;
826 sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U);
827 sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U);
828
829 if (hours >= 24U)
830 {
831 /* Get number of days elapsed from last calculation */
832 days_elapsed = (hours / 24U);
833
834 /* Set Hours in RTC_TimeTypeDef structure*/
835 sTime->Hours = (hours % 24U);
836
837 /* Read Alarm counter in RTC registers */
838 counter_alarm = RTC_ReadAlarmCounter(hrtc);
839
840 /* Calculate remaining time to reach alarm (only if set and not yet expired)*/
841 if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time))
842 {
843 counter_alarm -= counter_time;
844 }
845 else
846 {
847 /* In case of counter_alarm < counter_time */
848 /* Alarm expiration already occurred but alarm not deactivated */
849 counter_alarm = RTC_ALARM_RESETVALUE;
850 }
851
852 /* Set updated time in decreasing counter by number of days elapsed */
853 counter_time -= (days_elapsed * 24U * 3600U);
854
855 /* Write time counter in RTC registers */
856 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
857 {
858 return HAL_ERROR;
859 }
860
861 /* Set updated alarm to be set */
862 if (counter_alarm != RTC_ALARM_RESETVALUE)
863 {
864 counter_alarm += counter_time;
865
866 /* Write time counter in RTC registers */
867 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
868 {
869 return HAL_ERROR;
870 }
871 }
872 else
873 {
874 /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
875 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
876 {
877 return HAL_ERROR;
878 }
879 }
880
881 /* Update date */
882 RTC_DateUpdate(hrtc, days_elapsed);
883 }
884 else
885 {
886 sTime->Hours = hours;
887 }
888
889 /* Check the input parameters format */
890 if (Format != RTC_FORMAT_BIN)
891 {
892 /* Convert the time structure parameters to BCD format */
893 sTime->Hours = (uint8_t)RTC_ByteToBcd2(sTime->Hours);
894 sTime->Minutes = (uint8_t)RTC_ByteToBcd2(sTime->Minutes);
895 sTime->Seconds = (uint8_t)RTC_ByteToBcd2(sTime->Seconds);
896 }
897
898 return HAL_OK;
899 }
900
901
902 /**
903 * @brief Sets RTC current date.
904 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
905 * the configuration information for RTC.
906 * @param sDate: Pointer to date structure
907 * @param Format: specifies the format of the entered parameters.
908 * This parameter can be one of the following values:
909 * @arg RTC_FORMAT_BIN: Binary data format
910 * @arg RTC_FORMAT_BCD: BCD data format
911 * @retval HAL status
912 */
HAL_RTC_SetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)913 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
914 {
915 uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U;
916
917 /* Check input parameters */
918 if ((hrtc == NULL) || (sDate == NULL))
919 {
920 return HAL_ERROR;
921 }
922
923 /* Check the parameters */
924 assert_param(IS_RTC_FORMAT(Format));
925
926 /* Process Locked */
927 __HAL_LOCK(hrtc);
928
929 hrtc->State = HAL_RTC_STATE_BUSY;
930
931 if (Format == RTC_FORMAT_BIN)
932 {
933 assert_param(IS_RTC_YEAR(sDate->Year));
934 assert_param(IS_RTC_MONTH(sDate->Month));
935 assert_param(IS_RTC_DATE(sDate->Date));
936
937 /* Change the current date */
938 hrtc->DateToUpdate.Year = sDate->Year;
939 hrtc->DateToUpdate.Month = sDate->Month;
940 hrtc->DateToUpdate.Date = sDate->Date;
941 }
942 else
943 {
944 assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
945 assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
946 assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
947
948 /* Change the current date */
949 hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year);
950 hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
951 hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date);
952 }
953
954 /* WeekDay set by user can be ignored because automatically calculated */
955 hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
956 sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
957
958 /* Reset time to be aligned on the same day */
959 /* Read the time counter*/
960 counter_time = RTC_ReadTimeCounter(hrtc);
961
962 /* Fill the structure fields with the read parameters */
963 hours = counter_time / 3600U;
964 if (hours > 24U)
965 {
966 /* Set updated time in decreasing counter by number of days elapsed */
967 counter_time -= ((hours / 24U) * 24U * 3600U);
968 /* Write time counter in RTC registers */
969 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
970 {
971 /* Set RTC state */
972 hrtc->State = HAL_RTC_STATE_ERROR;
973
974 /* Process Unlocked */
975 __HAL_UNLOCK(hrtc);
976
977 return HAL_ERROR;
978 }
979
980 /* Read current Alarm counter in RTC registers */
981 counter_alarm = RTC_ReadAlarmCounter(hrtc);
982
983 /* Set again alarm to match with new time if enabled */
984 if (counter_alarm != RTC_ALARM_RESETVALUE)
985 {
986 if (counter_alarm < counter_time)
987 {
988 /* Add 1 day to alarm counter*/
989 counter_alarm += (uint32_t)(24U * 3600U);
990
991 /* Write new Alarm counter in RTC registers */
992 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
993 {
994 /* Set RTC state */
995 hrtc->State = HAL_RTC_STATE_ERROR;
996
997 /* Process Unlocked */
998 __HAL_UNLOCK(hrtc);
999
1000 return HAL_ERROR;
1001 }
1002 }
1003 }
1004
1005
1006 }
1007
1008 hrtc->State = HAL_RTC_STATE_READY ;
1009
1010 /* Process Unlocked */
1011 __HAL_UNLOCK(hrtc);
1012
1013 return HAL_OK;
1014 }
1015
1016 /**
1017 * @brief Gets RTC current date.
1018 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1019 * the configuration information for RTC.
1020 * @param sDate: Pointer to Date structure
1021 * @param Format: Specifies the format of the entered parameters.
1022 * This parameter can be one of the following values:
1023 * @arg RTC_FORMAT_BIN: Binary data format
1024 * @arg RTC_FORMAT_BCD: BCD data format
1025 * @retval HAL status
1026 */
HAL_RTC_GetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)1027 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
1028 {
1029 RTC_TimeTypeDef stime = {0U};
1030
1031 /* Check input parameters */
1032 if ((hrtc == NULL) || (sDate == NULL))
1033 {
1034 return HAL_ERROR;
1035 }
1036
1037 /* Check the parameters */
1038 assert_param(IS_RTC_FORMAT(Format));
1039
1040 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
1041 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
1042 {
1043 return HAL_ERROR;
1044 }
1045
1046 /* Fill the structure fields with the read parameters */
1047 sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
1048 sDate->Year = hrtc->DateToUpdate.Year;
1049 sDate->Month = hrtc->DateToUpdate.Month;
1050 sDate->Date = hrtc->DateToUpdate.Date;
1051
1052 /* Check the input parameters format */
1053 if (Format != RTC_FORMAT_BIN)
1054 {
1055 /* Convert the date structure parameters to BCD format */
1056 sDate->Year = (uint8_t)RTC_ByteToBcd2(sDate->Year);
1057 sDate->Month = (uint8_t)RTC_ByteToBcd2(sDate->Month);
1058 sDate->Date = (uint8_t)RTC_ByteToBcd2(sDate->Date);
1059 }
1060 return HAL_OK;
1061 }
1062
1063 /**
1064 * @}
1065 */
1066
1067 /** @defgroup RTC_Exported_Functions_Group3 Alarm functions
1068 * @brief RTC Alarm functions
1069 *
1070 @verbatim
1071 ===============================================================================
1072 ##### RTC Alarm functions #####
1073 ===============================================================================
1074
1075 [..] This section provides functions allowing to configure Alarm feature
1076
1077 @endverbatim
1078 * @{
1079 */
1080
1081 /**
1082 * @brief Sets the specified RTC Alarm.
1083 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1084 * the configuration information for RTC.
1085 * @param sAlarm: Pointer to Alarm structure
1086 * @param Format: Specifies the format of the entered parameters.
1087 * This parameter can be one of the following values:
1088 * @arg RTC_FORMAT_BIN: Binary data format
1089 * @arg RTC_FORMAT_BCD: BCD data format
1090 * @retval HAL status
1091 */
HAL_RTC_SetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1092 HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1093 {
1094 uint32_t counter_alarm = 0U, counter_time;
1095 RTC_TimeTypeDef stime = {0U};
1096
1097 /* Check input parameters */
1098 if ((hrtc == NULL) || (sAlarm == NULL))
1099 {
1100 return HAL_ERROR;
1101 }
1102
1103 /* Check the parameters */
1104 assert_param(IS_RTC_FORMAT(Format));
1105 assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1106
1107 /* Process Locked */
1108 __HAL_LOCK(hrtc);
1109
1110 hrtc->State = HAL_RTC_STATE_BUSY;
1111
1112 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
1113 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
1114 {
1115 return HAL_ERROR;
1116 }
1117
1118 /* Convert time in seconds */
1119 counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
1120 ((uint32_t)stime.Minutes * 60U) + \
1121 ((uint32_t)stime.Seconds));
1122
1123 if (Format == RTC_FORMAT_BIN)
1124 {
1125 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1126 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1127 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1128
1129 counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
1130 ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
1131 ((uint32_t)sAlarm->AlarmTime.Seconds));
1132 }
1133 else
1134 {
1135 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1136 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1137 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1138
1139 counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
1140 ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
1141 ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1142 }
1143
1144 /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
1145 if (counter_alarm < counter_time)
1146 {
1147 /* Add 1 day to alarm counter*/
1148 counter_alarm += (uint32_t)(24U * 3600U);
1149 }
1150
1151 /* Write Alarm counter in RTC registers */
1152 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
1153 {
1154 /* Set RTC state */
1155 hrtc->State = HAL_RTC_STATE_ERROR;
1156
1157 /* Process Unlocked */
1158 __HAL_UNLOCK(hrtc);
1159
1160 return HAL_ERROR;
1161 }
1162 else
1163 {
1164 hrtc->State = HAL_RTC_STATE_READY;
1165
1166 __HAL_UNLOCK(hrtc);
1167
1168 return HAL_OK;
1169 }
1170 }
1171
1172 /**
1173 * @brief Sets the specified RTC Alarm with Interrupt
1174 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1175 * the configuration information for RTC.
1176 * @param sAlarm: Pointer to Alarm structure
1177 * @param Format: Specifies the format of the entered parameters.
1178 * This parameter can be one of the following values:
1179 * @arg RTC_FORMAT_BIN: Binary data format
1180 * @arg RTC_FORMAT_BCD: BCD data format
1181 * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
1182 * @retval HAL status
1183 */
HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Format)1184 HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
1185 {
1186 uint32_t counter_alarm = 0U, counter_time;
1187 RTC_TimeTypeDef stime = {0U};
1188
1189 /* Check input parameters */
1190 if ((hrtc == NULL) || (sAlarm == NULL))
1191 {
1192 return HAL_ERROR;
1193 }
1194
1195 /* Check the parameters */
1196 assert_param(IS_RTC_FORMAT(Format));
1197 assert_param(IS_RTC_ALARM(sAlarm->Alarm));
1198
1199 /* Process Locked */
1200 __HAL_LOCK(hrtc);
1201
1202 hrtc->State = HAL_RTC_STATE_BUSY;
1203
1204 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
1205 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
1206 {
1207 return HAL_ERROR;
1208 }
1209
1210 /* Convert time in seconds */
1211 counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
1212 ((uint32_t)stime.Minutes * 60U) + \
1213 ((uint32_t)stime.Seconds));
1214
1215 if (Format == RTC_FORMAT_BIN)
1216 {
1217 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
1218 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
1219 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
1220
1221 counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
1222 ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
1223 ((uint32_t)sAlarm->AlarmTime.Seconds));
1224 }
1225 else
1226 {
1227 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1228 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1229 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1230
1231 counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
1232 ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
1233 ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1234 }
1235
1236 /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
1237 if (counter_alarm < counter_time)
1238 {
1239 /* Add 1 day to alarm counter*/
1240 counter_alarm += (uint32_t)(24U * 3600U);
1241 }
1242
1243 /* Write alarm counter in RTC registers */
1244 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
1245 {
1246 /* Set RTC state */
1247 hrtc->State = HAL_RTC_STATE_ERROR;
1248
1249 /* Process Unlocked */
1250 __HAL_UNLOCK(hrtc);
1251
1252 return HAL_ERROR;
1253 }
1254 else
1255 {
1256 /* Clear flag alarm A */
1257 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1258
1259 /* Configure the Alarm interrupt */
1260 __HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRA);
1261
1262 /* RTC Alarm Interrupt Configuration: EXTI configuration */
1263 __HAL_RTC_ALARM_EXTI_ENABLE_IT();
1264
1265 __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
1266
1267 hrtc->State = HAL_RTC_STATE_READY;
1268
1269 __HAL_UNLOCK(hrtc);
1270
1271 return HAL_OK;
1272 }
1273 }
1274
1275 /**
1276 * @brief Gets the RTC Alarm value and masks.
1277 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1278 * the configuration information for RTC.
1279 * @param sAlarm: Pointer to Date structure
1280 * @param Alarm: Specifies the Alarm.
1281 * This parameter can be one of the following values:
1282 * @arg RTC_ALARM_A: Alarm
1283 * @param Format: Specifies the format of the entered parameters.
1284 * This parameter can be one of the following values:
1285 * @arg RTC_FORMAT_BIN: Binary data format
1286 * @arg RTC_FORMAT_BCD: BCD data format
1287 * @retval HAL status
1288 */
HAL_RTC_GetAlarm(RTC_HandleTypeDef * hrtc,RTC_AlarmTypeDef * sAlarm,uint32_t Alarm,uint32_t Format)1289 HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
1290 {
1291 uint32_t counter_alarm = 0U;
1292
1293 /* Prevent unused argument(s) compilation warning */
1294 UNUSED(Alarm);
1295
1296 /* Check input parameters */
1297 if ((hrtc == NULL) || (sAlarm == NULL))
1298 {
1299 return HAL_ERROR;
1300 }
1301
1302 /* Check the parameters */
1303 assert_param(IS_RTC_FORMAT(Format));
1304 assert_param(IS_RTC_ALARM(Alarm));
1305
1306 /* Read Alarm counter in RTC registers */
1307 counter_alarm = RTC_ReadAlarmCounter(hrtc);
1308
1309 /* Fill the structure with the read parameters */
1310 /* Set hours in a day range (between 0 to 24)*/
1311 sAlarm->AlarmTime.Hours = (uint32_t)((counter_alarm / 3600U) % 24U);
1312 sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600U) / 60U);
1313 sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600U) % 60U);
1314
1315 if (Format != RTC_FORMAT_BIN)
1316 {
1317 sAlarm->AlarmTime.Hours = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours);
1318 sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes);
1319 sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds);
1320 }
1321
1322 return HAL_OK;
1323 }
1324
1325 /**
1326 * @brief Deactive the specified RTC Alarm
1327 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1328 * the configuration information for RTC.
1329 * @param Alarm: Specifies the Alarm.
1330 * This parameter can be one of the following values:
1331 * @arg RTC_ALARM_A: AlarmA
1332 * @retval HAL status
1333 */
HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef * hrtc,uint32_t Alarm)1334 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
1335 {
1336 /* Prevent unused argument(s) compilation warning */
1337 UNUSED(Alarm);
1338
1339 /* Check the parameters */
1340 assert_param(IS_RTC_ALARM(Alarm));
1341
1342 /* Check input parameters */
1343 if (hrtc == NULL)
1344 {
1345 return HAL_ERROR;
1346 }
1347
1348 /* Process Locked */
1349 __HAL_LOCK(hrtc);
1350
1351 hrtc->State = HAL_RTC_STATE_BUSY;
1352
1353 /* In case of interrupt mode is used, the interrupt source must disabled */
1354 __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1355
1356 /* Set Initialization mode */
1357 if (RTC_EnterInitMode(hrtc) != HAL_OK)
1358 {
1359 /* Set RTC state */
1360 hrtc->State = HAL_RTC_STATE_ERROR;
1361
1362 /* Process Unlocked */
1363 __HAL_UNLOCK(hrtc);
1364
1365 return HAL_ERROR;
1366 }
1367 else
1368 {
1369 /* Clear flag alarm A */
1370 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1371
1372 /* Set to default values ALRH & ALRL registers */
1373 WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER);
1374 WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER);
1375
1376 /* RTC Alarm Interrupt Configuration: Disable EXTI configuration */
1377 __HAL_RTC_ALARM_EXTI_DISABLE_IT();
1378
1379 /* Wait for synchro */
1380 if (RTC_ExitInitMode(hrtc) != HAL_OK)
1381 {
1382 hrtc->State = HAL_RTC_STATE_ERROR;
1383
1384 /* Process Unlocked */
1385 __HAL_UNLOCK(hrtc);
1386
1387 return HAL_ERROR;
1388 }
1389 }
1390 hrtc->State = HAL_RTC_STATE_READY;
1391
1392 /* Process Unlocked */
1393 __HAL_UNLOCK(hrtc);
1394
1395 return HAL_OK;
1396 }
1397
1398 /**
1399 * @brief This function handles Alarm interrupt request.
1400 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1401 * the configuration information for RTC.
1402 * @retval None
1403 */
HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef * hrtc)1404 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc)
1405 {
1406 if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
1407 {
1408 /* Get the status of the Interrupt */
1409 if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
1410 {
1411 /* AlarmA callback */
1412 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
1413 hrtc->AlarmAEventCallback(hrtc);
1414 #else
1415 HAL_RTC_AlarmAEventCallback(hrtc);
1416 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
1417
1418 /* Clear the Alarm interrupt pending bit */
1419 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1420 }
1421 }
1422
1423 /* Clear the EXTI's line Flag for RTC Alarm */
1424 __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
1425
1426 /* Change RTC state */
1427 hrtc->State = HAL_RTC_STATE_READY;
1428 }
1429
1430 /**
1431 * @brief Alarm A callback.
1432 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1433 * the configuration information for RTC.
1434 * @retval None
1435 */
HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef * hrtc)1436 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
1437 {
1438 /* Prevent unused argument(s) compilation warning */
1439 UNUSED(hrtc);
1440 /* NOTE : This function Should not be modified, when the callback is needed,
1441 the HAL_RTC_AlarmAEventCallback could be implemented in the user file
1442 */
1443 }
1444
1445 /**
1446 * @brief This function handles AlarmA Polling request.
1447 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1448 * the configuration information for RTC.
1449 * @param Timeout: Timeout duration
1450 * @retval HAL status
1451 */
HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)1452 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
1453 {
1454 uint32_t tickstart = HAL_GetTick();
1455
1456 /* Check input parameters */
1457 if (hrtc == NULL)
1458 {
1459 return HAL_ERROR;
1460 }
1461
1462 while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
1463 {
1464 if (Timeout != HAL_MAX_DELAY)
1465 {
1466 if ((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
1467 {
1468 hrtc->State = HAL_RTC_STATE_TIMEOUT;
1469 return HAL_TIMEOUT;
1470 }
1471 }
1472 }
1473
1474 /* Clear the Alarm interrupt pending bit */
1475 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1476
1477 /* Change RTC state */
1478 hrtc->State = HAL_RTC_STATE_READY;
1479
1480 return HAL_OK;
1481 }
1482
1483 /**
1484 * @}
1485 */
1486
1487 /** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions
1488 * @brief Peripheral State functions
1489 *
1490 @verbatim
1491 ===============================================================================
1492 ##### Peripheral State functions #####
1493 ===============================================================================
1494 [..]
1495 This subsection provides functions allowing to
1496 (+) Get RTC state
1497
1498 @endverbatim
1499 * @{
1500 */
1501 /**
1502 * @brief Returns the RTC state.
1503 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1504 * the configuration information for RTC.
1505 * @retval HAL state
1506 */
HAL_RTC_GetState(RTC_HandleTypeDef * hrtc)1507 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc)
1508 {
1509 return hrtc->State;
1510 }
1511
1512 /**
1513 * @}
1514 */
1515
1516 /** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions
1517 * @brief Peripheral Control functions
1518 *
1519 @verbatim
1520 ===============================================================================
1521 ##### Peripheral Control functions #####
1522 ===============================================================================
1523 [..]
1524 This subsection provides functions allowing to
1525 (+) Wait for RTC Time and Date Synchronization
1526
1527 @endverbatim
1528 * @{
1529 */
1530
1531 /**
1532 * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL)
1533 * are synchronized with RTC APB clock.
1534 * @note This function must be called before any read operation after an APB reset
1535 * or an APB clock stop.
1536 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1537 * the configuration information for RTC.
1538 * @retval HAL status
1539 */
HAL_RTC_WaitForSynchro(RTC_HandleTypeDef * hrtc)1540 HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc)
1541 {
1542 uint32_t tickstart = 0U;
1543
1544 /* Check input parameters */
1545 if (hrtc == NULL)
1546 {
1547 return HAL_ERROR;
1548 }
1549
1550 /* Clear RSF flag */
1551 CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
1552
1553 tickstart = HAL_GetTick();
1554
1555 /* Wait the registers to be synchronised */
1556 while ((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET)
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 * @}
1569 */
1570
1571
1572 /**
1573 * @}
1574 */
1575
1576 /** @addtogroup RTC_Private_Functions
1577 * @{
1578 */
1579
1580
1581 /**
1582 * @brief Read the time counter available in RTC_CNT registers.
1583 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1584 * the configuration information for RTC.
1585 * @retval Time counter
1586 */
RTC_ReadTimeCounter(RTC_HandleTypeDef * hrtc)1587 static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef *hrtc)
1588 {
1589 uint16_t high1 = 0U, high2 = 0U, low = 0U;
1590 uint32_t timecounter = 0U;
1591
1592 high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
1593 low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
1594 high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
1595
1596 if (high1 != high2)
1597 {
1598 /* In this case the counter roll over during reading of CNTL and CNTH registers,
1599 read again CNTL register then return the counter value */
1600 timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
1601 }
1602 else
1603 {
1604 /* No counter roll over during reading of CNTL and CNTH registers, counter
1605 value is equal to first value of CNTL and CNTH */
1606 timecounter = (((uint32_t) high1 << 16U) | low);
1607 }
1608
1609 return timecounter;
1610 }
1611
1612 /**
1613 * @brief Write the time counter in RTC_CNT registers.
1614 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1615 * the configuration information for RTC.
1616 * @param TimeCounter: Counter to write in RTC_CNT registers
1617 * @retval HAL status
1618 */
RTC_WriteTimeCounter(RTC_HandleTypeDef * hrtc,uint32_t TimeCounter)1619 static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter)
1620 {
1621 HAL_StatusTypeDef status = HAL_OK;
1622
1623 /* Set Initialization mode */
1624 if (RTC_EnterInitMode(hrtc) != HAL_OK)
1625 {
1626 status = HAL_ERROR;
1627 }
1628 else
1629 {
1630 /* Set RTC COUNTER MSB word */
1631 WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U));
1632 /* Set RTC COUNTER LSB word */
1633 WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
1634
1635 /* Wait for synchro */
1636 if (RTC_ExitInitMode(hrtc) != HAL_OK)
1637 {
1638 status = HAL_ERROR;
1639 }
1640 }
1641
1642 return status;
1643 }
1644
1645 /**
1646 * @brief Read the time counter available in RTC_ALR registers.
1647 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1648 * the configuration information for RTC.
1649 * @retval Time counter
1650 */
RTC_ReadAlarmCounter(RTC_HandleTypeDef * hrtc)1651 static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef *hrtc)
1652 {
1653 uint16_t high1 = 0U, low = 0U;
1654
1655 high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT);
1656 low = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT);
1657
1658 return (((uint32_t) high1 << 16U) | low);
1659 }
1660
1661 /**
1662 * @brief Write the time counter in RTC_ALR registers.
1663 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1664 * the configuration information for RTC.
1665 * @param AlarmCounter: Counter to write in RTC_ALR registers
1666 * @retval HAL status
1667 */
RTC_WriteAlarmCounter(RTC_HandleTypeDef * hrtc,uint32_t AlarmCounter)1668 static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef *hrtc, uint32_t AlarmCounter)
1669 {
1670 HAL_StatusTypeDef status = HAL_OK;
1671
1672 /* Set Initialization mode */
1673 if (RTC_EnterInitMode(hrtc) != HAL_OK)
1674 {
1675 status = HAL_ERROR;
1676 }
1677 else
1678 {
1679 /* Set RTC COUNTER MSB word */
1680 WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16U));
1681 /* Set RTC COUNTER LSB word */
1682 WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
1683
1684 /* Wait for synchro */
1685 if (RTC_ExitInitMode(hrtc) != HAL_OK)
1686 {
1687 status = HAL_ERROR;
1688 }
1689 }
1690
1691 return status;
1692 }
1693
1694 /**
1695 * @brief Enters the RTC Initialization mode.
1696 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1697 * the configuration information for RTC.
1698 * @retval HAL status
1699 */
RTC_EnterInitMode(RTC_HandleTypeDef * hrtc)1700 static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
1701 {
1702 uint32_t tickstart = 0U;
1703
1704 tickstart = HAL_GetTick();
1705 /* Wait till RTC is in INIT state and if Time out is reached exit */
1706 while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
1707 {
1708 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1709 {
1710 return HAL_TIMEOUT;
1711 }
1712 }
1713
1714 /* Disable the write protection for RTC registers */
1715 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1716
1717
1718 return HAL_OK;
1719 }
1720
1721 /**
1722 * @brief Exit the RTC Initialization mode.
1723 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1724 * the configuration information for RTC.
1725 * @retval HAL status
1726 */
RTC_ExitInitMode(RTC_HandleTypeDef * hrtc)1727 static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc)
1728 {
1729 uint32_t tickstart = 0U;
1730
1731 /* Disable the write protection for RTC registers */
1732 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1733
1734 tickstart = HAL_GetTick();
1735 /* Wait till RTC is in INIT state and if Time out is reached exit */
1736 while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
1737 {
1738 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1739 {
1740 return HAL_TIMEOUT;
1741 }
1742 }
1743
1744 return HAL_OK;
1745 }
1746
1747 /**
1748 * @brief Converts a 2 digit decimal to BCD format.
1749 * @param Value: Byte to be converted
1750 * @retval Converted byte
1751 */
RTC_ByteToBcd2(uint8_t Value)1752 static uint8_t RTC_ByteToBcd2(uint8_t Value)
1753 {
1754 uint32_t bcdhigh = 0U;
1755
1756 while (Value >= 10U)
1757 {
1758 bcdhigh++;
1759 Value -= 10U;
1760 }
1761
1762 return ((uint8_t)(bcdhigh << 4U) | Value);
1763 }
1764
1765 /**
1766 * @brief Converts from 2 digit BCD to Binary.
1767 * @param Value: BCD value to be converted
1768 * @retval Converted word
1769 */
RTC_Bcd2ToByte(uint8_t Value)1770 static uint8_t RTC_Bcd2ToByte(uint8_t Value)
1771 {
1772 uint32_t tmp = 0U;
1773 tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10U;
1774 return (tmp + (Value & (uint8_t)0x0F));
1775 }
1776
1777 /**
1778 * @brief Updates date when time is 23:59:59.
1779 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1780 * the configuration information for RTC.
1781 * @param DayElapsed: Number of days elapsed from last date update
1782 * @retval None
1783 */
RTC_DateUpdate(RTC_HandleTypeDef * hrtc,uint32_t DayElapsed)1784 static void RTC_DateUpdate(RTC_HandleTypeDef *hrtc, uint32_t DayElapsed)
1785 {
1786 uint32_t year = 0U, month = 0U, day = 0U;
1787 uint32_t loop = 0U;
1788
1789 /* Get the current year*/
1790 year = hrtc->DateToUpdate.Year;
1791
1792 /* Get the current month and day */
1793 month = hrtc->DateToUpdate.Month;
1794 day = hrtc->DateToUpdate.Date;
1795
1796 for (loop = 0U; loop < DayElapsed; loop++)
1797 {
1798 if ((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \
1799 (month == 8U) || (month == 10U) || (month == 12U))
1800 {
1801 if (day < 31U)
1802 {
1803 day++;
1804 }
1805 /* Date structure member: day = 31 */
1806 else
1807 {
1808 if (month != 12U)
1809 {
1810 month++;
1811 day = 1U;
1812 }
1813 /* Date structure member: day = 31 & month =12 */
1814 else
1815 {
1816 month = 1U;
1817 day = 1U;
1818 year++;
1819 }
1820 }
1821 }
1822 else if ((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U))
1823 {
1824 if (day < 30U)
1825 {
1826 day++;
1827 }
1828 /* Date structure member: day = 30 */
1829 else
1830 {
1831 month++;
1832 day = 1U;
1833 }
1834 }
1835 else if (month == 2U)
1836 {
1837 if (day < 28U)
1838 {
1839 day++;
1840 }
1841 else if (day == 28U)
1842 {
1843 /* Leap year */
1844 if (RTC_IsLeapYear(year))
1845 {
1846 day++;
1847 }
1848 else
1849 {
1850 month++;
1851 day = 1U;
1852 }
1853 }
1854 else if (day == 29U)
1855 {
1856 month++;
1857 day = 1U;
1858 }
1859 }
1860 }
1861
1862 /* Update year */
1863 hrtc->DateToUpdate.Year = year;
1864
1865 /* Update day and month */
1866 hrtc->DateToUpdate.Month = month;
1867 hrtc->DateToUpdate.Date = day;
1868
1869 /* Update day of the week */
1870 hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
1871 }
1872
1873 /**
1874 * @brief Check whether the passed year is Leap or not.
1875 * @param nYear year to check
1876 * @retval 1: leap year
1877 * 0: not leap year
1878 */
RTC_IsLeapYear(uint16_t nYear)1879 static uint8_t RTC_IsLeapYear(uint16_t nYear)
1880 {
1881 if ((nYear % 4U) != 0U)
1882 {
1883 return 0U;
1884 }
1885
1886 if ((nYear % 100U) != 0U)
1887 {
1888 return 1U;
1889 }
1890
1891 if ((nYear % 400U) == 0U)
1892 {
1893 return 1U;
1894 }
1895 else
1896 {
1897 return 0U;
1898 }
1899 }
1900
1901 /**
1902 * @brief Determines the week number, the day number and the week day number.
1903 * @param nYear year to check
1904 * @param nMonth Month to check
1905 * @param nDay Day to check
1906 * @note Day is calculated with hypothesis that year > 2000
1907 * @retval Value which can take one of the following parameters:
1908 * @arg RTC_WEEKDAY_MONDAY
1909 * @arg RTC_WEEKDAY_TUESDAY
1910 * @arg RTC_WEEKDAY_WEDNESDAY
1911 * @arg RTC_WEEKDAY_THURSDAY
1912 * @arg RTC_WEEKDAY_FRIDAY
1913 * @arg RTC_WEEKDAY_SATURDAY
1914 * @arg RTC_WEEKDAY_SUNDAY
1915 */
RTC_WeekDayNum(uint32_t nYear,uint8_t nMonth,uint8_t nDay)1916 static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
1917 {
1918 uint32_t year = 0U, weekday = 0U;
1919
1920 year = 2000U + nYear;
1921
1922 if (nMonth < 3U)
1923 {
1924 /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
1925 weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + ((year - 1U) / 4U) - ((year - 1U) / 100U) + ((year - 1U) / 400U)) % 7U;
1926 }
1927 else
1928 {
1929 /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
1930 weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + (year / 4U) - (year / 100U) + (year / 400U) - 2U) % 7U;
1931 }
1932
1933 return (uint8_t)weekday;
1934 }
1935
1936 /**
1937 * @}
1938 */
1939
1940 #endif /* HAL_RTC_MODULE_ENABLED */
1941 /**
1942 * @}
1943 */
1944
1945 /**
1946 * @}
1947 */
1948
1949 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1950