Subversion Repositories LedShow

Rev

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

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