Subversion Repositories DashDisplay

Rev

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

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_rtc.c
4
  * @author  MCD Application Team
5 mjames 5
  * @version V1.0.4
6
  * @date    29-April-2016
2 mjames 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
  *
5 mjames 127
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
2 mjames 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
{
5 mjames 429
  /* Prevent unused argument(s) compilation warning */
430
  UNUSED(hrtc);
2 mjames 431
  /* NOTE : This function Should not be modified, when the callback is needed,
432
            the HAL_RTC_MspInit could be implemented in the user file
433
   */
434
}
435
 
436
/**
437
  * @brief  DeInitializes the RTC MSP.
438
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
439
  *                the configuration information for RTC.
440
  * @retval None
441
  */
442
__weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
443
{
5 mjames 444
  /* Prevent unused argument(s) compilation warning */
445
  UNUSED(hrtc);
2 mjames 446
  /* NOTE : This function Should not be modified, when the callback is needed,
447
            the HAL_RTC_MspDeInit could be implemented in the user file
448
   */
449
}
450
 
451
/**
452
  * @}
453
  */
454
 
455
/** @defgroup RTC_Exported_Functions_Group2 Time and Date functions
456
 *  @brief   RTC Time and Date functions
457
 *
458
@verbatim  
459
 ===============================================================================
460
                 ##### RTC Time and Date functions #####
461
 ===============================================================================  
462
 
463
 [..] This section provides functions allowing to configure Time and Date features
464
 
465
@endverbatim
466
  * @{
467
  */
468
 
469
/**
470
  * @brief  Sets RTC current time.
471
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
472
  *                the configuration information for RTC.
473
  * @param  sTime: Pointer to Time structure
474
  * @param  Format: Specifies the format of the entered parameters.
475
  *          This parameter can be one of the following values:
476
  *            @arg RTC_FORMAT_BIN: Binary data format
477
  *            @arg RTC_FORMAT_BCD: BCD data format
478
  * @retval HAL status
479
  */
480
HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
481
{
482
  uint32_t counter_time = 0, counter_alarm = 0;
483
 
484
  /* Check input parameters */
485
  if((hrtc == NULL) || (sTime == NULL))
486
  {
487
     return HAL_ERROR;
488
  }
489
 
490
 /* Check the parameters */
491
  assert_param(IS_RTC_FORMAT(Format));
492
 
493
  /* Process Locked */
494
  __HAL_LOCK(hrtc);
495
 
496
  hrtc->State = HAL_RTC_STATE_BUSY;
497
 
498
  if(Format == RTC_FORMAT_BIN)
499
  {
500
    assert_param(IS_RTC_HOUR24(sTime->Hours));
501
    assert_param(IS_RTC_MINUTES(sTime->Minutes));
502
    assert_param(IS_RTC_SECONDS(sTime->Seconds));
503
 
504
    counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600) + \
505
                        ((uint32_t)sTime->Minutes * 60) + \
506
                        ((uint32_t)sTime->Seconds));  
507
  }
508
  else
509
  {
510
    assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
511
    assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
512
    assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
513
 
514
    counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600) + \
515
              ((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60) + \
516
              ((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds))));  
517
  }
518
 
519
  /* Write time counter in RTC registers */
520
  if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
521
  {
522
    /* Set RTC state */
523
    hrtc->State = HAL_RTC_STATE_ERROR;
524
 
525
    /* Process Unlocked */
526
    __HAL_UNLOCK(hrtc);
527
 
528
    return HAL_ERROR;
529
  }
530
  else
531
  {
532
    /* Clear Second and overflow flags */
533
    CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
534
 
535
    /* Read current Alarm counter in RTC registers */
536
    counter_alarm = RTC_ReadAlarmCounter(hrtc);
537
 
538
    /* Set again alarm to match with new time if enabled */
539
    if (counter_alarm != RTC_ALARM_RESETVALUE)
540
    {
541
      if(counter_alarm < counter_time)
542
      {
543
        /* Add 1 day to alarm counter*/
544
        counter_alarm += (uint32_t)(24 * 3600);
545
 
546
        /* Write new Alarm counter in RTC registers */
547
        if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
548
        {
549
          /* Set RTC state */
550
          hrtc->State = HAL_RTC_STATE_ERROR;
551
 
552
          /* Process Unlocked */
553
          __HAL_UNLOCK(hrtc);
554
 
555
          return HAL_ERROR;
556
        }
557
      }
558
    }
559
 
560
    hrtc->State = HAL_RTC_STATE_READY;
561
 
562
   __HAL_UNLOCK(hrtc);
563
 
564
   return HAL_OK;
565
  }
566
}
567
 
568
/**
569
  * @brief  Gets RTC current time.
570
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
571
  *                the configuration information for RTC.
572
  * @param  sTime: Pointer to Time structure
573
  * @param  Format: Specifies the format of the entered parameters.
574
  *          This parameter can be one of the following values:
575
  *            @arg RTC_FORMAT_BIN: Binary data format
576
  *            @arg RTC_FORMAT_BCD: BCD data format
577
  * @retval HAL status
578
  */
