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