1 /**
2   ******************************************************************************
3   * @file    stm32wlxx_hal_timebase_tim_template.c
4   * @author  MCD Application Team
5   * @brief   HAL time base based on the hardware TIM Template.
6   *
7   *          This file overrides the native HAL time base functions (defined as
8   *          weak) the TIM time base:
9   *           + Initializes the TIM peripheral generate a Period elapsed Event
10   *             each 1ms when uwTickFreq is set to default value, else 10 ms or
11   *             100 ms, depending of above global variable value.
12   *           + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2020 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                         ##### How to use this driver #####
28   ==============================================================================
29     [..]
30     This file must be copied to the application folder and modified as follows:
31     (#) Rename it to 'stm32wlxx_hal_timebase_tim.c'
32     (#) Add this file and the TIM HAL drivers to your project and uncomment
33        HAL_TIM_MODULE_ENABLED define in stm32wlxx_hal_conf.h
34 
35   @endverbatim
36   ******************************************************************************
37   */
38 
39 /* Includes ------------------------------------------------------------------*/
40 #include "stm32wlxx_hal.h"
41 
42 /** @addtogroup STM32WLxx_HAL_Driver
43   * @{
44   */
45 
46 /** @addtogroup HAL_TimeBase_TIM
47   * @{
48   */
49 
50 /* Private typedef -----------------------------------------------------------*/
51 /* Private define ------------------------------------------------------------*/
52 /* Private macro -------------------------------------------------------------*/
53 /* Private variables ---------------------------------------------------------*/
54 TIM_HandleTypeDef TimHandle = {.Init = {0}};
55 
56 /* Private function prototypes -----------------------------------------------*/
57 void TIM2_IRQHandler(void);
58 /* Private functions ---------------------------------------------------------*/
59 
60 /**
61   * @brief  This function configures the TIM2 as a time base source.
62   *         The time source is configured to have 1ms time base with a dedicated
63   *         Tick interrupt priority.
64   * @note   This function is called  automatically at the beginning of program
65   *         after reset by HAL_Init() or at any time when clock is configured,
66   *         by HAL_RCC_ClockConfig().
67   * @param  TickPriority: Tick interrupt priority.
68   * @retval HAL status
69   */
HAL_InitTick(uint32_t TickPriority)70 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
71 {
72   RCC_ClkInitTypeDef    clkconfig;
73   uint32_t              uwTimclock;
74   uint32_t              uwAPB1Prescaler = 0U;
75   uint32_t              uwPrescalerValue = 0U;
76   uint32_t              pFLatency;
77   HAL_StatusTypeDef     status = HAL_OK;
78 
79   /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that don't take the value zero)*/
80   if ((uint32_t)uwTickFreq != 0U)
81   {
82     /* Enable TIM2 clock */
83     __HAL_RCC_TIM2_CLK_ENABLE();
84 
85     /* Get clock configuration */
86     HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
87 
88     /* Get APB1 prescaler */
89     uwAPB1Prescaler = clkconfig.APB1CLKDivider;
90 
91     /* Compute TIM2 clock */
92     if (uwAPB1Prescaler == RCC_HCLK_DIV1)
93     {
94       uwTimclock = HAL_RCC_GetPCLK1Freq();
95     }
96     else
97     {
98       uwTimclock = 2*HAL_RCC_GetPCLK1Freq();
99     }
100 
101     /* Compute the prescaler value to have TIM2 counter clock equal to 1MHz */
102     uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
103 
104     /* Initialize TIM2 */
105     TimHandle.Instance = TIM2;
106 
107     /* Initialize TIMx peripheral as follow:
108     + Period = [(TIM2CLK/uwTickFreq) - 1]. to have a (1/uwTickFreq) s time base.
109     + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
110     + ClockDivision = 0
111     + Counter direction = Up
112     */
113     TimHandle.Init.Period = (1000000U / (1000U / (uint32_t)uwTickFreq)) - 1U;
114     TimHandle.Init.Prescaler = uwPrescalerValue;
115     TimHandle.Init.ClockDivision = 0U;
116     TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
117     TimHandle.Init.RepetitionCounter = 0U;
118     if (HAL_TIM_Base_Init(&TimHandle) == HAL_OK)
119     {
120       /* Start the TIM time Base generation in interrupt mode */
121       if (HAL_TIM_Base_Start_IT(&TimHandle) == HAL_OK)
122       {
123         /* Enable the TIM2 global Interrupt */
124         HAL_NVIC_EnableIRQ(TIM2_IRQn);
125 
126         /* Configure the SysTick IRQ priority */
127         if (TickPriority < (1UL << __NVIC_PRIO_BITS))
128         {
129           /*Configure the TIM2 IRQ priority */
130           HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority ,0U);
131           uwTickPrio = TickPriority;
132         }
133         else
134         {
135           status = HAL_ERROR;
136         }
137       }
138       else
139       {
140         status = HAL_ERROR;
141       }
142     }
143     else
144     {
145       status = HAL_ERROR;
146     }
147   }
148   else
149   {
150       status = HAL_ERROR;
151   }
152 
153   /* Return function status */
154   return status;
155 }
156 
157 /**
158   * @brief  Suspend Tick increment.
159   * @note   Disable the tick increment by disabling TIM2 update interrupt.
160   * @retval None
161   */
HAL_SuspendTick(void)162 void HAL_SuspendTick(void)
163 {
164   /* Disable TIM2 update Interrupt */
165   __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE);
166 }
167 
168 /**
169   * @brief  Resume Tick increment.
170   * @note   Enable the tick increment by Enabling TIM2 update interrupt.
171   * @retval None
172   */
HAL_ResumeTick(void)173 void HAL_ResumeTick(void)
174 {
175   /* Enable TIM2 Update interrupt */
176   __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
177 }
178 
179 /**
180   * @brief  Period elapsed callback in non blocking mode
181   * @note   This function is called  when TIM2 interrupt took place, inside
182   * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
183   * a global variable "uwTick" used as application time base.
184   * @param  htim : TIM handle
185   * @retval None
186   */
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim)187 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
188 {
189   HAL_IncTick();
190 }
191 
192 /**
193   * @brief  This function handles TIM interrupt request.
194   * @retval None
195   */
TIM2_IRQHandler(void)196 void TIM2_IRQHandler(void)
197 {
198   HAL_TIM_IRQHandler(&TimHandle);
199 }
200 
201 /**
202   * @}
203   */
204 
205 /**
206   * @}
207   */
208