579
HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
580
{
581
  uint32_t counter_time = 0, counter_alarm = 0, days_elapsed = 0, hours = 0;
582
 
583
  /* Check input parameters */
584
  if((hrtc == NULL) || (sTime == NULL))
585
  {
586
     return HAL_ERROR;
587
  }
588
 
589
  /* Check the parameters */
590
  assert_param(IS_RTC_FORMAT(Format));
591
 
592
  /* Check if counter overflow occurred */
593
  if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW))
594
  {
595
      return HAL_ERROR;
596
  }
597
 
598
  /* Read the time counter*/
599
  counter_time = RTC_ReadTimeCounter(hrtc);
600
 
601
  /* Fill the structure fields with the read parameters */
602
  hours = counter_time / 3600;
603
  sTime->Minutes  = (uint8_t)((counter_time % 3600) / 60);
604
  sTime->Seconds  = (uint8_t)((counter_time % 3600) % 60);
605
 
606
  if (hours >= 24)
607
  {
608
    /* Get number of days elapsed from last calculation */
609
    days_elapsed = (hours / 24);
610
 
611
    /* Set Hours in RTC_TimeTypeDef structure*/
612
    sTime->Hours = (hours % 24);    
613
 
614
    /* Read Alarm counter in RTC registers */
615
    counter_alarm = RTC_ReadAlarmCounter(hrtc);
616
 
617
    /* Calculate remaining time to reach alarm (only if set and not yet expired)*/
618
    if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time))
619
    {
620
      counter_alarm -= counter_time;
621
    }
622
    else
623
    {
624
      /* In case of counter_alarm < counter_time */
625
      /* Alarm expiration already occurred but alarm not deactivated */
626
      counter_alarm = RTC_ALARM_RESETVALUE;
627
    }
628
 
629
    /* Set updated time in decreasing counter by number of days elapsed */
630
    counter_time -= (days_elapsed * 24 * 3600);
631
 
632
    /* Write time counter in RTC registers */
633
    if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
634
    {
635
      return HAL_ERROR;
636
    }
637
 
638
    /* Set updated alarm to be set */
639
    if (counter_alarm != RTC_ALARM_RESETVALUE)
640
    {
641
      counter_alarm += counter_time;
642
 
643
      /* Write time counter in RTC registers */
644
      if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
645
      {
646
        return HAL_ERROR;
647
      }
648
    }
649
    else
650
    {
651
      /* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
652
      if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
653
      {
654
        return HAL_ERROR;
655
      }
656
    }
657
 
658
    /* Update date */
659
    RTC_DateUpdate(hrtc, days_elapsed);
660
  }
661
  else
662
  {
663
    sTime->Hours = hours;    
664
  }
665
 
666
  /* Check the input parameters format */
667
  if(Format != RTC_FORMAT_BIN)
668
  {
669
    /* Convert the time structure parameters to BCD format */
670
    sTime->Hours    = (uint8_t)RTC_ByteToBcd2(sTime->Hours);
671
    sTime->Minutes  = (uint8_t)RTC_ByteToBcd2(sTime->Minutes);
672
    sTime->Seconds  = (uint8_t)RTC_ByteToBcd2(sTime->Seconds);  
673
  }
674
 
675
  return HAL_OK;
676
}
677
 
678
 
679
/**
680
  * @brief  Sets RTC current date.
681
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
682
  *                the configuration information for RTC.
683
  * @param  sDate: Pointer to date structure
684
  * @param  Format: specifies the format of the entered parameters.
685
  *          This parameter can be one of the following values:
686
  *            @arg RTC_FORMAT_BIN: Binary data format
687
  *            @arg RTC_FORMAT_BCD: BCD data format
688
  * @retval HAL status
689
  */
