1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_hal_rtc.c
4   * @author  MCD Application Team
5   * @brief   RTC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Real Time Clock (RTC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + RTC Time and Date functions
10   *           + RTC Alarm functions
11   *           + Peripheral Control functions
12   *           + Peripheral State functions
13   *
14   @verbatim
15   ==============================================================================
16               ##### Backup Domain Operating Condition #####
17   ==============================================================================
18   [..] The real-time clock (RTC) and the RTC backup registers can be powered
19        from the VBAT voltage when the main VDD supply is powered off.
20        To retain the content of the RTC backup registers and supply the RTC
21        when VDD is turned off, VBAT pin can be connected to an optional
22        standby voltage supplied by a battery or by another source.
23 
24   [..] To allow the RTC operating even when the main digital supply (VDD) is turned
25        off, the VBAT pin powers the following blocks:
26     (#) The RTC
27     (#) The LSE oscillator
28     (#) PC13 to PC15 I/Os (when available)
29 
30   [..] When the backup domain is supplied by VDD (analog switch connected to VDD),
31        the following pins are available:
32     (#) PC14 and PC15 can be used as either GPIO or LSE pins
33     (#) PC13 can be used as a GPIO or as the RTC_AF1 pin
34 
35   [..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
36        because VDD is not present), the following pins are available:
37     (#) PC14 and PC15 can be used as LSE pins only
38     (#) PC13 can be used as the RTC_AF1 pin
39 
40                    ##### Backup Domain Reset #####
41   ==================================================================
42   [..] The backup domain reset sets all RTC registers and the RCC_BDCR register
43        to their reset values.
44   [..] A backup domain reset is generated when one of the following events occurs:
45     (#) Software reset, triggered by setting the BDRST bit in the
46         RCC Backup domain control register (RCC_BDCR).
47     (#) VDD or VBAT power on, if both supplies have previously been powered off.
48 
49                    ##### Backup Domain Access #####
50   ==================================================================
51   [..] After reset, the backup domain (RTC registers, RTC backup data
52        registers and backup SRAM) is protected against possible unwanted write
53        accesses.
54   [..] To enable access to the RTC Domain and RTC registers, proceed as follows:
55     (+) Enable the Power Controller (PWR) APB1 interface clock using the
56         __HAL_RCC_PWR_CLK_ENABLE() function.
57     (+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
58     (+) Select the RTC clock source using the __HAL_RCC_RTC_CONFIG() function.
59     (+) Enable RTC Clock using the __HAL_RCC_RTC_ENABLE() function.
60 
61 
62                   ##### How to use this driver #####
63   ==================================================================
64   [..]
65     (+) Enable the RTC domain access (see description in the section above).
66     (+) Configure the RTC Prescaler (Asynchronous and Synchronous) and RTC hour
67         format using the HAL_RTC_Init() function.
68 
69   *** Time and Date configuration ***
70   ===================================
71   [..]
72     (+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
73         and HAL_RTC_SetDate() functions.
74     (+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions.
75 
76   *** Alarm configuration ***
77   ===========================
78   [..]
79     (+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
80         You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function.
81     (+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
82 
83                   ##### RTC and low power modes #####
84   ==================================================================
85   [..] The MCU can be woken up from a low power mode by an RTC alternate
86        function.
87   [..] The RTC alternate functions are the RTC alarms (Alarm A and Alarm B),
88        RTC wakeup, RTC tamper event detection and RTC time stamp event detection.
89        These RTC alternate functions can wake up the system from the Stop and
90        Standby low power modes.
91   [..] The system can also wake up from low power modes without depending
92        on an external interrupt (Auto-wakeup mode), by using the RTC alarm
93        or the RTC wakeup events.
94   [..] The RTC provides a programmable time base for waking up from the
95        Stop or Standby mode at regular intervals.
96        Wakeup from STOP and STANDBY modes is possible only when the RTC clock source
97        is LSE or LSI.
98 
99    @endverbatim
100   ******************************************************************************
101   * @attention
102   *
103   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
104   *
105   * Redistribution and use in source and binary forms, with or without modification,
106   * are permitted provided that the following conditions are met:
107   *   1. Redistributions of source code must retain the above copyright notice,
108   *      this list of conditions and the following disclaimer.
109   *   2. Redistributions in binary form must reproduce the above copyright notice,
110   *      this list of conditions and the following disclaimer in the documentation
111   *      and/or other materials provided with the distribution.
112   *   3. Neither the name of STMicroelectronics nor the names of its contributors
113   *      may be used to endorse or promote products derived from this software
114   *      without specific prior written permission.
115   *
116   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
117   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
118   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
120   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
121   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
122   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
123   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
124   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
125   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126   *
127   ******************************************************************************
128   */
129 
130 /* Includes ------------------------------------------------------------------*/
131 #include "stm32l1xx_hal.h"
132 
133 /** @addtogroup STM32L1xx_HAL_Driver
134   * @{
135   */
136 
137 /** @defgroup RTC RTC
138   * @brief RTC HAL module driver
139   * @{
140   */
141 
142 #ifdef HAL_RTC_MODULE_ENABLED
143 
144 /* Private typedef -----------------------------------------------------------*/
145 /* Private define ------------------------------------------------------------*/
146 /* Private macro -------------------------------------------------------------*/
147 /* Private variables ---------------------------------------------------------*/
148 /* Private function prototypes -----------------------------------------------*/
149 /* Private functions ---------------------------------------------------------*/
150 /** @defgroup RTC_Exported_Functions RTC Exported Functions
151   * @{
152   */
153 
154 /** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
155  *  @brief    Initialization and Configuration functions
156  *
157 @verbatim
158  ===============================================================================
159               ##### Initialization and de-initialization functions #####
160  ===============================================================================
161    [..] This section provides functions allowing to initialize and configure the
162          RTC Prescaler (Synchronous and Asynchronous), RTC Hour format, disable
163          RTC registers Write protection, enter and exit the RTC initialization mode,
164          RTC registers synchronization check and reference clock detection enable.
165          (#) The RTC Prescaler is programmed to generate the RTC 1Hz time base.
166              It is split into 2 programmable prescalers to minimize power consumption.
167              (++) A 7-bit asynchronous prescaler and a 13-bit synchronous prescaler.
168              (++) When both prescalers are used, it is recommended to configure the
169                  asynchronous prescaler to a high value to minimize power consumption.
170          (#) All RTC registers are Write protected. Writing to the RTC registers
171              is enabled by writing a key into the Write Protection register, RTC_WPR.
172          (#) To configure the RTC Calendar, user application should enter
173              initialization mode. In this mode, the calendar counter is stopped
174              and its value can be updated. When the initialization sequence is
175              complete, the calendar restarts counting after 4 RTCCLK cycles.
176          (#) To read the calendar through the shadow registers after Calendar
177              initialization, calendar update or after wakeup from low power modes
178              the software must first clear the RSF flag. The software must then
179              wait until it is set again before reading the calendar, which means
180              that the calendar registers have been correctly copied into the
181              RTC_TR and RTC_DR shadow registers.The HAL_RTC_WaitForSynchro() function
182              implements the above software sequence (RSF clear and RSF check).
183 
184 @endverbatim
185   * @{
186   */
187 
188 /**
189   * @brief  Initializes the RTC peripheral
190   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
191   *                the configuration information for RTC.
192   * @retval HAL status
193   */
HAL_RTC_Init(RTC_HandleTypeDef * hrtc)194 HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
195 {
196   /* Check the RTC peripheral state */
197   if(hrtc == NULL)
198   {
199      return HAL_ERROR;
200   }
201 
202   /* Check the parameters */
203   assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
204   assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));
205   assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
206   assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));
207   assert_param(IS_RTC_OUTPUT(hrtc->Init.OutPut));
208   assert_param(IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));
209   assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType));
210 
211   if(hrtc->State == HAL_RTC_STATE_RESET)
212   {
213     /* Allocate lock resource and initialize it */
214     hrtc->Lock = HAL_UNLOCKED;
215 
216     /* Initialize RTC MSP */
217     HAL_RTC_MspInit(hrtc);
218   }
219 
220   /* Set RTC state */
221   hrtc->State = HAL_RTC_STATE_BUSY;
222 
223   /* Disable the write protection for RTC registers */
224   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
225 
226   /* Set Initialization mode */
227   if(RTC_EnterInitMode(hrtc) != HAL_OK)
228   {
229     /* Enable the write protection for RTC registers */
230     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
231 
232     /* Set RTC state */
233     hrtc->State = HAL_RTC_STATE_ERROR;
234 
235     return HAL_ERROR;
236   }
237   else
238   {
239     /* Clear RTC_CR FMT, OSEL and POL Bits */
240     hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
241     /* Set RTC_CR register */
242     hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);
243 
244     /* Configure the RTC PRER */
245     hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);
246     hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16);
247 
248     /* Exit Initialization mode */
249     hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
250 
251     hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE;
252     hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);
253 
254     /* Enable the write protection for RTC registers */
255     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
256 
257     /* Set RTC state */
258     hrtc->State = HAL_RTC_STATE_READY;
259 
260     return HAL_OK;
261   }
262 }
263 
264 /**
265   * @brief  DeInitializes the RTC peripheral
266   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
267   *                the configuration information for RTC.
268   * @note   This function doesn't reset the RTC Backup Data registers.
269   * @retval HAL status
270   */
HAL_RTC_DeInit(RTC_HandleTypeDef * hrtc)271 __weak HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
272 {
273   /* Prevent unused argument(s) compilation warning */
274   UNUSED(hrtc);
275 
276   /* Note : This function is defined into this file for library reference. */
277   /*        Function content is located into file stm32l1xx_hal_rtc_ex.c   */
278 
279   /* Return function status */
280   return HAL_ERROR;
281 }
282 
283 /**
284   * @brief  Initializes the RTC MSP.
285   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
286   *                the configuration information for RTC.
287   * @retval None
288   */
HAL_RTC_MspInit(RTC_HandleTypeDef * hrtc)289 __weak void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
290 {
291   /* Prevent unused argument(s) compilation warning */
292   UNUSED(hrtc);
293 
294   /* NOTE : This function Should not be modified, when the callback is needed,
295             the HAL_RTC_MspInit could be implemented in the user file
296    */
297 }
298 
299 /**
300   * @brief  DeInitializes the RTC MSP.
301   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
302   *                the configuration information for RTC.
303   * @retval None
304   */
HAL_RTC_MspDeInit(RTC_HandleTypeDef * hrtc)305 __weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
306 {
307   /* Prevent unused argument(s) compilation warning */
308   UNUSED(hrtc);
309 
310   /* NOTE : This function Should not be modified, when the callback is needed,
311             the HAL_RTC_MspDeInit could be implemented in the user file
312    */
313 }
314 
315 /**
316   * @}
317   */
318 
319 /** @defgroup RTC_Exported_Functions_Group2 RTC Time and Date functions
320  *  @brief   RTC Time and Date functions
321  *
322 @verbatim
323  ===============================================================================
324                  ##### RTC Time and Date functions #####
325  ===============================================================================
326 
327  [..] This section provides functions allowing to configure Time and Date features
328 
329 @endverbatim
330   * @{
331   */
332 
333 /**
334   * @brief  Sets RTC current time.
335   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
336   *                the configuration information for RTC.
337   * @param  sTime: Pointer to Time structure
338   * @param  Format: Specifies the format of the entered parameters.
339   *          This parameter can be one of the following values:
340   *            @arg RTC_FORMAT_BIN: Binary data format
341   *            @arg RTC_FORMAT_BCD: BCD data format
342   * @retval HAL status
343   */
HAL_RTC_SetTime(RTC_HandleTypeDef * hrtc,RTC_TimeTypeDef * sTime,uint32_t Format)344 HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
345 {
346   uint32_t tmpreg = 0;
347 
348  /* Check the parameters */
349   assert_param(IS_RTC_FORMAT(Format));
350   assert_param(IS_RTC_DAYLIGHT_SAVING(sTime->DayLightSaving));
351   assert_param(IS_RTC_STORE_OPERATION(sTime->StoreOperation));
352 
353   /* Process Locked */
354   __HAL_LOCK(hrtc);
355 
356   hrtc->State = HAL_RTC_STATE_BUSY;
357 
358   if(Format == RTC_FORMAT_BIN)
359   {
360     if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET)
361     {
362       assert_param(IS_RTC_HOUR12(sTime->Hours));
363       assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
364     }
365     else
366     {
367       sTime->TimeFormat = 0x00;
368       assert_param(IS_RTC_HOUR24(sTime->Hours));
369     }
370     assert_param(IS_RTC_MINUTES(sTime->Minutes));
371     assert_param(IS_RTC_SECONDS(sTime->Seconds));
372 
373     tmpreg = (uint32_t)(((uint32_t)RTC_ByteToBcd2(sTime->Hours) << 16) | \
374                         ((uint32_t)RTC_ByteToBcd2(sTime->Minutes) << 8) | \
375                         ((uint32_t)RTC_ByteToBcd2(sTime->Seconds)) | \
376                         (((uint32_t)sTime->TimeFormat) << 16));
377   }
378   else
379   {
380     if((hrtc->Instance->CR & RTC_CR_FMT) != (uint32_t)RESET)
381     {
382       tmpreg = RTC_Bcd2ToByte(sTime->Hours);
383       assert_param(IS_RTC_HOUR12(tmpreg));
384       assert_param(IS_RTC_HOURFORMAT12(sTime->TimeFormat));
385     }
386     else
387     {
388       sTime->TimeFormat = 0x00;
389       assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
390     }
391     assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
392     assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
393     tmpreg = (((uint32_t)(sTime->Hours) << 16) | \
394               ((uint32_t)(sTime->Minutes) << 8) | \
395               ((uint32_t)sTime->Seconds) | \
396               ((uint32_t)(sTime->TimeFormat) << 16));
397   }
398 
399   /* Disable the write protection for RTC registers */
400   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
401 
402   /* Set Initialization mode */
403   if(RTC_EnterInitMode(hrtc) != HAL_OK)
404   {
405     /* Enable the write protection for RTC registers */
406     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
407 
408     /* Set RTC state */
409     hrtc->State = HAL_RTC_STATE_ERROR;
410 
411     /* Process Unlocked */
412     __HAL_UNLOCK(hrtc);
413 
414     return HAL_ERROR;
415   }
416   else
417   {
418     /* Set the RTC_TR register */
419     hrtc->Instance->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
420 
421     /* Clear the bits to be configured */
422     hrtc->Instance->CR &= (uint32_t)~RTC_CR_BKP;
423 
424     /* Configure the RTC_CR register */
425     hrtc->Instance->CR |= (uint32_t)(sTime->DayLightSaving | sTime->StoreOperation);
426 
427     /* Exit Initialization mode */
428     hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
429 
430     /* Wait for synchro */
431     if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
432     {
433       /* Enable the write protection for RTC registers */
434       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
435 
436       hrtc->State = HAL_RTC_STATE_ERROR;
437 
438       /* Process Unlocked */
439       __HAL_UNLOCK(hrtc);
440 
441       return HAL_ERROR;
442     }
443 
444     /* Enable the write protection for RTC registers */
445     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
446 
447    hrtc->State = HAL_RTC_STATE_READY;
448 
449    __HAL_UNLOCK(hrtc);
450 
451    return HAL_OK;
452   }
453 }
454 
455 
456 /**
457   * @brief  Sets RTC current date.
458   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
459   *                the configuration information for RTC.
460   * @param  sDate: Pointer to date structure
461   * @param  Format: specifies the format of the entered parameters.
462   *          This parameter can be one of the following values:
463   *            @arg RTC_FORMAT_BIN: Binary data format
464   *            @arg RTC_FORMAT_BCD: BCD data format
465   * @retval HAL status
466   */
HAL_RTC_SetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)467 HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
468 {
469   uint32_t datetmpreg = 0;
470 
471  /* Check the parameters */
472   assert_param(IS_RTC_FORMAT(Format));
473 
474  /* Process Locked */
475  __HAL_LOCK(hrtc);
476 
477   hrtc->State = HAL_RTC_STATE_BUSY;
478 
479   if((Format == RTC_FORMAT_BIN) && ((sDate->Month & 0x10) == 0x10))
480   {
481     sDate->Month = (uint8_t)((sDate->Month & (uint8_t)~(0x10)) + (uint8_t)0x0A);
482   }
483 
484   assert_param(IS_RTC_WEEKDAY(sDate->WeekDay));
485 
486   if(Format == RTC_FORMAT_BIN)
487   {
488     assert_param(IS_RTC_YEAR(sDate->Year));
489     assert_param(IS_RTC_MONTH(sDate->Month));
490     assert_param(IS_RTC_DATE(sDate->Date));
491 
492    datetmpreg = (((uint32_t)RTC_ByteToBcd2(sDate->Year) << 16) | \
493                  ((uint32_t)RTC_ByteToBcd2(sDate->Month) << 8) | \
494                  ((uint32_t)RTC_ByteToBcd2(sDate->Date)) | \
495                  ((uint32_t)sDate->WeekDay << 13));
496   }
497   else
498   {
499     assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
500     datetmpreg = RTC_Bcd2ToByte(sDate->Month);
501     assert_param(IS_RTC_MONTH(datetmpreg));
502     datetmpreg = RTC_Bcd2ToByte(sDate->Date);
503     assert_param(IS_RTC_DATE(datetmpreg));
504 
505     datetmpreg = ((((uint32_t)sDate->Year) << 16) | \
506                   (((uint32_t)sDate->Month) << 8) | \
507                   ((uint32_t)sDate->Date) | \
508                   (((uint32_t)sDate->WeekDay) << 13));
509   }
510 
511   /* Disable the write protection for RTC registers */
512   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
513 
514   /* Set Initialization mode */
515   if(RTC_EnterInitMode(hrtc) != HAL_OK)
516   {
517     /* Enable the write protection for RTC registers */
518     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
519 
520     /* Set RTC state*/
521     hrtc->State = HAL_RTC_STATE_ERROR;
522 
523     /* Process Unlocked */
524     __HAL_UNLOCK(hrtc);
525 
526     return HAL_ERROR;
527   }
528   else
529   {
530     /* Set the RTC_DR register */
531     hrtc->Instance->DR = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK);
532 
533     /* Exit Initialization mode */
534     hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
535 
536     /* Wait for synchro */
537     if(HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
538     {
539       /* Enable the write protection for RTC registers */
540       __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
541 
542       hrtc->State = HAL_RTC_STATE_ERROR;
543 
544       /* Process Unlocked */
545       __HAL_UNLOCK(hrtc);
546 
547       return HAL_ERROR;
548     }
549 
550     /* Enable the write protection for RTC registers */
551     __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
552 
553     hrtc->State = HAL_RTC_STATE_READY ;
554 
555     /* Process Unlocked */
556     __HAL_UNLOCK(hrtc);
557 
558     return HAL_OK;
559   }
560 }
561 
562 /**
563   * @brief  Gets RTC current date.
564   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
565   *                the configuration information for RTC.
566   * @param  sDate: Pointer to Date structure
567   * @param  Format: Specifies the format of the entered parameters.
568   *          This parameter can be one of the following values:
569   *            @arg RTC_FORMAT_BIN:  Binary data format
570   *            @arg RTC_FORMAT_BCD:  BCD data format
571   * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values
572   * in the higher-order calendar shadow registers to ensure consistency between the time and date values.
573   * Reading RTC current time locks the values in calendar shadow registers until Current date is read.
574   * @retval HAL status
575   */
HAL_RTC_GetDate(RTC_HandleTypeDef * hrtc,RTC_DateTypeDef * sDate,uint32_t Format)576 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
577 {
578   uint32_t datetmpreg = 0;
579 
580   /* Check the parameters */
581   assert_param(IS_RTC_FORMAT(Format));
582 
583   /* Get the DR register */
584   datetmpreg = (uint32_t)(hrtc->Instance->DR & RTC_DR_RESERVED_MASK);
585 
586   /* Fill the structure fields with the read parameters */
587   sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16);
588   sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8);
589   sDate->Date = (uint8_t)(datetmpreg & (RTC_DR_DT | RTC_DR_DU));
590   sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> 13);
591 
592   /* Check the input parameters format */
593   if(Format == RTC_FORMAT_BIN)
594   {
595     /* Convert the date structure parameters to Binary format */
596     sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year);
597     sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month);
598     sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date);
599   }
600   return HAL_OK;
601 }
602 
603 /**
604   * @}
605   */
606 
607 /** @defgroup RTC_Exported_Functions_Group3 RTC Alarm functions
608  *  @brief   RTC Alarm functions
609  *
610 @verbatim
611  ===============================================================================
612                  ##### RTC Alarm functions #####
613  ===============================================================================
614 
615  [..] This section provides functions allowing to configure Alarm feature
616 
617 @endverbatim
618   * @{
619   */
620 
621 /**
622   * @brief  Deactive the specified RTC Alarm
623   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
624   *                the configuration information for RTC.
625   * @param  Alarm: Specifies the Alarm.
626   *          This parameter can be one of the following values:
627   *            @arg RTC_ALARM_A:  AlarmA
628   *            @arg RTC_ALARM_B:  AlarmB
629   * @retval HAL status
630   */
HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef * hrtc,uint32_t Alarm)631 HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
632 {
633   uint32_t tickstart = 0;
634 
635   /* Check the parameters */
636   assert_param(IS_RTC_ALARM(Alarm));
637 
638   /* Process Locked */
639   __HAL_LOCK(hrtc);
640 
641   hrtc->State = HAL_RTC_STATE_BUSY;
642 
643   /* Disable the write protection for RTC registers */
644   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
645 
646   if(Alarm == RTC_ALARM_A)
647   {
648     /* AlarmA */
649     __HAL_RTC_ALARMA_DISABLE(hrtc);
650 
651     /* In case of interrupt mode is used, the interrupt source must disabled */
652     __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
653 
654     tickstart = HAL_GetTick();
655 
656     /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */
657     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAWF) == RESET)
658     {
659       if((HAL_GetTick() - tickstart ) >  RTC_TIMEOUT_VALUE)
660       {
661         /* Enable the write protection for RTC registers */
662         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
663 
664         hrtc->State = HAL_RTC_STATE_TIMEOUT;
665 
666         /* Process Unlocked */
667         __HAL_UNLOCK(hrtc);
668 
669         return HAL_TIMEOUT;
670       }
671     }
672   }
673   else
674   {
675     /* AlarmB */
676     __HAL_RTC_ALARMB_DISABLE(hrtc);
677 
678     /* In case of interrupt mode is used, the interrupt source must disabled */
679     __HAL_RTC_ALARM_DISABLE_IT(hrtc,RTC_IT_ALRB);
680 
681     tickstart = HAL_GetTick();
682 
683     /* Wait till RTC ALRxWF flag is set and if Time out is reached exit */
684     while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBWF) == RESET)
685     {
686       if((HAL_GetTick() - tickstart ) >  RTC_TIMEOUT_VALUE)
687       {
688         /* Enable the write protection for RTC registers */
689         __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
690 
691         hrtc->State = HAL_RTC_STATE_TIMEOUT;
692 
693         /* Process Unlocked */
694         __HAL_UNLOCK(hrtc);
695 
696         return HAL_TIMEOUT;
697       }
698     }
699   }
700   /* Enable the write protection for RTC registers */
701   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
702 
703   hrtc->State = HAL_RTC_STATE_READY;
704 
705   /* Process Unlocked */
706   __HAL_UNLOCK(hrtc);
707 
708   return HAL_OK;
709 }
710 
711 /**
712   * @brief  This function handles Alarm interrupt request.
713   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
714   *                the configuration information for RTC.
715   * @retval None
716   */
HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef * hrtc)717 void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc)
718 {
719   /* Get the AlarmA interrupt source enable status */
720   if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA) != RESET)
721   {
722     /* Get the pending status of the AlarmA Interrupt */
723     if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != RESET)
724     {
725       /* AlarmA callback */
726       HAL_RTC_AlarmAEventCallback(hrtc);
727 
728       /* Clear the AlarmA interrupt pending bit */
729       __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
730     }
731   }
732 
733   /* Get the AlarmB interrupt source enable status */
734   if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRB) != RESET)
735   {
736     /* Get the pending status of the AlarmB Interrupt */
737     if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRBF) != RESET)
738     {
739       /* AlarmB callback */
740       HAL_RTCEx_AlarmBEventCallback(hrtc);
741 
742       /* Clear the AlarmB interrupt pending bit */
743       __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRBF);
744     }
745   }
746 
747   /* Clear the EXTI's line Flag for RTC Alarm */
748   __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
749 
750   /* Change RTC state */
751   hrtc->State = HAL_RTC_STATE_READY;
752 }
753 
754 /**
755   * @brief  Alarm A callback.
756   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
757   *                the configuration information for RTC.
758   * @retval None
759   */
HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef * hrtc)760 __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
761 {
762   /* Prevent unused argument(s) compilation warning */
763   UNUSED(hrtc);
764 
765   /* NOTE : This function Should not be modified, when the callback is needed,
766             the HAL_RTC_AlarmAEventCallback could be implemented in the user file
767    */
768 }
769 
770 /**
771   * @brief  This function handles AlarmA Polling request.
772   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
773   *                the configuration information for RTC.
774   * @param  Timeout: Timeout duration
775   * @retval HAL status
776   */
HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef * hrtc,uint32_t Timeout)777 HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
778 {
779 
780   uint32_t tickstart = HAL_GetTick();
781 
782   while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
783   {
784     if(Timeout != HAL_MAX_DELAY)
785     {
786       if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
787       {
788         hrtc->State = HAL_RTC_STATE_TIMEOUT;
789         return HAL_TIMEOUT;
790       }
791     }
792   }
793 
794   /* Clear the Alarm interrupt pending bit */
795   __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
796 
797   /* Change RTC state */
798   hrtc->State = HAL_RTC_STATE_READY;
799 
800   return HAL_OK;
801 }
802 
803 /**
804   * @}
805   */
806 
807 /** @defgroup RTC_Exported_Functions_Group5 Peripheral State functions
808  *  @brief   Peripheral State functions
809  *
810 @verbatim
811  ===============================================================================
812                      ##### Peripheral State functions #####
813  ===============================================================================
814     [..]
815     This subsection provides functions allowing to
816       (+) Get RTC state
817 
818 @endverbatim
819   * @{
820   */
821 /**
822   * @brief  Returns the RTC state.
823   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
824   *                the configuration information for RTC.
825   * @retval HAL state
826   */
HAL_RTC_GetState(RTC_HandleTypeDef * hrtc)827 HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc)
828 {
829   return hrtc->State;
830 }
831 
832 /**
833   * @}
834   */
835 
836 /**
837   * @}
838   */
839 
840 /** @defgroup RTC_Internal_Functions RTC Internal function
841   * @{
842   */
843 
844 /**
845   * @brief  Enters the RTC Initialization mode.
846   * @note   The RTC Initialization mode is write protected, use the
847   *         __HAL_RTC_WRITEPROTECTION_DISABLE() before calling this function.
848   * @param  hrtc: pointer to a RTC_HandleTypeDef structure that contains
849   *                the configuration information for RTC.
850   * @retval HAL status
851   */
RTC_EnterInitMode(RTC_HandleTypeDef * hrtc)852 HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
853 {
854   uint32_t tickstart = 0;
855 
856   /* Check if the Initialization mode is set */
857   if((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
858   {
859     /* Set the Initialization mode */
860     hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK;
861 
862     tickstart = HAL_GetTick();
863     /* Wait till RTC is in INIT state and if Time out is reached exit */
864     while((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
865     {
866       if((HAL_GetTick() - tickstart) >  RTC_TIMEOUT_VALUE)
867       {
868         return HAL_TIMEOUT;
869       }
870     }
871   }
872 
873   return HAL_OK;
874 }
875 
876 /**
877   * @brief  Converts a 2 digit decimal to BCD format.
878   * @param  Value: Byte to be converted
879   * @retval Converted byte
880   */
RTC_ByteToBcd2(uint8_t Value)881 uint8_t RTC_ByteToBcd2(uint8_t Value)
882 {
883   uint32_t bcdhigh = 0;
884 
885   while(Value >= 10)
886   {
887     bcdhigh++;
888     Value -= 10;
889   }
890 
891   return  ((uint8_t)(bcdhigh << 4) | Value);
892 }
893 
894 /**
895   * @brief  Converts from 2 digit BCD to Binary.
896   * @param  Value: BCD value to be converted
897   * @retval Converted word
898   */
RTC_Bcd2ToByte(uint8_t Value)899 uint8_t RTC_Bcd2ToByte(uint8_t Value)
900 {
901   uint32_t tmp = 0;
902   tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
903   return (tmp + (Value & (uint8_t)0x0F));
904 }
905 
906 
907 /**
908   * @}
909   */
910 
911 #endif /* HAL_RTC_MODULE_ENABLED */
912 /**
913   * @}
914   */
915 
916 /**
917   * @}
918   */
919 
920 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
921