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_wakeup_template.c
  4.   * @brief   HAL time base based on the hardware RTC_WAKEUP Template.
  5.   *    
  6.   *          This file overrides the native HAL time base functions (defined as weak)
  7.   *          to use the RTC WAKEUP for the time base generation:
  8.   *           + Intializes the RTC peripheral and configures the wakeup timer to be
  9.   *             incremented each 1ms
  10.   *           + The wakeup feature is configured to assert an interrupt each 1ms
  11.   *           + HAL_IncTick is called inside the HAL_RTCEx_WakeUpTimerEventCallback
  12.   *           + HSE (default), LSE or LSI can be selected as RTC clock source
  13.  @verbatim
  14.   ==============================================================================
  15.                         ##### How to use this driver #####
  16.   ==============================================================================
  17.     [..]
  18.     This file must be copied to the application folder and modified as follows:
  19.     (#) Rename it to 'stm32f0xx_hal_timebase_rtc_wakeup.c'
  20.     (#) Add this file and the RTC HAL drivers to your project and uncomment
  21.        HAL_RTC_MODULE_ENABLED define in stm32f0xx_hal_conf.h
  22.  
  23.     [..]
  24.     (@) HAL RTC alarm and HAL RTC wakeup drivers can’t be used with low power modes:
  25.         The wake up capability of the RTC may be intrusive in case of prior low power mode
  26.         configuration requiring different wake up sources.
  27.         Application/Example behavior is no more guaranteed
  28.     (@) The stm32f0xx_hal_timebase_tim use is recommended for the Applications/Examples
  29.           requiring low power modes
  30.  
  31.   @endverbatim
  32.   ******************************************************************************
  33.   * @attention
  34.   *
  35.   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  36.   * All rights reserved.</center></h2>
  37.   *
  38.   * This software component is licensed by ST under BSD 3-Clause license,
  39.   * the "License"; You may not use this file except in compliance with the
  40.   * License. You may obtain a copy of the License at:
  41.   *                        opensource.org/licenses/BSD-3-Clause
  42.   *
  43.   ******************************************************************************
  44.   */
  45.  
  46. /* Includes ------------------------------------------------------------------*/
  47. #include "stm32f0xx_hal.h"
  48. /** @addtogroup STM32F0xx_HAL_Driver
  49.   * @{
  50.   */
  51.  
  52. /** @defgroup HAL_TimeBase_RTC_WakeUp_Template  HAL TimeBase RTC WakeUp Template
  53.   * @{
  54.   */
  55.  
  56. /* Private typedef -----------------------------------------------------------*/
  57. /* Private define ------------------------------------------------------------*/
  58.  
  59. /* Uncomment the line below to select the appropriate RTC Clock source for your application:
  60.   + RTC_CLOCK_SOURCE_HSE: can be selected for applications requiring timing precision.
  61.   + RTC_CLOCK_SOURCE_LSE: can be selected for applications with low constraint on timing
  62.                           precision.
  63.   + RTC_CLOCK_SOURCE_LSI: can be selected for applications with low constraint on timing
  64.                           precision.
  65.   */
  66. #define RTC_CLOCK_SOURCE_HSE
  67. /* #define RTC_CLOCK_SOURCE_LSE */
  68. /* #define RTC_CLOCK_SOURCE_LSI */
  69.  
  70. #if defined(RTC_CLOCK_SOURCE_HSE)
  71.   #define RTC_ASYNCH_PREDIV       49U
  72.   #define RTC_SYNCH_PREDIV        4U
  73. #elif defined(RTC_CLOCK_SOURCE_LSE)
  74.   #define RTC_ASYNCH_PREDIV       0U
  75.   #define RTC_SYNCH_PREDIV        31U
  76. #else        /* CLOCK_SOURCE_LSI */
  77.   #define RTC_ASYNCH_PREDIV       0U
  78.   #define RTC_SYNCH_PREDIV        39U
  79. #endif       /* RTC_CLOCK_SOURCE_HSE */
  80.  
  81. /* Private macro -------------------------------------------------------------*/
  82. /* Private variables ---------------------------------------------------------*/
  83. RTC_HandleTypeDef        hRTC_Handle;
  84.  
  85. /* Private function prototypes -----------------------------------------------*/
  86. void RTC_IRQHandler(void);
  87.  
  88. /* Private functions ---------------------------------------------------------*/
  89.  
  90. /**
  91.   * @brief  This function configures the RTC_WKUP as a time base source.
  92.   *         The time source is configured  to have 1ms time base with a dedicated
  93.   *         Tick interrupt priority.
  94.   *         Wakeup Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK
  95.                              = 1ms
  96.   *         Wakeup Time = WakeupTimebase * WakeUpCounter (0 + 1)
  97.                         = 1 ms
  98.   * @note   This function is called  automatically at the beginning of program after
  99.   *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
  100.   * @param  TickPriority Tick interrupt priority.
  101.   * @retval HAL status
  102.   */
  103. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
  104. {
  105.   __IO uint32_t counter = 0U;
  106.  
  107.   RCC_OscInitTypeDef        RCC_OscInitStruct;
  108.   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
  109.   HAL_StatusTypeDef     status;
  110.  
  111. #ifdef RTC_CLOCK_SOURCE_LSE
  112.   /* Configue LSE as RTC clock soucre */
  113.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
  114.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  115.   RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  116.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  117. #elif defined (RTC_CLOCK_SOURCE_LSI)
  118.   /* Configue LSI as RTC clock soucre */
  119.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
  120.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  121.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  122.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  123. #elif defined (RTC_CLOCK_SOURCE_HSE)
  124.   /* Configue HSE as RTC clock soucre */
  125.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  126.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  127.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  128.   PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV32;
  129. #else
  130. #error Please select the RTC Clock source
  131. #endif /* RTC_CLOCK_SOURCE_LSE */
  132.  
  133.   status = HAL_RCC_OscConfig(&RCC_OscInitStruct);
  134.   if (status == HAL_OK)
  135.   {
  136.     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  137.     status = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
  138.   }
  139.   if (status == HAL_OK)
  140.   {
  141.     /* Enable RTC Clock */
  142.     __HAL_RCC_RTC_ENABLE();
  143.     /* The time base should be 1ms
  144.        Time base = ((RTC_ASYNCH_PREDIV + 1) * (RTC_SYNCH_PREDIV + 1)) / RTC_CLOCK
  145.        HSE/32 as RTC clock and HSE 8MHz
  146.          Time base = ((49 + 1) * (4 + 1)) / 250kHz
  147.                    = 1ms
  148.        LSE as RTC clock
  149.          Time base = ((31 + 1) * (0 + 1)) / 32.768Khz
  150.                    = ~1ms
  151.        LSI as RTC clock
  152.          Time base = ((39 + 1) * (0 + 1)) / 40Khz
  153.                    = 1ms
  154.     */
  155.     hRTC_Handle.Instance = RTC;
  156.     hRTC_Handle.Init.HourFormat = RTC_HOURFORMAT_24;
  157.     hRTC_Handle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
  158.     hRTC_Handle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
  159.     hRTC_Handle.Init.OutPut = RTC_OUTPUT_DISABLE;
  160.     hRTC_Handle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  161.     hRTC_Handle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  162.     status = HAL_RTC_Init(&hRTC_Handle);
  163.   }
  164.   if (status == HAL_OK)
  165.   {
  166.     /* Disable the write protection for RTC registers */
  167.     __HAL_RTC_WRITEPROTECTION_DISABLE(&hRTC_Handle);
  168.  
  169.     /* Disable the Wake-up Timer */
  170.     __HAL_RTC_WAKEUPTIMER_DISABLE(&hRTC_Handle);
  171.  
  172.     /* In case of interrupt mode is used, the interrupt source must disabled */
  173.     __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hRTC_Handle,RTC_IT_WUT);
  174.  
  175.     /* Wait till RTC WUTWF flag is set  */
  176.     while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hRTC_Handle, RTC_FLAG_WUTWF) == RESET)
  177.     {
  178.       if (counter++ == (SystemCoreClock /48U))
  179.       {
  180.         status = HAL_ERROR;
  181.       }
  182.     }
  183.   }
  184.   if (status == HAL_OK)
  185.   {
  186.     /* Clear PWR wake up Flag */
  187.     __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  188.  
  189.     /* Clear RTC Wake Up timer Flag */
  190.     __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hRTC_Handle, RTC_FLAG_WUTF);
  191.  
  192.     /* Configure the Wake-up Timer counter */
  193.     hRTC_Handle.Instance->WUTR = 0U;
  194.  
  195.     /* Clear the Wake-up Timer clock source bits in CR register */
  196.     hRTC_Handle.Instance->CR &= (uint32_t)~RTC_CR_WUCKSEL;
  197.  
  198.     /* Configure the clock source */
  199.     hRTC_Handle.Instance->CR |= (uint32_t)RTC_WAKEUPCLOCK_CK_SPRE_16BITS;
  200.  
  201.     /* RTC WakeUpTimer Interrupt Configuration: EXTI configuration */
  202.     __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
  203.  
  204.     __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();
  205.  
  206.     /* Configure the Interrupt in the RTC_CR register */
  207.     __HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hRTC_Handle, RTC_IT_WUT);
  208.  
  209.     /* Enable the Wake-up Timer */
  210.     __HAL_RTC_WAKEUPTIMER_ENABLE(&hRTC_Handle);
  211.  
  212.     /* Enable the write protection for RTC registers */
  213.     __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  214.  
  215.     /* Enable the RTC global Interrupt */
  216.     HAL_NVIC_EnableIRQ(RTC_IRQn);
  217.  
  218.     /* Configure the SysTick IRQ priority */
  219.     if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  220.     {
  221.       HAL_NVIC_SetPriority(RTC_IRQn, TickPriority, 0U);
  222.       uwTickPrio = TickPriority;
  223.     }
  224.     else
  225.     {
  226.       status = HAL_ERROR;
  227.     }
  228.   }
  229.   return status;
  230. }
  231.  
  232. /**
  233.   * @brief  Suspend Tick increment.
  234.   * @note   Disable the tick increment by disabling RTC_WKUP 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 WAKE UP TIMER Interrupt */
  243.   __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hRTC_Handle, RTC_IT_WUT);
  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_WKUP 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  WAKE UP TIMER  interrupt */
  259.   __HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hRTC_Handle, RTC_IT_WUT);
  260.   /* Enable the write protection for RTC registers */
  261.   __HAL_RTC_WRITEPROTECTION_ENABLE(&hRTC_Handle);
  262. }
  263.  
  264. /**
  265.   * @brief  Wake Up Timer Event Callback in non blocking mode
  266.   * @note   This function is called  when RTC_WKUP 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_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
  273. {
  274.   HAL_IncTick();
  275. }
  276.  
  277. /**
  278.   * @brief  This function handles  WAKE UP TIMER  interrupt request.
  279.   * @param  None
  280.   * @retval None
  281.   */
  282. void RTC_IRQHandler(void)
  283. {
  284.   HAL_RTCEx_WakeUpTimerIRQHandler(&hRTC_Handle);
  285. }
  286.  
  287. /**
  288.   * @}
  289.   */
  290.  
  291. /**
  292.   * @}
  293.   */
  294.  
  295. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  296.