690
HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
691
{
692
  uint32_t counter_time = 0, counter_alarm = 0, hours = 0;
693
 
694
  /* Check input parameters */
695
  if((hrtc == NULL) || (sDate == NULL))
696
  {
697
     return HAL_ERROR;
698
  }
699
 
700
  /* Check the parameters */
701
  assert_param(IS_RTC_FORMAT(Format));
702
 
703
 /* Process Locked */
704
 __HAL_LOCK(hrtc);
705
 
706
  hrtc->State = HAL_RTC_STATE_BUSY;
707
 
708
  if(Format == RTC_FORMAT_BIN)
709
  {  
710
    assert_param(IS_RTC_YEAR(sDate->Year));
711
    assert_param(IS_RTC_MONTH(sDate->Month));
712
    assert_param(IS_RTC_DATE(sDate->Date));
713
 
714
    /* Change the current date */
715
    hrtc->DateToUpdate.Year  = sDate->Year;
716
    hrtc->DateToUpdate.Month = sDate->Month;
717
    hrtc->DateToUpdate.Date  = sDate->Date;
718
  }
719
  else
720
  {  
721
    assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
722
    assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
723
    assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
724
 
725
    /* Change the current date */
726
    hrtc->DateToUpdate.Year  = RTC_Bcd2ToByte(sDate->Year);
727
    hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
728
    hrtc->DateToUpdate.Date  = RTC_Bcd2ToByte(sDate->Date);
729
  }
730
 
731
  /* WeekDay set by user can be ignored because automatically calculated */
732
  hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
733
  sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
734
 
735
  /* Reset time to be aligned on the same day */
736
  /* Read the time counter*/
737
  counter_time = RTC_ReadTimeCounter(hrtc);
738
 
739
  /* Fill the structure fields with the read parameters */
740
  hours = counter_time / 3600;
741
  if (hours > 24)
742
  {
743
    /* Set updated time in decreasing counter by number of days elapsed */
744
    counter_time -= ((hours / 24) * 24 * 3600);
745
    /* Write time counter in RTC registers */
746
    if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
747
    {
748
      /* Set RTC state */
749
      hrtc->State = HAL_RTC_STATE_ERROR;
750
 
751
      /* Process Unlocked */
752
      __HAL_UNLOCK(hrtc);
753
 
754
      return HAL_ERROR;
755
    }
756
 
757
    /* Read current Alarm counter in RTC registers */
758
    counter_alarm = RTC_ReadAlarmCounter(hrtc);
759
 
760
    /* Set again alarm to match with new time if enabled */
761
    if (counter_alarm != RTC_ALARM_RESETVALUE)
762
    {
763
      if(counter_alarm < counter_time)
764
      {
765
        /* Add 1 day to alarm counter*/
766
        counter_alarm += (uint32_t)(24 * 3600);
767
 
768
        /* Write new Alarm counter in RTC registers */
769
        if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
770
        {
771
          /* Set RTC state */
772
          hrtc->State = HAL_RTC_STATE_ERROR;
773
 
774
          /* Process Unlocked */
775
          __HAL_UNLOCK(hrtc);
776
 
777
          return HAL_ERROR;
778
        }
779
      }
780
    }
781
 
782
 
783
  }
784
 
785
  hrtc->State = HAL_RTC_STATE_READY ;
786
 
787
  /* Process Unlocked */
788
  __HAL_UNLOCK(hrtc);
789
 
790
  return HAL_OK;    
791
}
792
 
793
/**
794
  * @brief  Gets RTC current date.
795
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
796
  *                the configuration information for RTC.
797
  * @param  sDate: Pointer to Date structure
798
  * @param  Format: Specifies the format of the entered parameters.
799
  *          This parameter can be one of the following values:
800
  *            @arg RTC_FORMAT_BIN:  Binary data format
801
  *            @arg RTC_FORMAT_BCD:  BCD data format
802
  * @retval HAL status
803
  */
804
HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
805
{
806
  RTC_TimeTypeDef stime = {0};
807
 
808
  /* Check input parameters */
809
  if((hrtc == NULL) || (sDate == NULL))
810
  {
811
     return HAL_ERROR;
812
  }
813
 
814
  /* Check the parameters */
815
  assert_param(IS_RTC_FORMAT(Format));
816
 
817
  /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
818
  if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
819
  {
820
    return HAL_ERROR;
821
  }
822
 
823
  /* Fill the structure fields with the read parameters */
824
  sDate->WeekDay  = hrtc->DateToUpdate.WeekDay;
825
  sDate->Year     = hrtc->DateToUpdate.Year;
826
  sDate->Month    = hrtc->DateToUpdate.Month;
827
  sDate->Date     = hrtc->DateToUpdate.Date;
828
 
829
  /* Check the input parameters format */
830
  if(Format != RTC_FORMAT_BIN)
831
  {    
832
    /* Convert the date structure parameters to BCD format */
833
    sDate->Year   = (uint8_t)RTC_ByteToBcd2(sDate->Year);
834
    sDate->Month  = (uint8_t)RTC_ByteToBcd2(sDate->Month);
835
    sDate->Date   = (uint8_t)RTC_ByteToBcd2(sDate->Date);  
836
  }
837
  return HAL_OK;
838
}
839
 
840
/**
841
  * @}
842
  */
843
 
844
/** @defgroup RTC_Exported_Functions_Group3 Alarm functions
845
 *  @brief   RTC Alarm functions
846
 *
847
@verbatim  
848
 ===============================================================================
849
                 ##### RTC Alarm functions #####
850
 ===============================================================================  
851
 
852
 [..] This section provides functions allowing to configure Alarm feature
853
 
854
@endverbatim
855
  * @{
856
  */
857
 
858
/**
859
  * @brief  Sets the specified RTC Alarm.
860
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
861
  *                the configuration information for RTC.
862
  * @param  sAlarm: Pointer to Alarm structure
863
  * @param  Format: Specifies the format of the entered parameters.
864
  *          This parameter can be one of the following values:
865
  *             @arg RTC_FORMAT_BIN: Binary data format
866
  *             @arg RTC_FORMAT_BCD: BCD data format
867
  * @retval HAL status
868
  */
869
HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
870
{
871
  uint32_t counter_alarm = 0, counter_time;
872
  RTC_TimeTypeDef stime = {0};
873
 
874
  /* Check input parameters */
875
  if((hrtc == NULL) || (sAlarm == NULL))
876
  {
877
     return HAL_ERROR;
878
  }
879
 
880
  /* Check the parameters */
881
  assert_param(IS_RTC_FORMAT(Format));
882
  assert_param(IS_RTC_ALARM(sAlarm->Alarm));
883
 
884
  /* Process Locked */
885
  __HAL_LOCK(hrtc);
886
 
887
  hrtc->State = HAL_RTC_STATE_BUSY;
888
 
889
  /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
890
  if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
891
  {
892
    return HAL_ERROR;
893
  }
894
 
895
  /* Convert time in seconds */
896
  counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600) + \
