Subversion Repositories dashGPS

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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