Subversion Repositories FuelGauge

Rev

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

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f0xx_hal_timebase_rtc_alarm_template.c
  4.   * @brief   HAL time base based on the hardware RTC_ALARM Template.
  5.   *
  6.   *          This file override the native HAL time base functions (defined as weak)
  7.   *          to use the RTC ALARM for time base generation:
  8.   *           + Intializes the RTC peripheral to increment the seconds registers each 1ms
  9.   *           + The alarm is configured to assert an interrupt when the RTC reaches 1ms
  10.   *           + HAL_IncTick is called at each Alarm event and the time is reset to 00:00:00
  11.   *           + HSE (default), LSE or LSI can be selected as RTC clock source  
  12.  @verbatim
  13.   ==============================================================================
  14.                         ##### How to use this driver #####
  15.   ==============================================================================
  16.     [..]
  17.     This file must be copied to the application folder and modified as follows:
  18.     (#) Rename it to 'stm32f0xx_hal_timebase_rtc_alarm.c'
  19.     (#) Add this file and the RTC HAL drivers to your project and uncomment
  20.        HAL_RTC_MODULE_ENABLED define in stm32f0xx_hal_conf.h
  21.  
  22.     [..]
  23.     (@) HAL RTC alarm and HAL RTC wakeup drivers can’t be used with low power modes:
  24.         The wake up capability of the RTC may be intrusive in case of prior low power mode
  25.         configuration requiring different wake up sources.
  26.         Application/Example behavior is no more guaranteed
  27.     (@) The stm32f0xx_hal_timebase_tim use is recommended for the Applications/Examples
  28.           requiring low power modes
  29.  
  30.   @endverbatim
  31.   ******************************************************************************
  32.   * @attention
  33.   *
  34.   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  35.   * All rights reserved.</center></h2>
  36.   *
  37.   * This software component is licensed by ST under BSD 3-Clause license,
  38.   * the "License"; You may not use this file except in compliance with the
  39.   * License. You may obtain a copy of the License at:
  40.   *                        opensource.org/licenses/BSD-3-Clause
  41.   *
  42.   ******************************************************************************
  43.   */
  44.  
  45. /* Includes ------------------------------------------------------------------*/
  46. #include "stm32f0xx_hal.h"
  47. /** @addtogroup STM32F0xx_HAL_Driver
  48.   * @{
  49.   */
  50.  
  51. /** @defgroup HAL_TimeBase_RTC_Alarm_Template  HAL TimeBase RTC Alarm Template
  52.   * @{
  53.   */
  54.  
  55. /* Private typedef -----------------------------------------------------------*/
  56. /* Private define ------------------------------------------------------------*/
  57.  
  58. /* Uncomment the line below to select the appropriate RTC Clock source for your application:
  59.   + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
  60.   + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
  61.                           precision.
  62.   + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
  63.                           precision.
  64.   */
  65. #define RTC_CLOCK_SOURCE_HSE
  66. /* #define RTC_CLOCK_SOURCE_LSE */
  67. /* #define RTC_CLOCK_SOURCE_LSI */
  68.  
  69. #if defined(RTC_CLOCK_SOURCE_HSE)
  70.   #define RTC_ASYNCH_PREDIV       49U
  71.   #define RTC_SYNCH_PREDIV        4U
  72. #elif defined(RTC_CLOCK_SOURCE_LSE)
  73.   #define RTC_ASYNCH_PREDIV       0U
  74.   #define RTC_SYNCH_PREDIV        31U
  75. #else        /* CLOCK_SOURCE_LSI */
  76.   #define RTC_ASYNCH_PREDIV       0U
  77.   #define RTC_SYNCH_PREDIV        39U
  78. #endif       /* RTC_CLOCK_SOURCE_HSE */
  79.  
  80. /* Private macro -------------------------------------------------------------*/
  81. /* Private variables ---------------------------------------------------------*/
  82. RTC_HandleTypeDef        hRTC_Handle;
  83. /* Private function prototypes -----------------------------------------------*/
  84. void RTC_IRQHandler(void);
  85. /* Private functions ---------------------------------------------------------*/
  86.  
  87. /**
  88.   * @brief  This function configures the RTC_ALARMA as a time base source.
  89.   *         The time source is configured  to have 1ms time base with a dedicated
  90.   *         Tick interrupt priority.
  91.   * @note   This function is called  automatically at the beginning of program after
  92.   *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
  93.   * @param  TickPriority Tick interrupt priority.
  94.   * @retval HAL status
  95.   */
  96. HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority)
  97. {
  98.   __IO uint32_t counter = 0U;
  99.  
  100.   RCC_OscInitTypeDef        RCC_OscInitStruct;
  101.   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
  102.   HAL_StatusTypeDef     status;
  103.  
  104. #ifdef RTC_CLOCK_SOURCE_LSE
  105.   /* Configue LSE as RTC clock soucre */
  106.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  107.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  108.   RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  109.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  110. #elif defined (RTC_CLOCK_SOURCE_LSI)
  111.   /* Configue LSI as RTC clock soucre */
  112.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
  113.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  114.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  115.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  116. #elif defined (RTC_CLOCK_SOURCE_HSE)
  117.   /* Configue HSE as RTC clock soucre */
  118.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  119.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  120.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  121.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32;
  122. #else
  123. #error Please select the RTC Clock source
  124. #endif /* RTC_CLOCK_SOURCE_LSE */
  125.  
  126.   status = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  127.   if (status == HAL_OK)
  128.   {
  129.     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  130.     status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
  131.   }
  132.   if (status == HAL_OK)
  133.   {
  134.     /* Enable RTC Clock */
  135.     __HAL_RCC_RTC_ENABLE();
  136.     /* The time base should be 1ms
  137.        Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK
  138.        HSE/32 as RTC clock and HSE 8MHz
  139.          Time base = ((49 + 1) * (4 + 1)) / 250kHz
  140.                    = 1ms
  141.        LSE as RTC clock
  142.          Time base = ((31 + 1) * (0 + 1)) / 32.768KHz
  143.                    = ~1ms
  144.        LSI as RTC clock
  145.          Time base = ((39 + 1) * (0 + 1)) / 40KHz
  146.                    = 1ms
  147.     */
  148.     hRTC_Handle.Instance = RTC;
  149.     hRTC_Handle.Init.HourFormat = RTC_HOURFORMAT_24;
  150.     hRTC_Handle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  151.     hRTC_Handle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  152.     hRTC_Handle.Init.OutPut = RTC_OUTPUT_DISABLE;
  153.     hRTC_Handle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  154.     hRTC_Handle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  155.     status = HAL_RTC_Init(&hRTC_Handle);
  156.  
  157.     /* Disable the write protection for RTC registers */
  158.     __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
  159.  
  160.     /* Disable the Alarm A interrupt */
  161.     __HAL_RTC_ALARMA_DISABLE(&hRTC_Handle);
  162.  
  163.     /* Clear flag alarm A */
  164.     __HAL_RTC_ALARM_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_ALRAF);
  165.  
  166.     counter = 0U;
  167.     /* Wait till RTC ALRAWF flag is set and if Time out is reached exit */
  168.     while (__HAL_RTC_ALARM_GET_FLAG(&hRTC_Handle, RTC_FLAG_ALRAWF) == RESET)
  169.     {
  170.       if (counter++ == (SystemCoreClock / 48U)) /* Timeout = ~ 1s */
  171.       {
  172.         status = HAL_ERROR;
  173.       }
  174.     }
  175.   }
  176.   if (status == HAL_OK)
  177.   {
  178.     hRTC_Handle.Instance->ALRMAR = 0x01U;
  179.  
  180.     /* Configure the Alarm state: Enable Alarm */
  181.     __HAL_RTC_ALARMA_ENABLE(&hRTC_Handle);
  182.     /* Configure the Alarm interrupt */
  183.     __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
  184.  
  185.     /* RTC Alarm Interrupt Configuration: EXTI configuration */
  186.     __HAL_RTC_ALARM_EXTI_ENABLE_IT();
  187.     __HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
  188.  
  189.     /* Check if the Initialization mode is set */
  190.     if ((hRTC_Handle.Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
  191.     {
  192.       /* Set the Initialization mode */
  193.       hRTC_Handle.Instance->ISR = (uint32_t)RTC_INIT_MASK;
  194.       counter = 0U;
  195.       while ((hRTC_Handle.Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
  196.       {
  197.         if (counter++ == (SystemCoreClock / 48U)) /* Timeout = ~ 1s */
  198.         {
  199.           status = HAL_ERROR;
  200.         }
  201.       }
  202.     }
  203.   }
  204.   if (status == HAL_OK)
  205.   {
  206.     hRTC_Handle.Instance->DR = 0U;
  207.     hRTC_Handle.Instance->TR = 0U;
  208.  
  209.     hRTC_Handle.Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
  210.  
  211.     /* Enable the write protection for RTC registers */
  212.     __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  213.  
  214.     /* Enable the RTC Alarm Interrupt */
  215.     HAL_NVIC_EnableIRQ(RTC_IRQn);
  216.  
  217.     /* Configure the SysTick IRQ priority */
  218.     if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  219.     {
  220.       HAL_NVIC_SetPriority(RTC_IRQn, TickPriority, 0U);
  221.       uwTickPrio = TickPriority;
  222.     }
  223.     else
  224.     {
  225.       status = HAL_ERROR;
  226.     }
  227.  
  228.   }
  229.   return status;
  230. }
  231.  
  232. /**
  233.   * @brief  Suspend Tick increment.
  234.   * @note   Disable the tick increment by disabling RTC ALARM interrupt.
  235.   * @param  None
  236.   * @retval None
  237.   */
  238. void HAL_SuspendTick(void)
  239. {
  240.   /* Disable the write protection for RTC registers */
  241.   __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
  242.   /* Disable RTC ALARM update Interrupt */
  243.   __HAL_RTC_ALARM_DISABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
  244.   /* Enable the write protection for RTC registers */
  245.   __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  246. }
  247.  
  248. /**
  249.   * @brief  Resume Tick increment.
  250.   * @note   Enable the tick increment by Enabling RTC ALARM interrupt.
  251.   * @param  None
  252.   * @retval None
  253.   */
  254. void HAL_ResumeTick(void)
  255. {
  256.   /* Disable the write protection for RTC registers */
  257.   __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
  258.   /* Enable RTC ALARM Update interrupt */
  259.   __HAL_RTC_ALARM_ENABLE_IT(&hRTC_Handle, RTC_IT_ALRA);
  260.   /* Enable the write protection for RTC registers */
  261.   __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  262. }
  263.  
  264. /**
  265.   * @brief  ALARM A Event Callback in non blocking mode
  266.   * @note   This function is called  when RTC_ALARM interrupt took place, inside
  267.   * RTC_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
  268.   * a global variable "uwTick" used as application time base.
  269.   * @param  hrtc RTC handle
  270.   * @retval None
  271.   */
  272. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
  273. {
  274.   __IO uint32_t counter = 0U;
  275.  
  276.   HAL_IncTick();
  277.  
  278.   __HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
  279.  
  280.   /* Set the Initialization mode */
  281.   hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK;
  282.  
  283.   while((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
  284.   {
  285.     if(counter++ == (SystemCoreClock /48U)) /* Timeout = ~ 1s */
  286.     {
  287.       break;
  288.     }
  289.   }
  290.  
  291.   hrtc->Instance->DR = 0U;
  292.   hrtc->Instance->TR = 0U;
  293.  
  294.   hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
  295.  
  296.   /* Enable the write protection for RTC registers */
  297.   __HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
  298. }
  299.  
  300. /**
  301.   * @brief  This function handles RTC ALARM interrupt request.
  302.   * @param  None
  303.   * @retval None
  304.   */
  305. void RTC_IRQHandler(void)
  306. {
  307.   HAL_RTC_AlarmIRQHandler(&hRTC_Handle);
  308. }
  309.  
  310. /**
  311.   * @}
  312.   */
  313.  
  314. /**
  315.   * @}
  316.   */
  317.  
  318. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  319.