897
                      ((uint32_t)stime.Minutes * 60) + \
898
                      ((uint32_t)stime.Seconds));  
899
 
900
  if(Format == RTC_FORMAT_BIN)
901
  {
902
    assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
903
    assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
904
    assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
905
 
906
    counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600) + \
907
                        ((uint32_t)sAlarm->AlarmTime.Minutes * 60) + \
908
                        ((uint32_t)sAlarm->AlarmTime.Seconds));  
909
  }
910
  else
911
  {
912
    assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
913
    assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
914
    assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
915
 
916
    counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600) + \
917
              ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60) + \
918
              ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));  
919
  }
920
 
921
  /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
922
  if (counter_alarm < counter_time)
923
  {
924
    /* Add 1 day to alarm counter*/
925
    counter_alarm += (uint32_t)(24 * 3600);
926
  }
927
 
928
  /* Write Alarm counter in RTC registers */
929
  if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
930
  {
931
    /* Set RTC state */
932
    hrtc->State = HAL_RTC_STATE_ERROR;
933
 
934
    /* Process Unlocked */
935
    __HAL_UNLOCK(hrtc);
936
 
937
    return HAL_ERROR;
938
  }
939
  else
940
  {
941
    hrtc->State = HAL_RTC_STATE_READY;
942
 
943
   __HAL_UNLOCK(hrtc);
944
 
945
   return HAL_OK;
946
  }
947
}
948
 
949
/**
950
  * @brief  Sets the specified RTC Alarm with Interrupt
951
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
952
  *                the configuration information for RTC.
953
  * @param  sAlarm: Pointer to Alarm structure
954
  * @param  Format: Specifies the format of the entered parameters.
955
  *          This parameter can be one of the following values:
956
  *             @arg RTC_FORMAT_BIN: Binary data format
957
  *             @arg RTC_FORMAT_BCD: BCD data format
958
  * @note   The HAL_RTC_SetTime() must be called before enabling the Alarm feature.  
959
  * @retval HAL status
960
  */
961
HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
962
{
963
  uint32_t counter_alarm = 0, counter_time;
964
  RTC_TimeTypeDef stime = {0};
965
 
966
  /* Check input parameters */
967
  if((hrtc == NULL) || (sAlarm == NULL))
968
  {
969
     return HAL_ERROR;
970
  }
971
 
972
  /* Check the parameters */
973
  assert_param(IS_RTC_FORMAT(Format));
974
  assert_param(IS_RTC_ALARM(sAlarm->Alarm));
975
 
976
  /* Process Locked */
977
  __HAL_LOCK(hrtc);
978
 
979
  hrtc->State = HAL_RTC_STATE_BUSY;
980
 
981
  /* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
982
  if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
983
  {
984
    return HAL_ERROR;
985
  }
986
 
987
  /* Convert time in seconds */
988
  counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600) + \
989
                      ((uint32_t)stime.Minutes * 60) + \
990
                      ((uint32_t)stime.Seconds));  
991
 
992
  if(Format == RTC_FORMAT_BIN)
993
  {
994
    assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
995
    assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
996
    assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
997
 
998
    counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600) + \
999
      ((uint32_t)sAlarm->AlarmTime.Minutes * 60) + \
1000
        ((uint32_t)sAlarm->AlarmTime.Seconds));  
1001
  }
1002
  else
1003
  {
1004
    assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
1005
    assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
1006
    assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
1007
 
1008
    counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600) + \
1009
      ((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60) + \
1010
        ((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));  
1011
  }
1012
 
1013
  /* Check that requested alarm should expire in the same day (otherwise add 1 day) */
1014
  if (counter_alarm < counter_time)
1015
  {
1016
    /* Add 1 day to alarm counter*/
1017
    counter_alarm += (uint32_t)(24 * 3600);
1018
  }
1019
 
1020
  /* Write alarm counter in RTC registers */
1021
  if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
1022
  {
1023
    /* Set RTC state */
1024
    hrtc->State = HAL_RTC_STATE_ERROR;
1025
 
1026
    /* Process Unlocked */
1027
    __HAL_UNLOCK(hrtc);
1028
 
1029
    return HAL_ERROR;
1030
  }
1031
  else
1032
  {
1033
    /* Clear flag alarm A */
1034
    __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1035
 
1036
    /* Configure the Alarm interrupt */
1037
    __HAL_RTC_ALARM_ENABLE_IT(hrtc,RTC_IT_ALRA);
1038
 
1039
    /* RTC Alarm Interrupt Configuration: EXTI configuration */
1040
    __HAL_RTC_ALARM_EXTI_ENABLE_IT();
1041
 
1042
    __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
1043
 
1044
    hrtc->State = HAL_RTC_STATE_READY;
1045
 
1046
   __HAL_UNLOCK(hrtc);
1047
 
1048
   return HAL_OK;
1049
  }
