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