Subversion Repositories AFRtranscoder

Rev

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