1050
}
1051
 
1052
/**
1053
  * @brief  Gets the RTC Alarm value and masks.
1054
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1055
  *                the configuration information for RTC.
1056
  * @param  sAlarm: Pointer to Date structure
1057
  * @param  Alarm: Specifies the Alarm.
1058
  *          This parameter can be one of the following values:
1059
  *             @arg RTC_ALARM_A: Alarm
1060
  * @param  Format: Specifies the format of the entered parameters.
1061
  *          This parameter can be one of the following values:
1062
  *             @arg RTC_FORMAT_BIN: Binary data format
1063
  *             @arg RTC_FORMAT_BCD: BCD data format
1064
  * @retval HAL status
1065
  */
1066
HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Alarm, uint32_t Format)
1067
{
1068
  uint32_t counter_alarm = 0;
1069
 
1070
  /* Check input parameters */
1071
  if((hrtc == NULL) || (sAlarm == NULL))
1072
  {
1073
     return HAL_ERROR;
1074
  }
1075
 
1076
  /* Check the parameters */
1077
  assert_param(IS_RTC_FORMAT(Format));
1078
  assert_param(IS_RTC_ALARM(Alarm));
1079
 
1080
  /* Read Alarm counter in RTC registers */
1081
  counter_alarm = RTC_ReadAlarmCounter(hrtc);
1082
 
1083
  /* Fill the structure with the read parameters */
1084
  /* Set hours in a day range (between 0 to 24)*/
1085
  sAlarm->AlarmTime.Hours   = (uint32_t)((counter_alarm / 3600) % 24);
1086
  sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600) / 60);
1087
  sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600) % 60);
1088
 
1089
  if(Format != RTC_FORMAT_BIN)
1090
  {
1091
    sAlarm->AlarmTime.Hours   = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours);
1092
    sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes);
1093
    sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds);
1094
  }  
1095
 
1096
  return HAL_OK;
1097
}
1098
 
1099
/**
1100
  * @brief  Deactive the specified RTC Alarm
1101
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1102
  *                the configuration information for RTC.
1103
  * @param  Alarm: Specifies the Alarm.
1104
  *          This parameter can be one of the following values:
1105
  *            @arg RTC_ALARM_A:  AlarmA
1106
  * @retval HAL status
1107
  */
1108
HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc, uint32_t Alarm)
1109
{
1110
  /* Check the parameters */
1111
  assert_param(IS_RTC_ALARM(Alarm));
1112
 
1113
  /* Check input parameters */
1114
  if(hrtc == NULL)
1115
  {
1116
     return HAL_ERROR;
1117
  }
1118
 
1119
  /* Process Locked */
1120
  __HAL_LOCK(hrtc);
1121
 
1122
  hrtc->State = HAL_RTC_STATE_BUSY;
1123
 
1124
  /* In case of interrupt mode is used, the interrupt source must disabled */
1125
  __HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
1126
 
1127
  /* Set Initialization mode */
1128
  if(RTC_EnterInitMode(hrtc) != HAL_OK)
1129
  {
1130
    /* Set RTC state */
1131
    hrtc->State = HAL_RTC_STATE_ERROR;
1132
 
1133
    /* Process Unlocked */
1134
    __HAL_UNLOCK(hrtc);
1135
 
1136
    return HAL_ERROR;
1137
  }
1138
  else
1139
  {
1140
    /* Clear flag alarm A */
1141
    __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1142
 
1143
    /* Set to default values ALRH & ALRL registers */
1144
    WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER);
1145
    WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER);
1146
 
1147
    /* RTC Alarm Interrupt Configuration: Disable EXTI configuration */
1148
    __HAL_RTC_ALARM_EXTI_DISABLE_IT();
1149
 
1150
    /* Wait for synchro */
1151
    if(RTC_ExitInitMode(hrtc) != HAL_OK)
1152
    {      
1153
      hrtc->State = HAL_RTC_STATE_ERROR;
1154
 
1155
      /* Process Unlocked */
1156
      __HAL_UNLOCK(hrtc);
1157
 
1158
      return HAL_ERROR;
1159
    }
1160
  }
1161
  hrtc->State = HAL_RTC_STATE_READY;
1162
 
1163
  /* Process Unlocked */
1164
  __HAL_UNLOCK(hrtc);  
1165
 
1166
  return HAL_OK;
1167
}
1168
 
1169
/**
1170
  * @brief  This function handles Alarm interrupt request.
1171
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1172
  *                the configuration information for RTC.
1173
  * @retval None
1174
  */
