STM32F103xB HAL User Manual
stm32f1xx_hal_rtc.c
Go to the documentation of this file.
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>&copy; 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****/