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