1175
void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef* hrtc)
1176
{  
1177
  if(__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
1178
  {
1179
    /* Get the status of the Interrupt */
1180
    if(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
1181
    {
1182
      /* AlarmA callback */
1183
      HAL_RTC_AlarmAEventCallback(hrtc);
1184
 
1185
      /* Clear the Alarm interrupt pending bit */
1186
      __HAL_RTC_ALARM_CLEAR_FLAG(hrtc,RTC_FLAG_ALRAF);
1187
    }
1188
  }
1189
 
1190
  /* Clear the EXTI's line Flag for RTC Alarm */
1191
  __HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
1192
 
1193
  /* Change RTC state */
1194
  hrtc->State = HAL_RTC_STATE_READY;
1195
}
1196
 
1197
/**
1198
  * @brief  Alarm A callback.
1199
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1200
  *                the configuration information for RTC.
1201
  * @retval None
1202
  */
1203
__weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
1204
{
5 mjames 1205
  /* Prevent unused argument(s) compilation warning */
1206
  UNUSED(hrtc);
2 mjames 1207
  /* NOTE : This function Should not be modified, when the callback is needed,
1208
            the HAL_RTC_AlarmAEventCallback could be implemented in the user file
1209
   */
1210
}
1211
 
1212
/**
1213
  * @brief  This function handles AlarmA Polling request.
1214
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1215
  *                the configuration information for RTC.
1216
  * @param  Timeout: Timeout duration
1217
  * @retval HAL status
1218
  */
1219
HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
1220
{  
1221
  uint32_t tickstart = HAL_GetTick();  
1222
 
1223
  /* Check input parameters */
1224
  if(hrtc == NULL)
1225
  {
1226
     return HAL_ERROR;
1227
  }
1228
 
1229
  while(__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
1230
  {
1231
    if(Timeout != HAL_MAX_DELAY)
1232
    {
1233
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
1234
      {
1235
        hrtc->State = HAL_RTC_STATE_TIMEOUT;
1236
        return HAL_TIMEOUT;
1237
      }
1238
    }
1239
  }
1240
 
1241
  /* Clear the Alarm interrupt pending bit */
1242
  __HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
1243
 
1244
  /* Change RTC state */
1245
  hrtc->State = HAL_RTC_STATE_READY;
1246
 
1247
  return HAL_OK;  
1248
}
1249
 
1250
/**
1251
  * @}
1252
  */
1253
 
1254
/** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions
1255
 *  @brief   Peripheral State functions
1256
 *
1257
@verbatim  
1258
 ===============================================================================
1259
                     ##### Peripheral State functions #####
1260
 ===============================================================================  
1261
    [..]
1262
    This subsection provides functions allowing to
1263
      (+) Get RTC state
1264
 
1265
@endverbatim
1266
  * @{
1267
  */
1268
/**
1269
  * @brief  Returns the RTC state.
1270
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1271
  *                the configuration information for RTC.
1272
  * @retval HAL state
1273
  */
1274
HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef* hrtc)
1275
{
1276
  return hrtc->State;
1277
}
1278
 
1279
/**
1280
  * @}
1281
  */
1282
 
1283
/** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions
1284
 *  @brief   Peripheral Control functions
1285
 *
1286
@verbatim  
1287
 ===============================================================================
1288
                     ##### Peripheral Control functions #####
1289
 ===============================================================================  
1290
    [..]
1291
    This subsection provides functions allowing to
1292
      (+) Wait for RTC Time and Date Synchronization
1293
 
1294
@endverbatim
1295
  * @{
1296
  */
1297
 
1298
/**
1299
  * @brief  Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL)
1300
  *   are synchronized with RTC APB clock.
1301
  * @note   This function must be called before any read operation after an APB reset
1302
  *   or an APB clock stop.
1303
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1304
  *                the configuration information for RTC.
1305
  * @retval HAL status
1306
  */
1307
HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef* hrtc)
1308
{
1309
  uint32_t tickstart = 0;
1310
 
1311
  /* Check input parameters */
1312
  if(hrtc == NULL)
1313
  {
1314
     return HAL_ERROR;
1315
  }
1316
 
1317
  /* Clear RSF flag */
1318
  CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
1319
 
1320
  tickstart = HAL_GetTick();
1321
 
1322
  /* Wait the registers to be synchronised */
1323
  while((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET)
1324
  {
1325
    if((HAL_GetTick() - tickstart ) >  RTC_TIMEOUT_VALUE)
1326
    {      
1327
      return HAL_TIMEOUT;
1328
    }
1329
  }
1330
 
1331
  return HAL_OK;
1332
}
1333
 
1334
/**
1335
  * @}
1336
  */
1337
 
1338
 
1339
/**
1340
  * @}
1341
  */
1342
 
1343
/** @addtogroup RTC_Private_Functions
1344
  * @{
1345
  */
1346
 
1347
 
1348
/**
1349
  * @brief  Read the time counter available in RTC_CNT registers.
1350
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1351
  *                the configuration information for RTC.
1352
  * @retval Time counter
1353
  */
1354
static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef* hrtc)
1355
{
1356
  uint16_t high1 = 0, high2 = 0, low = 0;
1357
  uint32_t timecounter = 0;
1358
 
1359
  high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
1360
  low   = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
1361
  high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
1362
 
1363
  if (high1 != high2)
1364
  { /* In this case the counter roll over during reading of CNTL and CNTH registers,
1365
       read again CNTL register then return the counter value */
1366
    timecounter = (((uint32_t) high2 << 16 ) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
1367
  }
1368
  else
1369
  { /* No counter roll over during reading of CNTL and CNTH registers, counter
1370
       value is equal to first value of CNTL and CNTH */
1371
    timecounter = (((uint32_t) high1 << 16 ) | low);
1372
  }
1373
 
1374
  return timecounter;
1375
}
1376
 
1377
/**
1378
  * @brief  Write the time counter in RTC_CNT registers.
1379
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1380
  *                the configuration information for RTC.
1381
  * @param  TimeCounter: Counter to write in RTC_CNT registers
1382
  * @retval HAL status
1383
  */
1384
static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef* hrtc, uint32_t TimeCounter)
1385
{
1386
  HAL_StatusTypeDef status = HAL_OK;
1387
 
1388
  /* Set Initialization mode */
1389
  if(RTC_EnterInitMode(hrtc) != HAL_OK)
1390
  {
1391
    status = HAL_ERROR;
1392
  }
1393
  else
1394
  {
1395
    /* Set RTC COUNTER MSB word */
1396
    WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16));
1397
    /* Set RTC COUNTER LSB word */
1398
    WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
1399
 
1400
    /* Wait for synchro */
1401
    if(RTC_ExitInitMode(hrtc) != HAL_OK)
1402
    {      
1403
      status = HAL_ERROR;
1404
    }
1405
  }
