Subversion Repositories DashDisplay

Rev

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