Increment eeprom version
[betaflight.git] / lib / main / STM32F1 / Drivers / STM32F1xx_HAL_Driver / Src / stm32f1xx_hal_rtc.c
blobf25541df6d660368c6d9ea43e26568a6b205ba2f
1 /**
2 ******************************************************************************
3 * @file stm32f1xx_hal_rtc.c
4 * @author MCD Application Team
5 * @version V1.1.1
6 * @date 12-May-2017
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
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.
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.
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.
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
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.
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)
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.
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
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
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
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.
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()
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.
123 @endverbatim
124 ******************************************************************************
125 * @attention
127 * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
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.
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.
151 ******************************************************************************
154 /* Includes ------------------------------------------------------------------*/
155 #include "stm32f1xx_hal.h"
157 /** @addtogroup STM32F1xx_HAL_Driver
158 * @{
161 /** @defgroup RTC RTC
162 * @brief RTC HAL module driver
163 * @{
166 #ifdef HAL_RTC_MODULE_ENABLED
168 /* Private typedef -----------------------------------------------------------*/
169 /* Private define ------------------------------------------------------------*/
170 /** @defgroup RTC_Private_Constants RTC Private Constants
171 * @{
173 #define RTC_ALARM_RESETVALUE_REGISTER (uint16_t)0xFFFF
174 #define RTC_ALARM_RESETVALUE 0xFFFFFFFFU
177 * @}
180 /* Private macro -------------------------------------------------------------*/
181 /** @defgroup RTC_Private_Macros RTC Private Macros
182 * @{
185 * @}
188 /* Private variables ---------------------------------------------------------*/
189 /* Private function prototypes -----------------------------------------------*/
190 /** @defgroup RTC_Private_Functions RTC Private Functions
191 * @{
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);
206 * @}
209 /* Private functions ---------------------------------------------------------*/
210 /** @defgroup RTC_Exported_Functions RTC Exported Functions
211 * @{
214 /** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
215 * @brief Initialization and Configuration functions
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).
234 @endverbatim
235 * @{
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
244 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
246 uint32_t prescaler = 0U;
247 /* Check input parameters */
248 if(hrtc == NULL)
250 return HAL_ERROR;
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));
258 if(hrtc->State == HAL_RTC_STATE_RESET)
260 /* Allocate lock resource and initialize it */
261 hrtc->Lock = HAL_UNLOCKED;
263 /* Initialize RTC MSP */
264 HAL_RTC_MspInit(hrtc);
267 /* Set RTC state */
268 hrtc->State = HAL_RTC_STATE_BUSY;
270 /* Waiting for synchro */
271 if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
273 /* Set RTC state */
274 hrtc->State = HAL_RTC_STATE_ERROR;
276 return HAL_ERROR;
279 /* Set Initialization mode */
280 if(RTC_EnterInitMode(hrtc) != HAL_OK)
282 /* Set RTC state */
283 hrtc->State = HAL_RTC_STATE_ERROR;
285 return HAL_ERROR;
287 else
289 /* Clear Flags Bits */
290 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_OW | RTC_FLAG_ALRAF | RTC_FLAG_SEC));
292 if(hrtc->Init.OutPut != RTC_OUTPUTSOURCE_NONE)
294 /* Disable the selected Tamper pin */
295 CLEAR_BIT(BKP->CR, BKP_CR_TPE);
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);
301 if (hrtc->Init.AsynchPrediv != RTC_AUTO_1_SECOND)
303 /* RTC Prescaler provided directly by end-user*/
304 prescaler = hrtc->Init.AsynchPrediv;
306 else
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);
312 /* Check that RTC clock is enabled*/
313 if (prescaler == 0U)
315 /* Should not happen. Frequency is not available*/
316 hrtc->State = HAL_RTC_STATE_ERROR;
317 return HAL_ERROR;
319 else
321 /* RTC period = RTCCLK/(RTC_PR + 1) */
322 prescaler = prescaler - 1U;
326 /* Configure the RTC_PRLH / RTC_PRLL */
327 MODIFY_REG(hrtc->Instance->PRLH, RTC_PRLH_PRL, (prescaler >> 16U));
328 MODIFY_REG(hrtc->Instance->PRLL, RTC_PRLL_PRL, (prescaler & RTC_PRLL_PRL));
330 /* Wait for synchro */
331 if(RTC_ExitInitMode(hrtc) != HAL_OK)
333 hrtc->State = HAL_RTC_STATE_ERROR;
335 return HAL_ERROR;
338 /* Initialize date to 1st of January 2000 */
339 hrtc->DateToUpdate.Year = 0x00U;
340 hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY;
341 hrtc->DateToUpdate.Date = 0x01U;
343 /* Set RTC state */
344 hrtc->State = HAL_RTC_STATE_READY;
346 return HAL_OK;
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
357 HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
359 /* Check input parameters */
360 if(hrtc == NULL)
362 return HAL_ERROR;
365 /* Check the parameters */
366 assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
368 /* Set RTC state */
369 hrtc->State = HAL_RTC_STATE_BUSY;
371 /* Set Initialization mode */
372 if(RTC_EnterInitMode(hrtc) != HAL_OK)
374 /* Set RTC state */
375 hrtc->State = HAL_RTC_STATE_ERROR;
377 /* Release Lock */
378 __HAL_UNLOCK(hrtc);
380 return HAL_ERROR;
382 else
384 CLEAR_REG(hrtc->Instance->CNTL);
385 CLEAR_REG(hrtc->Instance->CNTH);
386 WRITE_REG(hrtc->Instance->PRLL, 0x00008000U);
387 CLEAR_REG(hrtc->Instance->PRLH);
389 /* Reset All CRH/CRL bits */
390 CLEAR_REG(hrtc->Instance->CRH);
391 CLEAR_REG(hrtc->Instance->CRL);
393 if(RTC_ExitInitMode(hrtc) != HAL_OK)
395 hrtc->State = HAL_RTC_STATE_ERROR;
397 /* Process Unlocked */
398 __HAL_UNLOCK(hrtc);
400 return HAL_ERROR;
404 /* Wait for synchro*/
405 HAL_RTC_WaitForSynchro(hrtc);
407 /* Clear RSF flag */
408 CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
410 /* De-Initialize RTC MSP */
411 HAL_RTC_MspDeInit(hrtc);
413 hrtc->State = HAL_RTC_STATE_RESET;
415 /* Release Lock */
416 __HAL_UNLOCK(hrtc);
418 return HAL_OK;
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
427 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
429 /* Prevent unused argument(s) compilation warning */
430 UNUSED(hrtc);
431 /* NOTE : This function Should not be modified, when the callback is needed,
432 the HAL_RTC_MspInit could be implemented in the user file
437 * @brief DeInitializes the RTC MSP.
438 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
439 * the configuration information for RTC.
440 * @retval None
442 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
444 /* Prevent unused argument(s) compilation warning */
445 UNUSED(hrtc);
446 /* NOTE : This function Should not be modified, when the callback is needed,
447 the HAL_RTC_MspDeInit could be implemented in the user file
452 * @}
455 /** @defgroup RTC_Exported_Functions_Group2 Time and Date functions
456 * @brief RTC Time and Date functions
458 @verbatim
459 ===============================================================================
460 ##### RTC Time and Date functions #####
461 ===============================================================================
463 [..] This section provides functions allowing to configure Time and Date features
465 @endverbatim
466 * @{
470 * @brief Sets RTC current time.
471 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
472 * the configuration information for RTC.
473 * @param sTime: Pointer to Time structure
474 * @param Format: Specifies the format of the entered parameters.
475 * This parameter can be one of the following values:
476 * @arg RTC_FORMAT_BIN: Binary data format
477 * @arg RTC_FORMAT_BCD: BCD data format
478 * @retval HAL status
480 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
482 uint32_t counter_time = 0U, counter_alarm = 0U;
484 /* Check input parameters */
485 if((hrtc == NULL) || (sTime == NULL))
487 return HAL_ERROR;
490 /* Check the parameters */
491 assert_param(IS_RTC_FORMAT(Format));
493 /* Process Locked */
494 __HAL_LOCK(hrtc);
496 hrtc->State = HAL_RTC_STATE_BUSY;
498 if(Format == RTC_FORMAT_BIN)
500 assert_param(IS_RTC_HOUR24(sTime->Hours));
501 assert_param(IS_RTC_MINUTES(sTime->Minutes));
502 assert_param(IS_RTC_SECONDS(sTime->Seconds));
504 counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600U) + \
505 ((uint32_t)sTime->Minutes * 60U) + \
506 ((uint32_t)sTime->Seconds));
508 else
510 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
511 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
512 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
514 counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600U) + \
515 ((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60U) + \
516 ((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds))));
519 /* Write time counter in RTC registers */
520 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
522 /* Set RTC state */
523 hrtc->State = HAL_RTC_STATE_ERROR;
525 /* Process Unlocked */
526 __HAL_UNLOCK(hrtc);
528 return HAL_ERROR;
530 else
532 /* Clear Second and overflow flags */
533 CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
535 /* Read current Alarm counter in RTC registers */
536 counter_alarm = RTC_ReadAlarmCounter(hrtc);
538 /* Set again alarm to match with new time if enabled */
539 if (counter_alarm != RTC_ALARM_RESETVALUE)
541 if(counter_alarm < counter_time)
543 /* Add 1 day to alarm counter*/
544 counter_alarm += (uint32_t)(24U * 3600U);
546 /* Write new Alarm counter in RTC registers */
547 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
549 /* Set RTC state */
550 hrtc->State = HAL_RTC_STATE_ERROR;
552 /* Process Unlocked */
553 __HAL_UNLOCK(hrtc);
555 return HAL_ERROR;
560 hrtc->State = HAL_RTC_STATE_READY;
562 __HAL_UNLOCK(hrtc);
564 return HAL_OK;
569 * @brief Gets RTC current time.
570 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
571 * the configuration information for RTC.
572 * @param sTime: Pointer to Time structure
573 * @param Format: Specifies the format of the entered parameters.
574 * This parameter can be one of the following values:
575 * @arg RTC_FORMAT_BIN: Binary data format
576 * @arg RTC_FORMAT_BCD: BCD data format
577 * @retval HAL status
579 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
581 uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U;
583 /* Check input parameters */
584 if((hrtc == NULL) || (sTime == NULL))
586 return HAL_ERROR;
589 /* Check the parameters */
590 assert_param(IS_RTC_FORMAT(Format));
592 /* Check if counter overflow occurred */
593 if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW))
595 return HAL_ERROR;
598 /* Read the time counter*/
599 counter_time = RTC_ReadTimeCounter(hrtc);
601 /* Fill the structure fields with the read parameters */
602 hours = counter_time / 3600U;
603 sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U);
604 sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U);
606 if (hours >= 24U)
608 /* Get number of days elapsed from last calculation */
609 days_elapsed = (hours / 24U);
611 /* Set Hours in RTC_TimeTypeDef structure*/
612 sTime->Hours = (hours % 24U);
614 /* Read Alarm counter in RTC registers */
615 counter_alarm = RTC_ReadAlarmCounter(hrtc);
617 /* Calculate remaining time to reach alarm (only if set and not yet expired)*/
618 if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time))
620 counter_alarm -= counter_time;
622 else
624 /* In case of counter_alarm < counter_time */
625 /* Alarm expiration already occurred but alarm not deactivated */
626 counter_alarm = RTC_ALARM_RESETVALUE;
629 /* Set updated time in decreasing counter by number of days elapsed */
630 counter_time -= (days_elapsed * 24U * 3600U);
632 /* Write time counter in RTC registers */
633 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
635 return HAL_ERROR;
638 /* Set updated alarm to be set */
639 if (counter_alarm != RTC_ALARM_RESETVALUE)
641 counter_alarm += counter_time;
643 /* Write time counter in RTC registers */
644 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
646 return HAL_ERROR;
649 else
651 /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
652 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
654 return HAL_ERROR;
658 /* Update date */
659 RTC_DateUpdate(hrtc, days_elapsed);
661 else
663 sTime->Hours = hours;
666 /* Check the input parameters format */
667 if(Format != RTC_FORMAT_BIN)
669 /* Convert the time structure parameters to BCD format */
670 sTime->Hours = (uint8_t)RTC_ByteToBcd2(sTime->Hours);
671 sTime->Minutes = (uint8_t)RTC_ByteToBcd2(sTime->Minutes);
672 sTime->Seconds = (uint8_t)RTC_ByteToBcd2(sTime->Seconds);
675 return HAL_OK;
680 * @brief Sets RTC current date.
681 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
682 * the configuration information for RTC.
683 * @param sDate: Pointer to date structure
684 * @param Format: specifies the format of the entered parameters.
685 * This parameter can be one of the following values:
686 * @arg RTC_FORMAT_BIN: Binary data format
687 * @arg RTC_FORMAT_BCD: BCD data format
688 * @retval HAL status
690 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
692 uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U;
694 /* Check input parameters */
695 if((hrtc == NULL) || (sDate == NULL))
697 return HAL_ERROR;
700 /* Check the parameters */
701 assert_param(IS_RTC_FORMAT(Format));
703 /* Process Locked */
704 __HAL_LOCK(hrtc);
706 hrtc->State = HAL_RTC_STATE_BUSY;
708 if(Format == RTC_FORMAT_BIN)
710 assert_param(IS_RTC_YEAR(sDate->Year));
711 assert_param(IS_RTC_MONTH(sDate->Month));
712 assert_param(IS_RTC_DATE(sDate->Date));
714 /* Change the current date */
715 hrtc->DateToUpdate.Year = sDate->Year;
716 hrtc->DateToUpdate.Month = sDate->Month;
717 hrtc->DateToUpdate.Date = sDate->Date;
719 else
721 assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
722 assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
723 assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
725 /* Change the current date */
726 hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year);
727 hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
728 hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date);
731 /* WeekDay set by user can be ignored because automatically calculated */
732 hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
733 sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
735 /* Reset time to be aligned on the same day */
736 /* Read the time counter*/
737 counter_time = RTC_ReadTimeCounter(hrtc);
739 /* Fill the structure fields with the read parameters */
740 hours = counter_time / 3600U;
741 if (hours > 24U)
743 /* Set updated time in decreasing counter by number of days elapsed */
744 counter_time -= ((hours / 24U) * 24U * 3600U);
745 /* Write time counter in RTC registers */
746 if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
748 /* Set RTC state */
749 hrtc->State = HAL_RTC_STATE_ERROR;
751 /* Process Unlocked */
752 __HAL_UNLOCK(hrtc);
754 return HAL_ERROR;
757 /* Read current Alarm counter in RTC registers */
758 counter_alarm = RTC_ReadAlarmCounter(hrtc);
760 /* Set again alarm to match with new time if enabled */
761 if (counter_alarm != RTC_ALARM_RESETVALUE)
763 if(counter_alarm < counter_time)
765 /* Add 1 day to alarm counter*/
766 counter_alarm += (uint32_t)(24U * 3600U);
768 /* Write new Alarm counter in RTC registers */
769 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
771 /* Set RTC state */
772 hrtc->State = HAL_RTC_STATE_ERROR;
774 /* Process Unlocked */
775 __HAL_UNLOCK(hrtc);
777 return HAL_ERROR;
785 hrtc->State = HAL_RTC_STATE_READY ;
787 /* Process Unlocked */
788 __HAL_UNLOCK(hrtc);
790 return HAL_OK;
794 * @brief Gets RTC current date.
795 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
796 * the configuration information for RTC.
797 * @param sDate: Pointer to Date structure
798 * @param Format: Specifies the format of the entered parameters.
799 * This parameter can be one of the following values:
800 * @arg RTC_FORMAT_BIN: Binary data format
801 * @arg RTC_FORMAT_BCD: BCD data format
802 * @retval HAL status
804 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
806 RTC_TimeTypeDef stime = {0U};
808 /* Check input parameters */
809 if((hrtc == NULL) || (sDate == NULL))
811 return HAL_ERROR;
814 /* Check the parameters */
815 assert_param(IS_RTC_FORMAT(Format));
817 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
818 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
820 return HAL_ERROR;
823 /* Fill the structure fields with the read parameters */
824 sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
825 sDate->Year = hrtc->DateToUpdate.Year;
826 sDate->Month = hrtc->DateToUpdate.Month;
827 sDate->Date = hrtc->DateToUpdate.Date;
829 /* Check the input parameters format */
830 if(Format != RTC_FORMAT_BIN)
832 /* Convert the date structure parameters to BCD format */
833 sDate->Year = (uint8_t)RTC_ByteToBcd2(sDate->Year);
834 sDate->Month = (uint8_t)RTC_ByteToBcd2(sDate->Month);
835 sDate->Date = (uint8_t)RTC_ByteToBcd2(sDate->Date);
837 return HAL_OK;
841 * @}
844 /** @defgroup RTC_Exported_Functions_Group3 Alarm functions
845 * @brief RTC Alarm functions
847 @verbatim
848 ===============================================================================
849 ##### RTC Alarm functions #####
850 ===============================================================================
852 [..] This section provides functions allowing to configure Alarm feature
854 @endverbatim
855 * @{
859 * @brief Sets the specified RTC Alarm.
860 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
861 * the configuration information for RTC.
862 * @param sAlarm: Pointer to Alarm structure
863 * @param Format: Specifies the format of the entered parameters.
864 * This parameter can be one of the following values:
865 * @arg RTC_FORMAT_BIN: Binary data format
866 * @arg RTC_FORMAT_BCD: BCD data format
867 * @retval HAL status
869 HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
871 uint32_t counter_alarm = 0U, counter_time;
872 RTC_TimeTypeDef stime = {0U};
874 /* Check input parameters */
875 if((hrtc == NULL) || (sAlarm == NULL))
877 return HAL_ERROR;
880 /* Check the parameters */
881 assert_param(IS_RTC_FORMAT(Format));
882 assert_param(IS_RTC_ALARM(sAlarm->Alarm));
884 /* Process Locked */
885 __HAL_LOCK(hrtc);
887 hrtc->State = HAL_RTC_STATE_BUSY;
889 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
890 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
892 return HAL_ERROR;
895 /* Convert time in seconds */
896 counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
897 ((uint32_t)stime.Minutes * 60U) + \
898 ((uint32_t)stime.Seconds));
900 if(Format == RTC_FORMAT_BIN)
902 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
903 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
904 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
906 counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
907 ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
908 ((uint32_t)sAlarm->AlarmTime.Seconds));
910 else
912 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
913 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
914 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
916 counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
917 ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
918 ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
921 /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
922 if (counter_alarm < counter_time)
924 /* Add 1 day to alarm counter*/
925 counter_alarm += (uint32_t)(24U * 3600U);
928 /* Write Alarm counter in RTC registers */
929 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
931 /* Set RTC state */
932 hrtc->State = HAL_RTC_STATE_ERROR;
934 /* Process Unlocked */
935 __HAL_UNLOCK(hrtc);
937 return HAL_ERROR;
939 else
941 hrtc->State = HAL_RTC_STATE_READY;
943 __HAL_UNLOCK(hrtc);
945 return HAL_OK;
950 * @brief Sets the specified RTC Alarm with Interrupt
951 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
952 * the configuration information for RTC.
953 * @param sAlarm: Pointer to Alarm structure
954 * @param Format: Specifies the format of the entered parameters.
955 * This parameter can be one of the following values:
956 * @arg RTC_FORMAT_BIN: Binary data format
957 * @arg RTC_FORMAT_BCD: BCD data format
958 * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
959 * @retval HAL status
961 HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
963 uint32_t counter_alarm = 0U, counter_time;
964 RTC_TimeTypeDef stime = {0U};
966 /* Check input parameters */
967 if((hrtc == NULL) || (sAlarm == NULL))
969 return HAL_ERROR;
972 /* Check the parameters */
973 assert_param(IS_RTC_FORMAT(Format));
974 assert_param(IS_RTC_ALARM(sAlarm->Alarm));
976 /* Process Locked */
977 __HAL_LOCK(hrtc);
979 hrtc->State = HAL_RTC_STATE_BUSY;
981 /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
982 if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
984 return HAL_ERROR;
987 /* Convert time in seconds */
988 counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
989 ((uint32_t)stime.Minutes * 60U) + \
990 ((uint32_t)stime.Seconds));
992 if(Format == RTC_FORMAT_BIN)
994 assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
995 assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
996 assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
998 counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
999 ((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
1000 ((uint32_t)sAlarm->AlarmTime.Seconds));
1002 else
1004 assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1005 assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1006 assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1008 counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
1009 ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
1010 ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1013 /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
1014 if (counter_alarm < counter_time)
1016 /* Add 1 day to alarm counter*/
1017 counter_alarm += (uint32_t)(24U * 3600U);
1020 /* Write alarm counter in RTC registers */
1021 if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
1023 /* Set RTC state */
1024 hrtc->State = HAL_RTC_STATE_ERROR;
1026 /* Process Unlocked */
1027 __HAL_UNLOCK(hrtc);
1029 return HAL_ERROR;
1031 else
1033 /* Clear flag alarm A */
1034 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1036 /* Configure the Alarm interrupt */
1037 __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA);
1039 /* RTC Alarm Interrupt Configuration: EXTI configuration */
1040 __HAL_RTC_ALARM_EXTI_ENABLE_IT();
1042 __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
1044 hrtc->State = HAL_RTC_STATE_READY;
1046 __HAL_UNLOCK(hrtc);
1048 return HAL_OK;
1053 * @brief Gets the RTC Alarm value and masks.
1054 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1055 * the configuration information for RTC.
1056 * @param sAlarm: Pointer to Date structure
1057 * @param Alarm: Specifies the Alarm.
1058 * This parameter can be one of the following values:
1059 * @arg RTC_ALARM_A: Alarm
1060 * @param Format: Specifies the format of the entered parameters.
1061 * This parameter can be one of the following values:
1062 * @arg RTC_FORMAT_BIN: Binary data format
1063 * @arg RTC_FORMAT_BCD: BCD data format
1064 * @retval HAL status
1066 HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
1068 uint32_t counter_alarm = 0U;
1070 /* Prevent unused argument(s) compilation warning */
1071 UNUSED(Alarm);
1073 /* Check input parameters */
1074 if((hrtc == NULL) || (sAlarm == NULL))
1076 return HAL_ERROR;
1079 /* Check the parameters */
1080 assert_param(IS_RTC_FORMAT(Format));
1081 assert_param(IS_RTC_ALARM(Alarm));
1083 /* Read Alarm counter in RTC registers */
1084 counter_alarm = RTC_ReadAlarmCounter(hrtc);
1086 /* Fill the structure with the read parameters */
1087 /* Set hours in a day range (between 0 to 24)*/
1088 sAlarm->AlarmTime.Hours = (uint32_t)((counter_alarm / 3600U) % 24U);
1089 sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600U) / 60U);
1090 sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600U) % 60U);
1092 if(Format != RTC_FORMAT_BIN)
1094 sAlarm->AlarmTime.Hours = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours);
1095 sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes);
1096 sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds);
1099 return HAL_OK;
1103 * @brief Deactive the specified RTC Alarm
1104 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1105 * the configuration information for RTC.
1106 * @param Alarm: Specifies the Alarm.
1107 * This parameter can be one of the following values:
1108 * @arg RTC_ALARM_A: AlarmA
1109 * @retval HAL status
1111 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
1113 /* Prevent unused argument(s) compilation warning */
1114 UNUSED(Alarm);
1116 /* Check the parameters */
1117 assert_param(IS_RTC_ALARM(Alarm));
1119 /* Check input parameters */
1120 if(hrtc == NULL)
1122 return HAL_ERROR;
1125 /* Process Locked */
1126 __HAL_LOCK(hrtc);
1128 hrtc->State = HAL_RTC_STATE_BUSY;
1130 /* In case of interrupt mode is used, the interrupt source must disabled */
1131 __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1133 /* Set Initialization mode */
1134 if(RTC_EnterInitMode(hrtc) != HAL_OK)
1136 /* Set RTC state */
1137 hrtc->State = HAL_RTC_STATE_ERROR;
1139 /* Process Unlocked */
1140 __HAL_UNLOCK(hrtc);
1142 return HAL_ERROR;
1144 else
1146 /* Clear flag alarm A */
1147 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1149 /* Set to default values ALRH & ALRL registers */
1150 WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER);
1151 WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER);
1153 /* RTC Alarm Interrupt Configuration: Disable EXTI configuration */
1154 __HAL_RTC_ALARM_EXTI_DISABLE_IT();
1156 /* Wait for synchro */
1157 if(RTC_ExitInitMode(hrtc) != HAL_OK)
1159 hrtc->State = HAL_RTC_STATE_ERROR;
1161 /* Process Unlocked */
1162 __HAL_UNLOCK(hrtc);
1164 return HAL_ERROR;
1167 hrtc->State = HAL_RTC_STATE_READY;
1169 /* Process Unlocked */
1170 __HAL_UNLOCK(hrtc);
1172 return HAL_OK;
1176 * @brief This function handles Alarm interrupt request.
1177 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1178 * the configuration information for RTC.
1179 * @retval None
1181 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc)
1183 if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
1185 /* Get the status of the Interrupt */
1186 if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
1188 /* AlarmA callback */
1189 HAL_RTC_AlarmAEventCallback(hrtc);
1191 /* Clear the Alarm interrupt pending bit */
1192 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc,RTC_FLAG_ALRAF);
1196 /* Clear the EXTI's line Flag for RTC Alarm */
1197 __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
1199 /* Change RTC state */
1200 hrtc->State = HAL_RTC_STATE_READY;
1204 * @brief Alarm A callback.
1205 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1206 * the configuration information for RTC.
1207 * @retval None
1209 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
1211 /* Prevent unused argument(s) compilation warning */
1212 UNUSED(hrtc);
1213 /* NOTE : This function Should not be modified, when the callback is needed,
1214 the HAL_RTC_AlarmAEventCallback could be implemented in the user file
1219 * @brief This function handles AlarmA Polling request.
1220 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1221 * the configuration information for RTC.
1222 * @param Timeout: Timeout duration
1223 * @retval HAL status
1225 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
1227 uint32_t tickstart = HAL_GetTick();
1229 /* Check input parameters */
1230 if(hrtc == NULL)
1232 return HAL_ERROR;
1235 while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
1237 if(Timeout != HAL_MAX_DELAY)
1239 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1241 hrtc->State = HAL_RTC_STATE_TIMEOUT;
1242 return HAL_TIMEOUT;
1247 /* Clear the Alarm interrupt pending bit */
1248 __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1250 /* Change RTC state */
1251 hrtc->State = HAL_RTC_STATE_READY;
1253 return HAL_OK;
1257 * @}
1260 /** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions
1261 * @brief Peripheral State functions
1263 @verbatim
1264 ===============================================================================
1265 ##### Peripheral State functions #####
1266 ===============================================================================
1267 [..]
1268 This subsection provides functions allowing to
1269 (+) Get RTC state
1271 @endverbatim
1272 * @{
1275 * @brief Returns the RTC state.
1276 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1277 * the configuration information for RTC.
1278 * @retval HAL state
1280 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc)
1282 return hrtc->State;
1286 * @}
1289 /** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions
1290 * @brief Peripheral Control functions
1292 @verbatim
1293 ===============================================================================
1294 ##### Peripheral Control functions #####
1295 ===============================================================================
1296 [..]
1297 This subsection provides functions allowing to
1298 (+) Wait for RTC Time and Date Synchronization
1300 @endverbatim
1301 * @{
1305 * @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL)
1306 * are synchronized with RTC APB clock.
1307 * @note This function must be called before any read operation after an APB reset
1308 * or an APB clock stop.
1309 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1310 * the configuration information for RTC.
1311 * @retval HAL status
1313 HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc)
1315 uint32_t tickstart = 0U;
1317 /* Check input parameters */
1318 if(hrtc == NULL)
1320 return HAL_ERROR;
1323 /* Clear RSF flag */
1324 CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
1326 tickstart = HAL_GetTick();
1328 /* Wait the registers to be synchronised */
1329 while((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET)
1331 if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
1333 return HAL_TIMEOUT;
1337 return HAL_OK;
1341 * @}
1346 * @}
1349 /** @addtogroup RTC_Private_Functions
1350 * @{
1355 * @brief Read the time counter available in RTC_CNT registers.
1356 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1357 * the configuration information for RTC.
1358 * @retval Time counter
1360 static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef* hrtc)
1362 uint16_t high1 = 0U, high2 = 0U, low = 0U;
1363 uint32_t timecounter = 0U;
1365 high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
1366 low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
1367 high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
1369 if (high1 != high2)
1370 { /* In this case the counter roll over during reading of CNTL and CNTH registers,
1371 read again CNTL register then return the counter value */
1372 timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
1374 else
1375 { /* No counter roll over during reading of CNTL and CNTH registers, counter
1376 value is equal to first value of CNTL and CNTH */
1377 timecounter = (((uint32_t) high1 << 16U) | low);
1380 return timecounter;
1384 * @brief Write the time counter in RTC_CNT registers.
1385 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1386 * the configuration information for RTC.
1387 * @param TimeCounter: Counter to write in RTC_CNT registers
1388 * @retval HAL status
1390 static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef* hrtc, uint32_t TimeCounter)
1392 HAL_StatusTypeDef status = HAL_OK;
1394 /* Set Initialization mode */
1395 if(RTC_EnterInitMode(hrtc) != HAL_OK)
1397 status = HAL_ERROR;
1399 else
1401 /* Set RTC COUNTER MSB word */
1402 WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U));
1403 /* Set RTC COUNTER LSB word */
1404 WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
1406 /* Wait for synchro */
1407 if(RTC_ExitInitMode(hrtc) != HAL_OK)
1409 status = HAL_ERROR;
1413 return status;
1417 * @brief Read the time counter available in RTC_ALR registers.
1418 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1419 * the configuration information for RTC.
1420 * @retval Time counter
1422 static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef* hrtc)
1424 uint16_t high1 = 0U, low = 0U;
1426 high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT);
1427 low = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT);
1429 return (((uint32_t) high1 << 16U) | low);
1433 * @brief Write the time counter in RTC_ALR registers.
1434 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1435 * the configuration information for RTC.
1436 * @param AlarmCounter: Counter to write in RTC_ALR registers
1437 * @retval HAL status
1439 static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter)
1441 HAL_StatusTypeDef status = HAL_OK;
1443 /* Set Initialization mode */
1444 if(RTC_EnterInitMode(hrtc) != HAL_OK)
1446 status = HAL_ERROR;
1448 else
1450 /* Set RTC COUNTER MSB word */
1451 WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16U));
1452 /* Set RTC COUNTER LSB word */
1453 WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
1455 /* Wait for synchro */
1456 if(RTC_ExitInitMode(hrtc) != HAL_OK)
1458 status = HAL_ERROR;
1462 return status;
1466 * @brief Enters the RTC Initialization mode.
1467 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1468 * the configuration information for RTC.
1469 * @retval HAL status
1471 static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
1473 uint32_t tickstart = 0U;
1475 tickstart = HAL_GetTick();
1476 /* Wait till RTC is in INIT state and if Time out is reached exit */
1477 while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
1479 if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1481 return HAL_TIMEOUT;
1485 /* Disable the write protection for RTC registers */
1486 __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1489 return HAL_OK;
1493 * @brief Exit the RTC Initialization mode.
1494 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1495 * the configuration information for RTC.
1496 * @retval HAL status
1498 static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef* hrtc)
1500 uint32_t tickstart = 0U;
1502 /* Disable the write protection for RTC registers */
1503 __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1505 tickstart = HAL_GetTick();
1506 /* Wait till RTC is in INIT state and if Time out is reached exit */
1507 while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
1509 if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
1511 return HAL_TIMEOUT;
1515 return HAL_OK;
1519 * @brief Converts a 2 digit decimal to BCD format.
1520 * @param Value: Byte to be converted
1521 * @retval Converted byte
1523 static uint8_t RTC_ByteToBcd2(uint8_t Value)
1525 uint32_t bcdhigh = 0U;
1527 while(Value >= 10U)
1529 bcdhigh++;
1530 Value -= 10U;
1533 return ((uint8_t)(bcdhigh << 4U) | Value);
1537 * @brief Converts from 2 digit BCD to Binary.
1538 * @param Value: BCD value to be converted
1539 * @retval Converted word
1541 static uint8_t RTC_Bcd2ToByte(uint8_t Value)
1543 uint32_t tmp = 0U;
1544 tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10U;
1545 return (tmp + (Value & (uint8_t)0x0F));
1549 * @brief Updates date when time is 23:59:59.
1550 * @param hrtc pointer to a RTC_HandleTypeDef structure that contains
1551 * the configuration information for RTC.
1552 * @param DayElapsed: Number of days elapsed from last date update
1553 * @retval None
1555 static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed)
1557 uint32_t year = 0U, month = 0U, day = 0U;
1558 uint32_t loop = 0U;
1560 /* Get the current year*/
1561 year = hrtc->DateToUpdate.Year;
1563 /* Get the current month and day */
1564 month = hrtc->DateToUpdate.Month;
1565 day = hrtc->DateToUpdate.Date;
1567 for (loop = 0U; loop < DayElapsed; loop++)
1569 if((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \
1570 (month == 8U) || (month == 10U) || (month == 12U))
1572 if(day < 31U)
1574 day++;
1576 /* Date structure member: day = 31 */
1577 else
1579 if(month != 12U)
1581 month++;
1582 day = 1U;
1584 /* Date structure member: day = 31 & month =12 */
1585 else
1587 month = 1U;
1588 day = 1U;
1589 year++;
1593 else if((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U))
1595 if(day < 30U)
1597 day++;
1599 /* Date structure member: day = 30 */
1600 else
1602 month++;
1603 day = 1U;
1606 else if(month == 2U)
1608 if(day < 28U)
1610 day++;
1612 else if(day == 28U)
1614 /* Leap year */
1615 if(RTC_IsLeapYear(year))
1617 day++;
1619 else
1621 month++;
1622 day = 1U;
1625 else if(day == 29U)
1627 month++;
1628 day = 1U;
1633 /* Update year */
1634 hrtc->DateToUpdate.Year = year;
1636 /* Update day and month */
1637 hrtc->DateToUpdate.Month = month;
1638 hrtc->DateToUpdate.Date = day;
1640 /* Update day of the week */
1641 hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
1645 * @brief Check whether the passed year is Leap or not.
1646 * @param nYear year to check
1647 * @retval 1: leap year
1648 * 0: not leap year
1650 static uint8_t RTC_IsLeapYear(uint16_t nYear)
1652 if((nYear % 4U) != 0U)
1654 return 0U;
1657 if((nYear % 100U) != 0U)
1659 return 1U;
1662 if((nYear % 400U) == 0U)
1664 return 1U;
1666 else
1668 return 0U;
1673 * @brief Determines the week number, the day number and the week day number.
1674 * @param nYear year to check
1675 * @param nMonth Month to check
1676 * @param nDay Day to check
1677 * @note Day is calculated with hypothesis that year > 2000
1678 * @retval Value which can take one of the following parameters:
1679 * @arg RTC_WEEKDAY_MONDAY
1680 * @arg RTC_WEEKDAY_TUESDAY
1681 * @arg RTC_WEEKDAY_WEDNESDAY
1682 * @arg RTC_WEEKDAY_THURSDAY
1683 * @arg RTC_WEEKDAY_FRIDAY
1684 * @arg RTC_WEEKDAY_SATURDAY
1685 * @arg RTC_WEEKDAY_SUNDAY
1687 static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
1689 uint32_t year = 0U, weekday = 0U;
1691 year = 2000U + nYear;
1693 if(nMonth < 3U)
1695 /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
1696 weekday = (((23U * nMonth)/9U) + nDay + 4U + year + ((year-1U)/4U) - ((year-1U)/100U) + ((year-1U)/400U)) % 7U;
1698 else
1700 /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
1701 weekday = (((23U * nMonth)/9U) + nDay + 4U + year + (year/4U) - (year/100U) + (year/400U) - 2U ) % 7U;
1704 return (uint8_t)weekday;
1708 * @}
1711 #endif /* HAL_RTC_MODULE_ENABLED */
1713 * @}
1717 * @}
1720 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/