1406
 
1407
  return status;
1408
}
1409
 
1410
/**
1411
  * @brief  Read the time counter available in RTC_ALR registers.
1412
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1413
  *                the configuration information for RTC.
1414
  * @retval Time counter
1415
  */
1416
static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef* hrtc)
1417
{
1418
  uint16_t high1 = 0, low = 0;
1419
 
1420
  high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT);
1421
  low   = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT);
1422
 
1423
  return (((uint32_t) high1 << 16 ) | low);
1424
}
1425
 
1426
/**
1427
  * @brief  Write the time counter in RTC_ALR registers.
1428
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1429
  *                the configuration information for RTC.
1430
  * @param  AlarmCounter: Counter to write in RTC_ALR registers
1431
  * @retval HAL status
1432
  */
1433
static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter)
1434
{
1435
  HAL_StatusTypeDef status = HAL_OK;
1436
 
1437
  /* Set Initialization mode */
1438
  if(RTC_EnterInitMode(hrtc) != HAL_OK)
1439
  {
1440
    status = HAL_ERROR;
1441
  }
1442
  else
1443
  {
1444
    /* Set RTC COUNTER MSB word */
1445
    WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16));
1446
    /* Set RTC COUNTER LSB word */
1447
    WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
1448
 
1449
    /* Wait for synchro */
1450
    if(RTC_ExitInitMode(hrtc) != HAL_OK)
1451
    {      
1452
      status = HAL_ERROR;
1453
    }
1454
  }
1455
 
1456
  return status;
1457
}
1458
 
1459
/**
1460
  * @brief  Enters the RTC Initialization mode.
1461
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1462
  *                the configuration information for RTC.
1463
  * @retval HAL status
1464
  */
1465
static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
1466
{
1467
  uint32_t tickstart = 0;
1468
 
1469
  tickstart = HAL_GetTick();
1470
  /* Wait till RTC is in INIT state and if Time out is reached exit */
1471
  while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
1472
  {
1473
    if((HAL_GetTick() - tickstart) >  RTC_TIMEOUT_VALUE)
1474
    {      
1475
      return HAL_TIMEOUT;
1476
    }
1477
  }
1478
 
1479
  /* Disable the write protection for RTC registers */
1480
  __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
1481
 
1482
 
1483
  return HAL_OK;  
1484
}
1485
 
1486
/**
1487
  * @brief  Exit the RTC Initialization mode.
1488
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1489
  *                the configuration information for RTC.
1490
  * @retval HAL status
1491
  */
