firmware-nucleo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c (58476B)
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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */
