STM32F103xB HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f1xx_hal_rtc.c 00004 * @author MCD Application Team 00005 * @brief RTC HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Real Time Clock (RTC) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + RTC Time and Date functions 00010 * + RTC Alarm functions 00011 * + Peripheral Control functions 00012 * + Peripheral State functions 00013 * 00014 @verbatim 00015 ============================================================================== 00016 ##### How to use this driver ##### 00017 ================================================================== 00018 [..] 00019 (+) Enable the RTC domain access (see description in the section above). 00020 (+) Configure the RTC Prescaler (Asynchronous prescaler to generate RTC 1Hz time base) 00021 using the HAL_RTC_Init() function. 00022 00023 *** Time and Date configuration *** 00024 =================================== 00025 [..] 00026 (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime() 00027 and HAL_RTC_SetDate() functions. 00028 (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions. 00029 00030 *** Alarm configuration *** 00031 =========================== 00032 [..] 00033 (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function. 00034 You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function. 00035 (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function. 00036 00037 *** Tamper configuration *** 00038 ============================ 00039 [..] 00040 (+) Enable the RTC Tamper and configure the Tamper Level using the 00041 HAL_RTCEx_SetTamper() function. You can configure RTC Tamper with interrupt 00042 mode using HAL_RTCEx_SetTamper_IT() function. 00043 (+) The TAMPER1 alternate function can be mapped to PC13 00044 00045 *** Backup Data Registers configuration *** 00046 =========================================== 00047 [..] 00048 (+) To write to the RTC Backup Data registers, use the HAL_RTCEx_BKUPWrite() 00049 function. 00050 (+) To read the RTC Backup Data registers, use the HAL_RTCEx_BKUPRead() 00051 function. 00052 00053 ##### WARNING: Drivers Restrictions ##### 00054 ================================================================== 00055 [..] RTC version used on STM32F1 families is version V1. All the features supported by V2 00056 (other families) will be not supported on F1. 00057 [..] As on V2, main RTC features are managed by HW. But on F1, date feature is completely 00058 managed by SW. 00059 [..] Then, there are some restrictions compared to other families: 00060 (+) Only format 24 hours supported in HAL (format 12 hours not supported) 00061 (+) Date is saved in SRAM. Then, when MCU is in STOP or STANDBY mode, date will be lost. 00062 User should implement a way to save date before entering in low power mode (an 00063 example is provided with firmware package based on backup registers) 00064 (+) Date is automatically updated each time a HAL_RTC_GetTime or HAL_RTC_GetDate is called. 00065 (+) Alarm detection is limited to 1 day. It will expire only 1 time (no alarm repetition, need 00066 to program a new alarm) 00067 00068 ##### Backup Domain Operating Condition ##### 00069 ============================================================================== 00070 [..] The real-time clock (RTC) and the RTC backup registers can be powered 00071 from the VBAT voltage when the main VDD supply is powered off. 00072 To retain the content of the RTC backup registers and supply the RTC 00073 when VDD is turned off, VBAT pin can be connected to an optional 00074 standby voltage supplied by a battery or by another source. 00075 00076 [..] To allow the RTC operating even when the main digital supply (VDD) is turned 00077 off, the VBAT pin powers the following blocks: 00078 (#) The RTC 00079 (#) The LSE oscillator 00080 (#) The backup SRAM when the low power backup regulator is enabled 00081 (#) PC13 to PC15 I/Os, plus PI8 I/O (when available) 00082 00083 [..] When the backup domain is supplied by VDD (analog switch connected to VDD), 00084 the following pins are available: 00085 (+) PC13 can be used as a Tamper pin 00086 00087 [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT 00088 because VDD is not present), the following pins are available: 00089 (+) PC13 can be used as the Tamper pin 00090 00091 ##### Backup Domain Reset ##### 00092 ================================================================== 00093 [..] The backup domain reset sets all RTC registers and the RCC_BDCR register 00094 to their reset values. 00095 [..] A backup domain reset is generated when one of the following events occurs: 00096 (#) Software reset, triggered by setting the BDRST bit in the 00097 RCC Backup domain control register (RCC_BDCR). 00098 (#) VDD or VBAT power on, if both supplies have previously been powered off. 00099 (#) Tamper detection event resets all data backup registers. 00100 00101 ##### Backup Domain Access ##### 00102 ================================================================== 00103 [..] After reset, the backup domain (RTC registers, RTC backup data 00104 registers and backup SRAM) is protected against possible unwanted write 00105 accesses. 00106 [..] To enable access to the RTC Domain and RTC registers, proceed as follows: 00107 (+) Call the function HAL_RCCEx_PeriphCLKConfig in using RCC_PERIPHCLK_RTC for 00108 PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSE) 00109 (+) Enable the BKP clock in using __HAL_RCC_BKP_CLK_ENABLE() 00110 00111 ##### RTC and low power modes ##### 00112 ================================================================== 00113 [..] The MCU can be woken up from a low power mode by an RTC alternate 00114 function. 00115 [..] The RTC alternate functions are the RTC alarms (Alarm A), 00116 and RTC tamper event detection. 00117 These RTC alternate functions can wake up the system from the Stop and 00118 Standby low power modes. 00119 [..] The system can also wake up from low power modes without depending 00120 on an external interrupt (Auto-wakeup mode), by using the RTC alarm. 00121 00122 *** Callback registration *** 00123 ============================================= 00124 [..] 00125 The compilation define USE_HAL_RTC_REGISTER_CALLBACKS when set to 1 00126 allows the user to configure dynamically the driver callbacks. 00127 Use Function @ref HAL_RTC_RegisterCallback() to register an interrupt callback. 00128 00129 [..] 00130 Function @ref HAL_RTC_RegisterCallback() allows to register following callbacks: 00131 (+) AlarmAEventCallback : RTC Alarm A Event callback. 00132 (+) Tamper1EventCallback : RTC Tamper 1 Event callback. 00133 (+) MspInitCallback : RTC MspInit callback. 00134 (+) MspDeInitCallback : RTC MspDeInit callback. 00135 [..] 00136 This function takes as parameters the HAL peripheral handle, the Callback ID 00137 and a pointer to the user callback function. 00138 00139 [..] 00140 Use function @ref HAL_RTC_UnRegisterCallback() to reset a callback to the default 00141 weak function. 00142 @ref HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00143 and the Callback ID. 00144 This function allows to reset following callbacks: 00145 (+) AlarmAEventCallback : RTC Alarm A Event callback. 00146 (+) Tamper1EventCallback : RTC Tamper 1 Event callback. 00147 (+) MspInitCallback : RTC MspInit callback. 00148 (+) MspDeInitCallback : RTC MspDeInit callback. 00149 [..] 00150 By default, after the @ref HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET, 00151 all callbacks are set to the corresponding weak functions : 00152 example @ref AlarmAEventCallback(). 00153 Exception done for MspInit and MspDeInit callbacks that are reset to the legacy weak function 00154 in the @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit() only when these callbacks are null 00155 (not registered beforehand). 00156 If not, MspInit or MspDeInit are not null, @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit() 00157 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) 00158 [..] 00159 Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only. 00160 Exception done MspInit/MspDeInit that can be registered/unregistered 00161 in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state, 00162 thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. 00163 In that case first register the MspInit/MspDeInit user callbacks 00164 using @ref HAL_RTC_RegisterCallback() before calling @ref HAL_RTC_DeInit() 00165 or @ref HAL_RTC_Init() function. 00166 [..] 00167 When The compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or 00168 not defined, the callback registration feature is not available and all callbacks 00169 are set to the corresponding weak functions. 00170 @endverbatim 00171 ****************************************************************************** 00172 * @attention 00173 * 00174 * <h2><center>© Copyright (c) 2016 STMicroelectronics. 00175 * All rights reserved.</center></h2> 00176 * 00177 * This software component is licensed by ST under BSD 3-Clause license, 00178 * the "License"; You may not use this file except in compliance with the 00179 * License. You may obtain a copy of the License at: 00180 * opensource.org/licenses/BSD-3-Clause 00181 * 00182 ****************************************************************************** 00183 */ 00184 00185 /* Includes ------------------------------------------------------------------*/ 00186 #include "stm32f1xx_hal.h" 00187 00188 /** @addtogroup STM32F1xx_HAL_Driver 00189 * @{ 00190 */ 00191 00192 /** @defgroup RTC RTC 00193 * @brief RTC HAL module driver 00194 * @{ 00195 */ 00196 00197 #ifdef HAL_RTC_MODULE_ENABLED 00198 00199 /* Private typedef -----------------------------------------------------------*/ 00200 /* Private define ------------------------------------------------------------*/ 00201 /** @defgroup RTC_Private_Constants RTC Private Constants 00202 * @{ 00203 */ 00204 #define RTC_ALARM_RESETVALUE_REGISTER (uint16_t)0xFFFF 00205 #define RTC_ALARM_RESETVALUE 0xFFFFFFFFU 00206 00207 /** 00208 * @} 00209 */ 00210 00211 /* Private macro -------------------------------------------------------------*/ 00212 /** @defgroup RTC_Private_Macros RTC Private Macros 00213 * @{ 00214 */ 00215 /** 00216 * @} 00217 */ 00218 00219 /* Private variables ---------------------------------------------------------*/ 00220 /* Private function prototypes -----------------------------------------------*/ 00221 /** @defgroup RTC_Private_Functions RTC Private Functions 00222 * @{ 00223 */ 00224 static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef *hrtc); 00225 static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter); 00226 static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef *hrtc); 00227 static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef *hrtc, uint32_t AlarmCounter); 00228 static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc); 00229 static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc); 00230 static uint8_t RTC_ByteToBcd2(uint8_t Value); 00231 static uint8_t RTC_Bcd2ToByte(uint8_t Value); 00232 static uint8_t RTC_IsLeapYear(uint16_t nYear); 00233 static void RTC_DateUpdate(RTC_HandleTypeDef *hrtc, uint32_t DayElapsed); 00234 static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay); 00235 00236 /** 00237 * @} 00238 */ 00239 00240 /* Private functions ---------------------------------------------------------*/ 00241 /** @defgroup RTC_Exported_Functions RTC Exported Functions 00242 * @{ 00243 */ 00244 00245 /** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions 00246 * @brief Initialization and Configuration functions 00247 * 00248 @verbatim 00249 =============================================================================== 00250 ##### Initialization and de-initialization functions ##### 00251 =============================================================================== 00252 [..] This section provides functions allowing to initialize and configure the 00253 RTC Prescaler (Asynchronous), disable RTC registers Write protection, 00254 enter and exit the RTC initialization mode, 00255 RTC registers synchronization check and reference clock detection enable. 00256 (#) The RTC Prescaler should be programmed to generate the RTC 1Hz time base. 00257 (#) All RTC registers are Write protected. Writing to the RTC registers 00258 is enabled by setting the CNF bit in the RTC_CRL register. 00259 (#) To read the calendar after wakeup from low power modes (Standby or Stop) 00260 the software must first wait for the RSF bit (Register Synchronized Flag) 00261 in the RTC_CRL register to be set by hardware. 00262 The HAL_RTC_WaitForSynchro() function implements the above software 00263 sequence (RSF clear and RSF check). 00264 00265 @endverbatim 00266 * @{ 00267 */ 00268 00269 /** 00270 * @brief Initializes the RTC peripheral 00271 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00272 * the configuration information for RTC. 00273 * @retval HAL status 00274 */ 00275 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc) 00276 { 00277 uint32_t prescaler = 0U; 00278 /* Check input parameters */ 00279 if (hrtc == NULL) 00280 { 00281 return HAL_ERROR; 00282 } 00283 00284 /* Check the parameters */ 00285 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance)); 00286 assert_param(IS_RTC_CALIB_OUTPUT(hrtc->Init.OutPut)); 00287 assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv)); 00288 00289 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) 00290 if (hrtc->State == HAL_RTC_STATE_RESET) 00291 { 00292 /* Allocate lock resource and initialize it */ 00293 hrtc->Lock = HAL_UNLOCKED; 00294 00295 hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */ 00296 hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback; /* Legacy weak Tamper1EventCallback */ 00297 00298 if (hrtc->MspInitCallback == NULL) 00299 { 00300 hrtc->MspInitCallback = HAL_RTC_MspInit; 00301 } 00302 /* Init the low level hardware */ 00303 hrtc->MspInitCallback(hrtc); 00304 00305 if (hrtc->MspDeInitCallback == NULL) 00306 { 00307 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; 00308 } 00309 } 00310 #else 00311 if (hrtc->State == HAL_RTC_STATE_RESET) 00312 { 00313 /* Allocate lock resource and initialize it */ 00314 hrtc->Lock = HAL_UNLOCKED; 00315 00316 /* Initialize RTC MSP */ 00317 HAL_RTC_MspInit(hrtc); 00318 } 00319 #endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */ 00320 00321 /* Set RTC state */ 00322 hrtc->State = HAL_RTC_STATE_BUSY; 00323 00324 /* Waiting for synchro */ 00325 if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK) 00326 { 00327 /* Set RTC state */ 00328 hrtc->State = HAL_RTC_STATE_ERROR; 00329 00330 return HAL_ERROR; 00331 } 00332 00333 /* Set Initialization mode */ 00334 if (RTC_EnterInitMode(hrtc) != HAL_OK) 00335 { 00336 /* Set RTC state */ 00337 hrtc->State = HAL_RTC_STATE_ERROR; 00338 00339 return HAL_ERROR; 00340 } 00341 else 00342 { 00343 /* Clear Flags Bits */ 00344 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_OW | RTC_FLAG_ALRAF | RTC_FLAG_SEC)); 00345 00346 if (hrtc->Init.OutPut != RTC_OUTPUTSOURCE_NONE) 00347 { 00348 /* Disable the selected Tamper pin */ 00349 CLEAR_BIT(BKP->CR, BKP_CR_TPE); 00350 } 00351 00352 /* Set the signal which will be routed to RTC Tamper pin*/ 00353 MODIFY_REG(BKP->RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), hrtc->Init.OutPut); 00354 00355 if (hrtc->Init.AsynchPrediv != RTC_AUTO_1_SECOND) 00356 { 00357 /* RTC Prescaler provided directly by end-user*/ 00358 prescaler = hrtc->Init.AsynchPrediv; 00359 } 00360 else 00361 { 00362 /* RTC Prescaler will be automatically calculated to get 1 second timebase */ 00363 /* Get the RTCCLK frequency */ 00364 prescaler = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC); 00365 00366 /* Check that RTC clock is enabled*/ 00367 if (prescaler == 0U) 00368 { 00369 /* Should not happen. Frequency is not available*/ 00370 hrtc->State = HAL_RTC_STATE_ERROR; 00371 return HAL_ERROR; 00372 } 00373 else 00374 { 00375 /* RTC period = RTCCLK/(RTC_PR + 1) */ 00376 prescaler = prescaler - 1U; 00377 } 00378 } 00379 00380 /* Configure the RTC_PRLH / RTC_PRLL */ 00381 MODIFY_REG(hrtc->Instance->PRLH, RTC_PRLH_PRL, (prescaler >> 16U)); 00382 MODIFY_REG(hrtc->Instance->PRLL, RTC_PRLL_PRL, (prescaler & RTC_PRLL_PRL)); 00383 00384 /* Wait for synchro */ 00385 if (RTC_ExitInitMode(hrtc) != HAL_OK) 00386 { 00387 hrtc->State = HAL_RTC_STATE_ERROR; 00388 00389 return HAL_ERROR; 00390 } 00391 00392 /* Initialize date to 1st of January 2000 */ 00393 hrtc->DateToUpdate.Year = 0x00U; 00394 hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY; 00395 hrtc->DateToUpdate.Date = 0x01U; 00396 00397 /* Set RTC state */ 00398 hrtc->State = HAL_RTC_STATE_READY; 00399 00400 return HAL_OK; 00401 } 00402 } 00403 00404 /** 00405 * @brief DeInitializes the RTC peripheral 00406 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00407 * the configuration information for RTC. 00408 * @note This function does not reset the RTC Backup Data registers. 00409 * @retval HAL status 00410 */ 00411 HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc) 00412 { 00413 /* Check input parameters */ 00414 if (hrtc == NULL) 00415 { 00416 return HAL_ERROR; 00417 } 00418 00419 /* Check the parameters */ 00420 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance)); 00421 00422 /* Set RTC state */ 00423 hrtc->State = HAL_RTC_STATE_BUSY; 00424 00425 /* Set Initialization mode */ 00426 if (RTC_EnterInitMode(hrtc) != HAL_OK) 00427 { 00428 /* Set RTC state */ 00429 hrtc->State = HAL_RTC_STATE_ERROR; 00430 00431 /* Release Lock */ 00432 __HAL_UNLOCK(hrtc); 00433 00434 return HAL_ERROR; 00435 } 00436 else 00437 { 00438 CLEAR_REG(hrtc->Instance->CNTL); 00439 CLEAR_REG(hrtc->Instance->CNTH); 00440 WRITE_REG(hrtc->Instance->PRLL, 0x00008000U); 00441 CLEAR_REG(hrtc->Instance->PRLH); 00442 00443 /* Reset All CRH/CRL bits */ 00444 CLEAR_REG(hrtc->Instance->CRH); 00445 CLEAR_REG(hrtc->Instance->CRL); 00446 00447 if (RTC_ExitInitMode(hrtc) != HAL_OK) 00448 { 00449 hrtc->State = HAL_RTC_STATE_ERROR; 00450 00451 /* Process Unlocked */ 00452 __HAL_UNLOCK(hrtc); 00453 00454 return HAL_ERROR; 00455 } 00456 } 00457 00458 /* Wait for synchro*/ 00459 HAL_RTC_WaitForSynchro(hrtc); 00460 00461 /* Clear RSF flag */ 00462 CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF); 00463 00464 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) 00465 if (hrtc->MspDeInitCallback == NULL) 00466 { 00467 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; 00468 } 00469 00470 /* DeInit the low level hardware: CLOCK, NVIC.*/ 00471 hrtc->MspDeInitCallback(hrtc); 00472 00473 #else 00474 /* De-Initialize RTC MSP */ 00475 HAL_RTC_MspDeInit(hrtc); 00476 #endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */ 00477 00478 hrtc->State = HAL_RTC_STATE_RESET; 00479 00480 /* Release Lock */ 00481 __HAL_UNLOCK(hrtc); 00482 00483 return HAL_OK; 00484 } 00485 00486 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) 00487 /** 00488 * @brief Register a User RTC Callback 00489 * To be used instead of the weak predefined callback 00490 * @param hrtc RTC handle 00491 * @param CallbackID ID of the callback to be registered 00492 * This parameter can be one of the following values: 00493 * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID 00494 * @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID 00495 * @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID 00496 * @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID 00497 * @param pCallback pointer to the Callback function 00498 * @retval HAL status 00499 */ 00500 HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, pRTC_CallbackTypeDef pCallback) 00501 { 00502 HAL_StatusTypeDef status = HAL_OK; 00503 00504 if (pCallback == NULL) 00505 { 00506 return HAL_ERROR; 00507 } 00508 00509 /* Process locked */ 00510 __HAL_LOCK(hrtc); 00511 00512 if (HAL_RTC_STATE_READY == hrtc->State) 00513 { 00514 switch (CallbackID) 00515 { 00516 case HAL_RTC_ALARM_A_EVENT_CB_ID : 00517 hrtc->AlarmAEventCallback = pCallback; 00518 break; 00519 00520 case HAL_RTC_TAMPER1_EVENT_CB_ID : 00521 hrtc->Tamper1EventCallback = pCallback; 00522 break; 00523 00524 case HAL_RTC_MSPINIT_CB_ID : 00525 hrtc->MspInitCallback = pCallback; 00526 break; 00527 00528 case HAL_RTC_MSPDEINIT_CB_ID : 00529 hrtc->MspDeInitCallback = pCallback; 00530 break; 00531 00532 default : 00533 /* Return error status */ 00534 status = HAL_ERROR; 00535 break; 00536 } 00537 } 00538 else if (HAL_RTC_STATE_RESET == hrtc->State) 00539 { 00540 switch (CallbackID) 00541 { 00542 case HAL_RTC_MSPINIT_CB_ID : 00543 hrtc->MspInitCallback = pCallback; 00544 break; 00545 00546 case HAL_RTC_MSPDEINIT_CB_ID : 00547 hrtc->MspDeInitCallback = pCallback; 00548 break; 00549 00550 default : 00551 /* Return error status */ 00552 status = HAL_ERROR; 00553 break; 00554 } 00555 } 00556 else 00557 { 00558 /* Return error status */ 00559 status = HAL_ERROR; 00560 } 00561 00562 /* Release Lock */ 00563 __HAL_UNLOCK(hrtc); 00564 00565 return status; 00566 } 00567 00568 /** 00569 * @brief Unregister an RTC Callback 00570 * RTC callabck is redirected to the weak predefined callback 00571 * @param hrtc RTC handle 00572 * @param CallbackID ID of the callback to be unregistered 00573 * This parameter can be one of the following values: 00574 * @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID 00575 * @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID 00576 * @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID 00577 * @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID 00578 * @retval HAL status 00579 */ 00580 HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID) 00581 { 00582 HAL_StatusTypeDef status = HAL_OK; 00583 00584 /* Process locked */ 00585 __HAL_LOCK(hrtc); 00586 00587 if (HAL_RTC_STATE_READY == hrtc->State) 00588 { 00589 switch (CallbackID) 00590 { 00591 case HAL_RTC_ALARM_A_EVENT_CB_ID : 00592 hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */ 00593 break; 00594 00595 case HAL_RTC_TAMPER1_EVENT_CB_ID : 00596 hrtc->Tamper1EventCallback = HAL_RTCEx_Tamper1EventCallback; /* Legacy weak Tamper1EventCallback */ 00597 break; 00598 00599 case HAL_RTC_MSPINIT_CB_ID : 00600 hrtc->MspInitCallback = HAL_RTC_MspInit; 00601 break; 00602 00603 case HAL_RTC_MSPDEINIT_CB_ID : 00604 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; 00605 break; 00606 00607 default : 00608 /* Return error status */ 00609 status = HAL_ERROR; 00610 break; 00611 } 00612 } 00613 else if (HAL_RTC_STATE_RESET == hrtc->State) 00614 { 00615 switch (CallbackID) 00616 { 00617 case HAL_RTC_MSPINIT_CB_ID : 00618 hrtc->MspInitCallback = HAL_RTC_MspInit; 00619 break; 00620 00621 case HAL_RTC_MSPDEINIT_CB_ID : 00622 hrtc->MspDeInitCallback = HAL_RTC_MspDeInit; 00623 break; 00624 00625 default : 00626 /* Return error status */ 00627 status = HAL_ERROR; 00628 break; 00629 } 00630 } 00631 else 00632 { 00633 /* Return error status */ 00634 status = HAL_ERROR; 00635 } 00636 00637 /* Release Lock */ 00638 __HAL_UNLOCK(hrtc); 00639 00640 return status; 00641 } 00642 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ 00643 00644 /** 00645 * @brief Initializes the RTC MSP. 00646 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00647 * the configuration information for RTC. 00648 * @retval None 00649 */ 00650 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc) 00651 { 00652 /* Prevent unused argument(s) compilation warning */ 00653 UNUSED(hrtc); 00654 /* NOTE : This function Should not be modified, when the callback is needed, 00655 the HAL_RTC_MspInit could be implemented in the user file 00656 */ 00657 } 00658 00659 /** 00660 * @brief DeInitializes the RTC MSP. 00661 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00662 * the configuration information for RTC. 00663 * @retval None 00664 */ 00665 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc) 00666 { 00667 /* Prevent unused argument(s) compilation warning */ 00668 UNUSED(hrtc); 00669 /* NOTE : This function Should not be modified, when the callback is needed, 00670 the HAL_RTC_MspDeInit could be implemented in the user file 00671 */ 00672 } 00673 00674 /** 00675 * @} 00676 */ 00677 00678 /** @defgroup RTC_Exported_Functions_Group2 Time and Date functions 00679 * @brief RTC Time and Date functions 00680 * 00681 @verbatim 00682 =============================================================================== 00683 ##### RTC Time and Date functions ##### 00684 =============================================================================== 00685 00686 [..] This section provides functions allowing to configure Time and Date features 00687 00688 @endverbatim 00689 * @{ 00690 */ 00691 00692 /** 00693 * @brief Sets RTC current time. 00694 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00695 * the configuration information for RTC. 00696 * @param sTime: Pointer to Time structure 00697 * @param Format: Specifies the format of the entered parameters. 00698 * This parameter can be one of the following values: 00699 * @arg RTC_FORMAT_BIN: Binary data format 00700 * @arg RTC_FORMAT_BCD: BCD data format 00701 * @retval HAL status 00702 */ 00703 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) 00704 { 00705 uint32_t counter_time = 0U, counter_alarm = 0U; 00706 00707 /* Check input parameters */ 00708 if ((hrtc == NULL) || (sTime == NULL)) 00709 { 00710 return HAL_ERROR; 00711 } 00712 00713 /* Check the parameters */ 00714 assert_param(IS_RTC_FORMAT(Format)); 00715 00716 /* Process Locked */ 00717 __HAL_LOCK(hrtc); 00718 00719 hrtc->State = HAL_RTC_STATE_BUSY; 00720 00721 if (Format == RTC_FORMAT_BIN) 00722 { 00723 assert_param(IS_RTC_HOUR24(sTime->Hours)); 00724 assert_param(IS_RTC_MINUTES(sTime->Minutes)); 00725 assert_param(IS_RTC_SECONDS(sTime->Seconds)); 00726 00727 counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600U) + \ 00728 ((uint32_t)sTime->Minutes * 60U) + \ 00729 ((uint32_t)sTime->Seconds)); 00730 } 00731 else 00732 { 00733 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours))); 00734 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes))); 00735 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds))); 00736 00737 counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600U) + \ 00738 ((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60U) + \ 00739 ((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds)))); 00740 } 00741 00742 /* Write time counter in RTC registers */ 00743 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK) 00744 { 00745 /* Set RTC state */ 00746 hrtc->State = HAL_RTC_STATE_ERROR; 00747 00748 /* Process Unlocked */ 00749 __HAL_UNLOCK(hrtc); 00750 00751 return HAL_ERROR; 00752 } 00753 else 00754 { 00755 /* Clear Second and overflow flags */ 00756 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW)); 00757 00758 /* Read current Alarm counter in RTC registers */ 00759 counter_alarm = RTC_ReadAlarmCounter(hrtc); 00760 00761 /* Set again alarm to match with new time if enabled */ 00762 if (counter_alarm != RTC_ALARM_RESETVALUE) 00763 { 00764 if (counter_alarm < counter_time) 00765 { 00766 /* Add 1 day to alarm counter*/ 00767 counter_alarm += (uint32_t)(24U * 3600U); 00768 00769 /* Write new Alarm counter in RTC registers */ 00770 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK) 00771 { 00772 /* Set RTC state */ 00773 hrtc->State = HAL_RTC_STATE_ERROR; 00774 00775 /* Process Unlocked */ 00776 __HAL_UNLOCK(hrtc); 00777 00778 return HAL_ERROR; 00779 } 00780 } 00781 } 00782 00783 hrtc->State = HAL_RTC_STATE_READY; 00784 00785 __HAL_UNLOCK(hrtc); 00786 00787 return HAL_OK; 00788 } 00789 } 00790 00791 /** 00792 * @brief Gets RTC current time. 00793 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00794 * the configuration information for RTC. 00795 * @param sTime: Pointer to Time structure 00796 * @param Format: Specifies the format of the entered parameters. 00797 * This parameter can be one of the following values: 00798 * @arg RTC_FORMAT_BIN: Binary data format 00799 * @arg RTC_FORMAT_BCD: BCD data format 00800 * @retval HAL status 00801 */ 00802 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format) 00803 { 00804 uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U; 00805 00806 /* Check input parameters */ 00807 if ((hrtc == NULL) || (sTime == NULL)) 00808 { 00809 return HAL_ERROR; 00810 } 00811 00812 /* Check the parameters */ 00813 assert_param(IS_RTC_FORMAT(Format)); 00814 00815 /* Check if counter overflow occurred */ 00816 if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW)) 00817 { 00818 return HAL_ERROR; 00819 } 00820 00821 /* Read the time counter*/ 00822 counter_time = RTC_ReadTimeCounter(hrtc); 00823 00824 /* Fill the structure fields with the read parameters */ 00825 hours = counter_time / 3600U; 00826 sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U); 00827 sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U); 00828 00829 if (hours >= 24U) 00830 { 00831 /* Get number of days elapsed from last calculation */ 00832 days_elapsed = (hours / 24U); 00833 00834 /* Set Hours in RTC_TimeTypeDef structure*/ 00835 sTime->Hours = (hours % 24U); 00836 00837 /* Read Alarm counter in RTC registers */ 00838 counter_alarm = RTC_ReadAlarmCounter(hrtc); 00839 00840 /* Calculate remaining time to reach alarm (only if set and not yet expired)*/ 00841 if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time)) 00842 { 00843 counter_alarm -= counter_time; 00844 } 00845 else 00846 { 00847 /* In case of counter_alarm < counter_time */ 00848 /* Alarm expiration already occurred but alarm not deactivated */ 00849 counter_alarm = RTC_ALARM_RESETVALUE; 00850 } 00851 00852 /* Set updated time in decreasing counter by number of days elapsed */ 00853 counter_time -= (days_elapsed * 24U * 3600U); 00854 00855 /* Write time counter in RTC registers */ 00856 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK) 00857 { 00858 return HAL_ERROR; 00859 } 00860 00861 /* Set updated alarm to be set */ 00862 if (counter_alarm != RTC_ALARM_RESETVALUE) 00863 { 00864 counter_alarm += counter_time; 00865 00866 /* Write time counter in RTC registers */ 00867 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK) 00868 { 00869 return HAL_ERROR; 00870 } 00871 } 00872 else 00873 { 00874 /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */ 00875 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK) 00876 { 00877 return HAL_ERROR; 00878 } 00879 } 00880 00881 /* Update date */ 00882 RTC_DateUpdate(hrtc, days_elapsed); 00883 } 00884 else 00885 { 00886 sTime->Hours = hours; 00887 } 00888 00889 /* Check the input parameters format */ 00890 if (Format != RTC_FORMAT_BIN) 00891 { 00892 /* Convert the time structure parameters to BCD format */ 00893 sTime->Hours = (uint8_t)RTC_ByteToBcd2(sTime->Hours); 00894 sTime->Minutes = (uint8_t)RTC_ByteToBcd2(sTime->Minutes); 00895 sTime->Seconds = (uint8_t)RTC_ByteToBcd2(sTime->Seconds); 00896 } 00897 00898 return HAL_OK; 00899 } 00900 00901 00902 /** 00903 * @brief Sets RTC current date. 00904 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 00905 * the configuration information for RTC. 00906 * @param sDate: Pointer to date structure 00907 * @param Format: specifies the format of the entered parameters. 00908 * This parameter can be one of the following values: 00909 * @arg RTC_FORMAT_BIN: Binary data format 00910 * @arg RTC_FORMAT_BCD: BCD data format 00911 * @retval HAL status 00912 */ 00913 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) 00914 { 00915 uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U; 00916 00917 /* Check input parameters */ 00918 if ((hrtc == NULL) || (sDate == NULL)) 00919 { 00920 return HAL_ERROR; 00921 } 00922 00923 /* Check the parameters */ 00924 assert_param(IS_RTC_FORMAT(Format)); 00925 00926 /* Process Locked */ 00927 __HAL_LOCK(hrtc); 00928 00929 hrtc->State = HAL_RTC_STATE_BUSY; 00930 00931 if (Format == RTC_FORMAT_BIN) 00932 { 00933 assert_param(IS_RTC_YEAR(sDate->Year)); 00934 assert_param(IS_RTC_MONTH(sDate->Month)); 00935 assert_param(IS_RTC_DATE(sDate->Date)); 00936 00937 /* Change the current date */ 00938 hrtc->DateToUpdate.Year = sDate->Year; 00939 hrtc->DateToUpdate.Month = sDate->Month; 00940 hrtc->DateToUpdate.Date = sDate->Date; 00941 } 00942 else 00943 { 00944 assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year))); 00945 assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month))); 00946 assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date))); 00947 00948 /* Change the current date */ 00949 hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year); 00950 hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month); 00951 hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date); 00952 } 00953 00954 /* WeekDay set by user can be ignored because automatically calculated */ 00955 hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date); 00956 sDate->WeekDay = hrtc->DateToUpdate.WeekDay; 00957 00958 /* Reset time to be aligned on the same day */ 00959 /* Read the time counter*/ 00960 counter_time = RTC_ReadTimeCounter(hrtc); 00961 00962 /* Fill the structure fields with the read parameters */ 00963 hours = counter_time / 3600U; 00964 if (hours > 24U) 00965 { 00966 /* Set updated time in decreasing counter by number of days elapsed */ 00967 counter_time -= ((hours / 24U) * 24U * 3600U); 00968 /* Write time counter in RTC registers */ 00969 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK) 00970 { 00971 /* Set RTC state */ 00972 hrtc->State = HAL_RTC_STATE_ERROR; 00973 00974 /* Process Unlocked */ 00975 __HAL_UNLOCK(hrtc); 00976 00977 return HAL_ERROR; 00978 } 00979 00980 /* Read current Alarm counter in RTC registers */ 00981 counter_alarm = RTC_ReadAlarmCounter(hrtc); 00982 00983 /* Set again alarm to match with new time if enabled */ 00984 if (counter_alarm != RTC_ALARM_RESETVALUE) 00985 { 00986 if (counter_alarm < counter_time) 00987 { 00988 /* Add 1 day to alarm counter*/ 00989 counter_alarm += (uint32_t)(24U * 3600U); 00990 00991 /* Write new Alarm counter in RTC registers */ 00992 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK) 00993 { 00994 /* Set RTC state */ 00995 hrtc->State = HAL_RTC_STATE_ERROR; 00996 00997 /* Process Unlocked */ 00998 __HAL_UNLOCK(hrtc); 00999 01000 return HAL_ERROR; 01001 } 01002 } 01003 } 01004 01005 01006 } 01007 01008 hrtc->State = HAL_RTC_STATE_READY ; 01009 01010 /* Process Unlocked */ 01011 __HAL_UNLOCK(hrtc); 01012 01013 return HAL_OK; 01014 } 01015 01016 /** 01017 * @brief Gets RTC current date. 01018 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01019 * the configuration information for RTC. 01020 * @param sDate: Pointer to Date structure 01021 * @param Format: Specifies the format of the entered parameters. 01022 * This parameter can be one of the following values: 01023 * @arg RTC_FORMAT_BIN: Binary data format 01024 * @arg RTC_FORMAT_BCD: BCD data format 01025 * @retval HAL status 01026 */ 01027 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format) 01028 { 01029 RTC_TimeTypeDef stime = {0U}; 01030 01031 /* Check input parameters */ 01032 if ((hrtc == NULL) || (sDate == NULL)) 01033 { 01034 return HAL_ERROR; 01035 } 01036 01037 /* Check the parameters */ 01038 assert_param(IS_RTC_FORMAT(Format)); 01039 01040 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */ 01041 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK) 01042 { 01043 return HAL_ERROR; 01044 } 01045 01046 /* Fill the structure fields with the read parameters */ 01047 sDate->WeekDay = hrtc->DateToUpdate.WeekDay; 01048 sDate->Year = hrtc->DateToUpdate.Year; 01049 sDate->Month = hrtc->DateToUpdate.Month; 01050 sDate->Date = hrtc->DateToUpdate.Date; 01051 01052 /* Check the input parameters format */ 01053 if (Format != RTC_FORMAT_BIN) 01054 { 01055 /* Convert the date structure parameters to BCD format */ 01056 sDate->Year = (uint8_t)RTC_ByteToBcd2(sDate->Year); 01057 sDate->Month = (uint8_t)RTC_ByteToBcd2(sDate->Month); 01058 sDate->Date = (uint8_t)RTC_ByteToBcd2(sDate->Date); 01059 } 01060 return HAL_OK; 01061 } 01062 01063 /** 01064 * @} 01065 */ 01066 01067 /** @defgroup RTC_Exported_Functions_Group3 Alarm functions 01068 * @brief RTC Alarm functions 01069 * 01070 @verbatim 01071 =============================================================================== 01072 ##### RTC Alarm functions ##### 01073 =============================================================================== 01074 01075 [..] This section provides functions allowing to configure Alarm feature 01076 01077 @endverbatim 01078 * @{ 01079 */ 01080 01081 /** 01082 * @brief Sets the specified RTC Alarm. 01083 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01084 * the configuration information for RTC. 01085 * @param sAlarm: Pointer to Alarm structure 01086 * @param Format: Specifies the format of the entered parameters. 01087 * This parameter can be one of the following values: 01088 * @arg RTC_FORMAT_BIN: Binary data format 01089 * @arg RTC_FORMAT_BCD: BCD data format 01090 * @retval HAL status 01091 */ 01092 HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format) 01093 { 01094 uint32_t counter_alarm = 0U, counter_time; 01095 RTC_TimeTypeDef stime = {0U}; 01096 01097 /* Check input parameters */ 01098 if ((hrtc == NULL) || (sAlarm == NULL)) 01099 { 01100 return HAL_ERROR; 01101 } 01102 01103 /* Check the parameters */ 01104 assert_param(IS_RTC_FORMAT(Format)); 01105 assert_param(IS_RTC_ALARM(sAlarm->Alarm)); 01106 01107 /* Process Locked */ 01108 __HAL_LOCK(hrtc); 01109 01110 hrtc->State = HAL_RTC_STATE_BUSY; 01111 01112 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */ 01113 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK) 01114 { 01115 return HAL_ERROR; 01116 } 01117 01118 /* Convert time in seconds */ 01119 counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \ 01120 ((uint32_t)stime.Minutes * 60U) + \ 01121 ((uint32_t)stime.Seconds)); 01122 01123 if (Format == RTC_FORMAT_BIN) 01124 { 01125 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours)); 01126 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes)); 01127 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds)); 01128 01129 counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \ 01130 ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \ 01131 ((uint32_t)sAlarm->AlarmTime.Seconds)); 01132 } 01133 else 01134 { 01135 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); 01136 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes))); 01137 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); 01138 01139 counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \ 01140 ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \ 01141 ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); 01142 } 01143 01144 /* Check that requested alarm should expire in the same day (otherwise add 1 day) */ 01145 if (counter_alarm < counter_time) 01146 { 01147 /* Add 1 day to alarm counter*/ 01148 counter_alarm += (uint32_t)(24U * 3600U); 01149 } 01150 01151 /* Write Alarm counter in RTC registers */ 01152 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK) 01153 { 01154 /* Set RTC state */ 01155 hrtc->State = HAL_RTC_STATE_ERROR; 01156 01157 /* Process Unlocked */ 01158 __HAL_UNLOCK(hrtc); 01159 01160 return HAL_ERROR; 01161 } 01162 else 01163 { 01164 hrtc->State = HAL_RTC_STATE_READY; 01165 01166 __HAL_UNLOCK(hrtc); 01167 01168 return HAL_OK; 01169 } 01170 } 01171 01172 /** 01173 * @brief Sets the specified RTC Alarm with Interrupt 01174 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01175 * the configuration information for RTC. 01176 * @param sAlarm: Pointer to Alarm structure 01177 * @param Format: Specifies the format of the entered parameters. 01178 * This parameter can be one of the following values: 01179 * @arg RTC_FORMAT_BIN: Binary data format 01180 * @arg RTC_FORMAT_BCD: BCD data format 01181 * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature. 01182 * @retval HAL status 01183 */ 01184 HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format) 01185 { 01186 uint32_t counter_alarm = 0U, counter_time; 01187 RTC_TimeTypeDef stime = {0U}; 01188 01189 /* Check input parameters */ 01190 if ((hrtc == NULL) || (sAlarm == NULL)) 01191 { 01192 return HAL_ERROR; 01193 } 01194 01195 /* Check the parameters */ 01196 assert_param(IS_RTC_FORMAT(Format)); 01197 assert_param(IS_RTC_ALARM(sAlarm->Alarm)); 01198 01199 /* Process Locked */ 01200 __HAL_LOCK(hrtc); 01201 01202 hrtc->State = HAL_RTC_STATE_BUSY; 01203 01204 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */ 01205 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK) 01206 { 01207 return HAL_ERROR; 01208 } 01209 01210 /* Convert time in seconds */ 01211 counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \ 01212 ((uint32_t)stime.Minutes * 60U) + \ 01213 ((uint32_t)stime.Seconds)); 01214 01215 if (Format == RTC_FORMAT_BIN) 01216 { 01217 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours)); 01218 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes)); 01219 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds)); 01220 01221 counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \ 01222 ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \ 01223 ((uint32_t)sAlarm->AlarmTime.Seconds)); 01224 } 01225 else 01226 { 01227 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours))); 01228 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes))); 01229 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); 01230 01231 counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \ 01232 ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \ 01233 ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds))); 01234 } 01235 01236 /* Check that requested alarm should expire in the same day (otherwise add 1 day) */ 01237 if (counter_alarm < counter_time) 01238 { 01239 /* Add 1 day to alarm counter*/ 01240 counter_alarm += (uint32_t)(24U * 3600U); 01241 } 01242 01243 /* Write alarm counter in RTC registers */ 01244 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK) 01245 { 01246 /* Set RTC state */ 01247 hrtc->State = HAL_RTC_STATE_ERROR; 01248 01249 /* Process Unlocked */ 01250 __HAL_UNLOCK(hrtc); 01251 01252 return HAL_ERROR; 01253 } 01254 else 01255 { 01256 /* Clear flag alarm A */ 01257 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); 01258 01259 /* Configure the Alarm interrupt */ 01260 __HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRA); 01261 01262 /* RTC Alarm Interrupt Configuration: EXTI configuration */ 01263 __HAL_RTC_ALARM_EXTI_ENABLE_IT(); 01264 01265 __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE(); 01266 01267 hrtc->State = HAL_RTC_STATE_READY; 01268 01269 __HAL_UNLOCK(hrtc); 01270 01271 return HAL_OK; 01272 } 01273 } 01274 01275 /** 01276 * @brief Gets the RTC Alarm value and masks. 01277 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01278 * the configuration information for RTC. 01279 * @param sAlarm: Pointer to Date structure 01280 * @param Alarm: Specifies the Alarm. 01281 * This parameter can be one of the following values: 01282 * @arg RTC_ALARM_A: Alarm 01283 * @param Format: Specifies the format of the entered parameters. 01284 * This parameter can be one of the following values: 01285 * @arg RTC_FORMAT_BIN: Binary data format 01286 * @arg RTC_FORMAT_BCD: BCD data format 01287 * @retval HAL status 01288 */ 01289 HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format) 01290 { 01291 uint32_t counter_alarm = 0U; 01292 01293 /* Prevent unused argument(s) compilation warning */ 01294 UNUSED(Alarm); 01295 01296 /* Check input parameters */ 01297 if ((hrtc == NULL) || (sAlarm == NULL)) 01298 { 01299 return HAL_ERROR; 01300 } 01301 01302 /* Check the parameters */ 01303 assert_param(IS_RTC_FORMAT(Format)); 01304 assert_param(IS_RTC_ALARM(Alarm)); 01305 01306 /* Read Alarm counter in RTC registers */ 01307 counter_alarm = RTC_ReadAlarmCounter(hrtc); 01308 01309 /* Fill the structure with the read parameters */ 01310 /* Set hours in a day range (between 0 to 24)*/ 01311 sAlarm->AlarmTime.Hours = (uint32_t)((counter_alarm / 3600U) % 24U); 01312 sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600U) / 60U); 01313 sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600U) % 60U); 01314 01315 if (Format != RTC_FORMAT_BIN) 01316 { 01317 sAlarm->AlarmTime.Hours = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours); 01318 sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes); 01319 sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds); 01320 } 01321 01322 return HAL_OK; 01323 } 01324 01325 /** 01326 * @brief Deactive the specified RTC Alarm 01327 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01328 * the configuration information for RTC. 01329 * @param Alarm: Specifies the Alarm. 01330 * This parameter can be one of the following values: 01331 * @arg RTC_ALARM_A: AlarmA 01332 * @retval HAL status 01333 */ 01334 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm) 01335 { 01336 /* Prevent unused argument(s) compilation warning */ 01337 UNUSED(Alarm); 01338 01339 /* Check the parameters */ 01340 assert_param(IS_RTC_ALARM(Alarm)); 01341 01342 /* Check input parameters */ 01343 if (hrtc == NULL) 01344 { 01345 return HAL_ERROR; 01346 } 01347 01348 /* Process Locked */ 01349 __HAL_LOCK(hrtc); 01350 01351 hrtc->State = HAL_RTC_STATE_BUSY; 01352 01353 /* In case of interrupt mode is used, the interrupt source must disabled */ 01354 __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA); 01355 01356 /* Set Initialization mode */ 01357 if (RTC_EnterInitMode(hrtc) != HAL_OK) 01358 { 01359 /* Set RTC state */ 01360 hrtc->State = HAL_RTC_STATE_ERROR; 01361 01362 /* Process Unlocked */ 01363 __HAL_UNLOCK(hrtc); 01364 01365 return HAL_ERROR; 01366 } 01367 else 01368 { 01369 /* Clear flag alarm A */ 01370 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); 01371 01372 /* Set to default values ALRH & ALRL registers */ 01373 WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER); 01374 WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER); 01375 01376 /* RTC Alarm Interrupt Configuration: Disable EXTI configuration */ 01377 __HAL_RTC_ALARM_EXTI_DISABLE_IT(); 01378 01379 /* Wait for synchro */ 01380 if (RTC_ExitInitMode(hrtc) != HAL_OK) 01381 { 01382 hrtc->State = HAL_RTC_STATE_ERROR; 01383 01384 /* Process Unlocked */ 01385 __HAL_UNLOCK(hrtc); 01386 01387 return HAL_ERROR; 01388 } 01389 } 01390 hrtc->State = HAL_RTC_STATE_READY; 01391 01392 /* Process Unlocked */ 01393 __HAL_UNLOCK(hrtc); 01394 01395 return HAL_OK; 01396 } 01397 01398 /** 01399 * @brief This function handles Alarm interrupt request. 01400 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01401 * the configuration information for RTC. 01402 * @retval None 01403 */ 01404 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc) 01405 { 01406 if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA)) 01407 { 01408 /* Get the status of the Interrupt */ 01409 if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET) 01410 { 01411 /* AlarmA callback */ 01412 #if (USE_HAL_RTC_REGISTER_CALLBACKS == 1) 01413 hrtc->AlarmAEventCallback(hrtc); 01414 #else 01415 HAL_RTC_AlarmAEventCallback(hrtc); 01416 #endif /* USE_HAL_RTC_REGISTER_CALLBACKS */ 01417 01418 /* Clear the Alarm interrupt pending bit */ 01419 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); 01420 } 01421 } 01422 01423 /* Clear the EXTI's line Flag for RTC Alarm */ 01424 __HAL_RTC_ALARM_EXTI_CLEAR_FLAG(); 01425 01426 /* Change RTC state */ 01427 hrtc->State = HAL_RTC_STATE_READY; 01428 } 01429 01430 /** 01431 * @brief Alarm A callback. 01432 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01433 * the configuration information for RTC. 01434 * @retval None 01435 */ 01436 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) 01437 { 01438 /* Prevent unused argument(s) compilation warning */ 01439 UNUSED(hrtc); 01440 /* NOTE : This function Should not be modified, when the callback is needed, 01441 the HAL_RTC_AlarmAEventCallback could be implemented in the user file 01442 */ 01443 } 01444 01445 /** 01446 * @brief This function handles AlarmA Polling request. 01447 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01448 * the configuration information for RTC. 01449 * @param Timeout: Timeout duration 01450 * @retval HAL status 01451 */ 01452 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout) 01453 { 01454 uint32_t tickstart = HAL_GetTick(); 01455 01456 /* Check input parameters */ 01457 if (hrtc == NULL) 01458 { 01459 return HAL_ERROR; 01460 } 01461 01462 while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET) 01463 { 01464 if (Timeout != HAL_MAX_DELAY) 01465 { 01466 if ((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) 01467 { 01468 hrtc->State = HAL_RTC_STATE_TIMEOUT; 01469 return HAL_TIMEOUT; 01470 } 01471 } 01472 } 01473 01474 /* Clear the Alarm interrupt pending bit */ 01475 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); 01476 01477 /* Change RTC state */ 01478 hrtc->State = HAL_RTC_STATE_READY; 01479 01480 return HAL_OK; 01481 } 01482 01483 /** 01484 * @} 01485 */ 01486 01487 /** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions 01488 * @brief Peripheral State functions 01489 * 01490 @verbatim 01491 =============================================================================== 01492 ##### Peripheral State functions ##### 01493 =============================================================================== 01494 [..] 01495 This subsection provides functions allowing to 01496 (+) Get RTC state 01497 01498 @endverbatim 01499 * @{ 01500 */ 01501 /** 01502 * @brief Returns the RTC state. 01503 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01504 * the configuration information for RTC. 01505 * @retval HAL state 01506 */ 01507 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc) 01508 { 01509 return hrtc->State; 01510 } 01511 01512 /** 01513 * @} 01514 */ 01515 01516 /** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions 01517 * @brief Peripheral Control functions 01518 * 01519 @verbatim 01520 =============================================================================== 01521 ##### Peripheral Control functions ##### 01522 =============================================================================== 01523 [..] 01524 This subsection provides functions allowing to 01525 (+) Wait for RTC Time and Date Synchronization 01526 01527 @endverbatim 01528 * @{ 01529 */ 01530 01531 /** 01532 * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL) 01533 * are synchronized with RTC APB clock. 01534 * @note This function must be called before any read operation after an APB reset 01535 * or an APB clock stop. 01536 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01537 * the configuration information for RTC. 01538 * @retval HAL status 01539 */ 01540 HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc) 01541 { 01542 uint32_t tickstart = 0U; 01543 01544 /* Check input parameters */ 01545 if (hrtc == NULL) 01546 { 01547 return HAL_ERROR; 01548 } 01549 01550 /* Clear RSF flag */ 01551 CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF); 01552 01553 tickstart = HAL_GetTick(); 01554 01555 /* Wait the registers to be synchronised */ 01556 while ((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET) 01557 { 01558 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) 01559 { 01560 return HAL_TIMEOUT; 01561 } 01562 } 01563 01564 return HAL_OK; 01565 } 01566 01567 /** 01568 * @} 01569 */ 01570 01571 01572 /** 01573 * @} 01574 */ 01575 01576 /** @addtogroup RTC_Private_Functions 01577 * @{ 01578 */ 01579 01580 01581 /** 01582 * @brief Read the time counter available in RTC_CNT registers. 01583 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01584 * the configuration information for RTC. 01585 * @retval Time counter 01586 */ 01587 static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef *hrtc) 01588 { 01589 uint16_t high1 = 0U, high2 = 0U, low = 0U; 01590 uint32_t timecounter = 0U; 01591 01592 high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT); 01593 low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT); 01594 high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT); 01595 01596 if (high1 != high2) 01597 { 01598 /* In this case the counter roll over during reading of CNTL and CNTH registers, 01599 read again CNTL register then return the counter value */ 01600 timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT)); 01601 } 01602 else 01603 { 01604 /* No counter roll over during reading of CNTL and CNTH registers, counter 01605 value is equal to first value of CNTL and CNTH */ 01606 timecounter = (((uint32_t) high1 << 16U) | low); 01607 } 01608 01609 return timecounter; 01610 } 01611 01612 /** 01613 * @brief Write the time counter in RTC_CNT registers. 01614 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01615 * the configuration information for RTC. 01616 * @param TimeCounter: Counter to write in RTC_CNT registers 01617 * @retval HAL status 01618 */ 01619 static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter) 01620 { 01621 HAL_StatusTypeDef status = HAL_OK; 01622 01623 /* Set Initialization mode */ 01624 if (RTC_EnterInitMode(hrtc) != HAL_OK) 01625 { 01626 status = HAL_ERROR; 01627 } 01628 else 01629 { 01630 /* Set RTC COUNTER MSB word */ 01631 WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U)); 01632 /* Set RTC COUNTER LSB word */ 01633 WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT)); 01634 01635 /* Wait for synchro */ 01636 if (RTC_ExitInitMode(hrtc) != HAL_OK) 01637 { 01638 status = HAL_ERROR; 01639 } 01640 } 01641 01642 return status; 01643 } 01644 01645 /** 01646 * @brief Read the time counter available in RTC_ALR registers. 01647 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01648 * the configuration information for RTC. 01649 * @retval Time counter 01650 */ 01651 static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef *hrtc) 01652 { 01653 uint16_t high1 = 0U, low = 0U; 01654 01655 high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT); 01656 low = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT); 01657 01658 return (((uint32_t) high1 << 16U) | low); 01659 } 01660 01661 /** 01662 * @brief Write the time counter in RTC_ALR registers. 01663 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01664 * the configuration information for RTC. 01665 * @param AlarmCounter: Counter to write in RTC_ALR registers 01666 * @retval HAL status 01667 */ 01668 static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef *hrtc, uint32_t AlarmCounter) 01669 { 01670 HAL_StatusTypeDef status = HAL_OK; 01671 01672 /* Set Initialization mode */ 01673 if (RTC_EnterInitMode(hrtc) != HAL_OK) 01674 { 01675 status = HAL_ERROR; 01676 } 01677 else 01678 { 01679 /* Set RTC COUNTER MSB word */ 01680 WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16U)); 01681 /* Set RTC COUNTER LSB word */ 01682 WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR)); 01683 01684 /* Wait for synchro */ 01685 if (RTC_ExitInitMode(hrtc) != HAL_OK) 01686 { 01687 status = HAL_ERROR; 01688 } 01689 } 01690 01691 return status; 01692 } 01693 01694 /** 01695 * @brief Enters the RTC Initialization mode. 01696 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01697 * the configuration information for RTC. 01698 * @retval HAL status 01699 */ 01700 static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc) 01701 { 01702 uint32_t tickstart = 0U; 01703 01704 tickstart = HAL_GetTick(); 01705 /* Wait till RTC is in INIT state and if Time out is reached exit */ 01706 while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET) 01707 { 01708 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) 01709 { 01710 return HAL_TIMEOUT; 01711 } 01712 } 01713 01714 /* Disable the write protection for RTC registers */ 01715 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); 01716 01717 01718 return HAL_OK; 01719 } 01720 01721 /** 01722 * @brief Exit the RTC Initialization mode. 01723 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01724 * the configuration information for RTC. 01725 * @retval HAL status 01726 */ 01727 static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc) 01728 { 01729 uint32_t tickstart = 0U; 01730 01731 /* Disable the write protection for RTC registers */ 01732 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); 01733 01734 tickstart = HAL_GetTick(); 01735 /* Wait till RTC is in INIT state and if Time out is reached exit */ 01736 while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET) 01737 { 01738 if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) 01739 { 01740 return HAL_TIMEOUT; 01741 } 01742 } 01743 01744 return HAL_OK; 01745 } 01746 01747 /** 01748 * @brief Converts a 2 digit decimal to BCD format. 01749 * @param Value: Byte to be converted 01750 * @retval Converted byte 01751 */ 01752 static uint8_t RTC_ByteToBcd2(uint8_t Value) 01753 { 01754 uint32_t bcdhigh = 0U; 01755 01756 while (Value >= 10U) 01757 { 01758 bcdhigh++; 01759 Value -= 10U; 01760 } 01761 01762 return ((uint8_t)(bcdhigh << 4U) | Value); 01763 } 01764 01765 /** 01766 * @brief Converts from 2 digit BCD to Binary. 01767 * @param Value: BCD value to be converted 01768 * @retval Converted word 01769 */ 01770 static uint8_t RTC_Bcd2ToByte(uint8_t Value) 01771 { 01772 uint32_t tmp = 0U; 01773 tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10U; 01774 return (tmp + (Value & (uint8_t)0x0F)); 01775 } 01776 01777 /** 01778 * @brief Updates date when time is 23:59:59. 01779 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains 01780 * the configuration information for RTC. 01781 * @param DayElapsed: Number of days elapsed from last date update 01782 * @retval None 01783 */ 01784 static void RTC_DateUpdate(RTC_HandleTypeDef *hrtc, uint32_t DayElapsed) 01785 { 01786 uint32_t year = 0U, month = 0U, day = 0U; 01787 uint32_t loop = 0U; 01788 01789 /* Get the current year*/ 01790 year = hrtc->DateToUpdate.Year; 01791 01792 /* Get the current month and day */ 01793 month = hrtc->DateToUpdate.Month; 01794 day = hrtc->DateToUpdate.Date; 01795 01796 for (loop = 0U; loop < DayElapsed; loop++) 01797 { 01798 if ((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \ 01799 (month == 8U) || (month == 10U) || (month == 12U)) 01800 { 01801 if (day < 31U) 01802 { 01803 day++; 01804 } 01805 /* Date structure member: day = 31 */ 01806 else 01807 { 01808 if (month != 12U) 01809 { 01810 month++; 01811 day = 1U; 01812 } 01813 /* Date structure member: day = 31 & month =12 */ 01814 else 01815 { 01816 month = 1U; 01817 day = 1U; 01818 year++; 01819 } 01820 } 01821 } 01822 else if ((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U)) 01823 { 01824 if (day < 30U) 01825 { 01826 day++; 01827 } 01828 /* Date structure member: day = 30 */ 01829 else 01830 { 01831 month++; 01832 day = 1U; 01833 } 01834 } 01835 else if (month == 2U) 01836 { 01837 if (day < 28U) 01838 { 01839 day++; 01840 } 01841 else if (day == 28U) 01842 { 01843 /* Leap year */ 01844 if (RTC_IsLeapYear(year)) 01845 { 01846 day++; 01847 } 01848 else 01849 { 01850 month++; 01851 day = 1U; 01852 } 01853 } 01854 else if (day == 29U) 01855 { 01856 month++; 01857 day = 1U; 01858 } 01859 } 01860 } 01861 01862 /* Update year */ 01863 hrtc->DateToUpdate.Year = year; 01864 01865 /* Update day and month */ 01866 hrtc->DateToUpdate.Month = month; 01867 hrtc->DateToUpdate.Date = day; 01868 01869 /* Update day of the week */ 01870 hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day); 01871 } 01872 01873 /** 01874 * @brief Check whether the passed year is Leap or not. 01875 * @param nYear year to check 01876 * @retval 1: leap year 01877 * 0: not leap year 01878 */ 01879 static uint8_t RTC_IsLeapYear(uint16_t nYear) 01880 { 01881 if ((nYear % 4U) != 0U) 01882 { 01883 return 0U; 01884 } 01885 01886 if ((nYear % 100U) != 0U) 01887 { 01888 return 1U; 01889 } 01890 01891 if ((nYear % 400U) == 0U) 01892 { 01893 return 1U; 01894 } 01895 else 01896 { 01897 return 0U; 01898 } 01899 } 01900 01901 /** 01902 * @brief Determines the week number, the day number and the week day number. 01903 * @param nYear year to check 01904 * @param nMonth Month to check 01905 * @param nDay Day to check 01906 * @note Day is calculated with hypothesis that year > 2000 01907 * @retval Value which can take one of the following parameters: 01908 * @arg RTC_WEEKDAY_MONDAY 01909 * @arg RTC_WEEKDAY_TUESDAY 01910 * @arg RTC_WEEKDAY_WEDNESDAY 01911 * @arg RTC_WEEKDAY_THURSDAY 01912 * @arg RTC_WEEKDAY_FRIDAY 01913 * @arg RTC_WEEKDAY_SATURDAY 01914 * @arg RTC_WEEKDAY_SUNDAY 01915 */ 01916 static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay) 01917 { 01918 uint32_t year = 0U, weekday = 0U; 01919 01920 year = 2000U + nYear; 01921 01922 if (nMonth < 3U) 01923 { 01924 /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/ 01925 weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + ((year - 1U) / 4U) - ((year - 1U) / 100U) + ((year - 1U) / 400U)) % 7U; 01926 } 01927 else 01928 { 01929 /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/ 01930 weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + (year / 4U) - (year / 100U) + (year / 400U) - 2U) % 7U; 01931 } 01932 01933 return (uint8_t)weekday; 01934 } 01935 01936 /** 01937 * @} 01938 */ 01939 01940 #endif /* HAL_RTC_MODULE_ENABLED */ 01941 /** 01942 * @} 01943 */ 01944 01945 /** 01946 * @} 01947 */ 01948 01949 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/