1492
static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef* hrtc)
1493
{
1494
  uint32_t tickstart = 0;
1495
 
1496
  /* Disable the write protection for RTC registers */
1497
  __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
1498
 
1499
  tickstart = HAL_GetTick();
1500
  /* Wait till RTC is in INIT state and if Time out is reached exit */
1501
  while((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
1502
  {
1503
    if((HAL_GetTick() - tickstart) >  RTC_TIMEOUT_VALUE)
1504
    {      
1505
      return HAL_TIMEOUT;
1506
    }
1507
  }
1508
 
1509
  return HAL_OK;  
1510
}
1511
 
1512
/**
1513
  * @brief  Converts a 2 digit decimal to BCD format.
1514
  * @param  Value: Byte to be converted
1515
  * @retval Converted byte
1516
  */
1517
static uint8_t RTC_ByteToBcd2(uint8_t Value)
1518
{
1519
  uint32_t bcdhigh = 0;
1520
 
1521
  while(Value >= 10)
1522
  {
1523
    bcdhigh++;
1524
    Value -= 10;
1525
  }
1526
 
1527
  return  ((uint8_t)(bcdhigh << 4) | Value);
1528
}
1529
 
1530
/**
1531
  * @brief  Converts from 2 digit BCD to Binary.
1532
  * @param  Value: BCD value to be converted
1533
  * @retval Converted word
1534
  */
1535
static uint8_t RTC_Bcd2ToByte(uint8_t Value)
1536
{
1537
  uint32_t tmp = 0;
1538
  tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10;
1539
  return (tmp + (Value & (uint8_t)0x0F));
1540
}
1541
 
1542
/**
1543
  * @brief  Updates date when time is 23:59:59.
1544
  * @param  hrtc   pointer to a RTC_HandleTypeDef structure that contains
1545
  *                the configuration information for RTC.
1546
  * @param  DayElapsed: Number of days elapsed from last date update
1547
  * @retval None
1548
  */
1549
static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed)
1550
{
1551
  uint32_t year = 0, month = 0, day = 0;
1552
  uint32_t loop = 0;
1553
 
1554
  /* Get the current year*/
1555
  year = hrtc->DateToUpdate.Year;
1556
 
1557
  /* Get the current month and day */
1558
  month = hrtc->DateToUpdate.Month;
1559
  day = hrtc->DateToUpdate.Date;
1560
 
1561
  for (loop = 0; loop < DayElapsed; loop++)
1562
  {
1563
    if((month == 1) || (month == 3) || (month == 5) || (month == 7) || \
1564
       (month == 8) || (month == 10) || (month == 12))
1565
    {
1566
      if(day < 31)
1567
      {
1568
        day++;
1569
      }
1570
      /* Date structure member: day = 31 */
1571
      else
1572
      {
1573
        if(month != 12)
1574
        {
1575
          month++;
1576
          day = 1;
1577
        }
1578
        /* Date structure member: day = 31 & month =12 */
1579
        else
1580
        {
1581
          month = 1;
1582
          day = 1;
1583
          year++;
1584
        }
1585
      }
1586
    }
1587
    else if((month == 4) || (month == 6) || (month == 9) || (month == 11))
1588
    {
1589
      if(day < 30)
1590
      {
1591
        day++;
1592
      }
1593
      /* Date structure member: day = 30 */
1594
      else
1595
      {
1596
        month++;
1597
        day = 1;
1598
      }
1599
    }
1600
    else if(month == 2)
1601
    {
1602
      if(day < 28)
1603
      {
1604
        day++;
1605
      }
1606
      else if(day == 28)
1607
      {
1608
        /* Leap year */
1609
        if(RTC_IsLeapYear(year))
1610
        {
1611
          day++;
1612
        }
1613
        else
1614
        {
1615
          month++;
1616
          day = 1;
1617
        }
1618
      }
1619
      else if(day == 29)
1620
      {
1621
        month++;
1622
        day = 1;
1623
      }
1624
    }
1625
  }
1626
 
1627
  /* Update year */
1628
  hrtc->DateToUpdate.Year = year;
1629
 
1630
  /* Update day and month */
1631
  hrtc->DateToUpdate.Month = month;
1632
  hrtc->DateToUpdate.Date = day;
1633
 
1634
  /* Update day of the week */
1635
  hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
1636
}
1637
 
1638
/**
1639
  * @brief  Check whether the passed year is Leap or not.
1640
  * @param  nYear  year to check
1641
  * @retval 1: leap year
1642
  *         0: not leap year
1643
  */
1644
static uint8_t RTC_IsLeapYear(uint16_t nYear)
1645
{
1646
  if((nYear % 4) != 0)
1647
  {
1648
    return 0;
1649
  }
1650
 
1651
  if((nYear % 100) != 0)
1652
  {
1653
    return 1;
1654
  }
1655
 
1656
  if((nYear % 400) == 0)
1657
  {
1658
    return 1;
1659
  }
1660
  else
1661
  {
1662
    return 0;
1663
  }
1664
}
1665
 
1666
/**
1667
  * @brief  Determines the week number, the day number and the week day number.
1668
  * @param  nYear   year to check
1669
  * @param  nMonth  Month to check
1670
  * @param  nDay    Day to check
1671
  * @note   Day is calculated with hypothesis that year > 2000
1672
  * @retval Value which can take one of the following parameters:
1673
  *         @arg RTC_WEEKDAY_MONDAY
1674
  *         @arg RTC_WEEKDAY_TUESDAY
1675
  *         @arg RTC_WEEKDAY_WEDNESDAY
1676
  *         @arg RTC_WEEKDAY_THURSDAY
1677
  *         @arg RTC_WEEKDAY_FRIDAY
1678
  *         @arg RTC_WEEKDAY_SATURDAY
1679
  *         @arg RTC_WEEKDAY_SUNDAY
1680
  */
1681
static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
1682
{
1683
  uint32_t year = 0, weekday = 0;
1684
 
1685
  year = 2000 + nYear;
1686
 
1687
  if(nMonth < 3)
1688
  {
1689
    /*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
1690
    weekday = (((23 * nMonth)/9) + nDay + 4 + year + ((year-1)/4) - ((year-1)/100) + ((year-1)/400)) % 7;
1691
  }
1692
  else
1693
  {
1694
    /*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
1695
    weekday = (((23 * nMonth)/9) + nDay + 4 + year + (year/4) - (year/100) + (year/400) - 2 ) % 7;
1696
  }
1697
 
1698
  return (uint8_t)weekday;
1699
}
1700
 
1701
/**
1702
  * @}
1703
  */
1704
 
1705
#endif /* HAL_RTC_MODULE_ENABLED */
1706
/**
1707
  * @}
1708
  */
1709
 
1710
/**
1711
  * @}
1712
  */
1713
 
1714
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/