1 /**
2   ******************************************************************************
3   * @file    stm32g4xx_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 override 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   * @attention
13   *
14   * Copyright (c) 2019 STMicroelectronics.
15   * All rights reserved.
16   *
17   * This software is licensed under terms that can be found in the LICENSE file
18   * in the root directory of this software component.
19   * If no LICENSE file comes with this software, it is provided AS-IS.
20   *
21   ******************************************************************************
22   @verbatim
23   ==============================================================================
24                         ##### How to use this driver #####
25   ==============================================================================
26     [..]
27     This file must be copied to the application folder and modified as follows:
28     (#) Rename it to 'stm32g4xx_hal_timebase_tim.c'
29     (#) Add this file and the TIM HAL driver files to your project and make sure
30        HAL_TIM_MODULE_ENABLED is defined in stm32g4xx_hal_conf.h
31 
32     [..]
33     (@) The application needs to ensure that the time base is always set to 1 millisecond
34        to have correct HAL operation.
35 
36   @endverbatim
37   ******************************************************************************
38   */
39 
40 /* Includes ------------------------------------------------------------------*/
41 #include "stm32g4xx_hal.h"
42 
43 /** @addtogroup STM32G4xx_HAL_Driver
44   * @{
45   */
46 
47 /** @addtogroup HAL_TimeBase
48   * @{
49   */
50 
51 /* Private typedef -----------------------------------------------------------*/
52 /* Private define ------------------------------------------------------------*/
53 /* Private macro -------------------------------------------------------------*/
54 /* Private variables ---------------------------------------------------------*/
55 TIM_HandleTypeDef        TimHandle;
56 /* Private function prototypes -----------------------------------------------*/
57 void TIM6_DAC_IRQHandler(void);
58 /* Private functions ---------------------------------------------------------*/
59 
60 /**
61   * @brief  This function configures the TIM6 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 after
65   *         reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
66   * @param  TickPriority: Tick interrupt priority.
67   * @retval HAL status
68   */
HAL_InitTick(uint32_t TickPriority)69 HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
70 {
71   RCC_ClkInitTypeDef    clkconfig;
72   uint32_t              uwTimclock;
73   uint32_t              uwAPB1Prescaler;
74   uint32_t              uwPrescalerValue;
75   uint32_t              pFLatency;
76   HAL_StatusTypeDef     status;
77 
78   /* Configure the TIM6 IRQ priority */
79   HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority, 0U);
80 
81   /* Enable the TIM6 global Interrupt */
82   HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
83 
84   /* Enable TIM6 clock */
85   __HAL_RCC_TIM6_CLK_ENABLE();
86 
87   /* Get clock configuration */
88   HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
89 
90   /* Get APB1 prescaler */
91   uwAPB1Prescaler = clkconfig.APB1CLKDivider;
92 
93   /* Compute TIM6 clock */
94   if (uwAPB1Prescaler == RCC_HCLK_DIV1)
95   {
96     uwTimclock = HAL_RCC_GetPCLK1Freq();
97   }
98   else
99   {
100     uwTimclock = 2U * HAL_RCC_GetPCLK1Freq();
101   }
102 
103   /* Compute the prescaler value to have TIM6 counter clock equal to 1MHz */
104   uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U);
105 
106   /* Initialize TIM6 */
107   TimHandle.Instance = TIM6;
108 
109   /* Initialize TIMx peripheral as follow:
110   + Period = [(TIM6CLK/1000) - 1]. to have a (1/1000) s time base.
111   + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
112   + ClockDivision = 0
113   + Counter direction = Up
114   */
115   TimHandle.Init.Period = (1000000U / 1000U) - 1U;
116   TimHandle.Init.Prescaler = uwPrescalerValue;
117   TimHandle.Init.ClockDivision = 0;
118   TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
119   status = HAL_TIM_Base_Init(&TimHandle);
120   if (status == HAL_OK)
121   {
122     /* Start the TIM time Base generation in interrupt mode */
123     status = HAL_TIM_Base_Start_IT(&TimHandle);
124     if (status == HAL_OK)
125     {
126       /* Configure the SysTick IRQ priority */
127       if (TickPriority < (1UL << __NVIC_PRIO_BITS))
128       {
129         /* Configure the TIM IRQ priority */
130         HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority, 0U);
131         uwTickPrio = TickPriority;
132       }
133       else
134       {
135         status = HAL_ERROR;
136       }
137     }
138   }
139 
140   /* Return function status */
141   return status;
142 }
143 
144 /**
145   * @brief  Suspend Tick increment.
146   * @note   Disable the tick increment by disabling TIM6 update interrupt.
147   * @param  None
148   * @retval None
149   */
HAL_SuspendTick(void)150 void HAL_SuspendTick(void)
151 {
152   /* Disable TIM6 update interrupt */
153   __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE);
154 }
155 
156 /**
157   * @brief  Resume Tick increment.
158   * @note   Enable the tick increment by enabling TIM6 update interrupt.
159   * @param  None
160   * @retval None
161   */
HAL_ResumeTick(void)162 void HAL_ResumeTick(void)
163 {
164   /* Enable TIM6 update interrupt */
165   __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
166 }
167 
168 /**
169   * @brief  Period elapsed callback in non blocking mode
170   * @note   This function is called  when TIM6 interrupt took place, inside
171   * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
172   * a global variable "uwTick" used as application time base.
173   * @param  htim : TIM handle
174   * @retval None
175   */
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim)176 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
177 {
178   HAL_IncTick();
179 }
180 
181 /**
182   * @brief  This function handles TIM interrupt request.
183   * @param  None
184   * @retval None
185   */
TIM6_DAC_IRQHandler(void)186 void TIM6_DAC_IRQHandler(void)
187 {
188   HAL_TIM_IRQHandler(&TimHandle);
189 }
190 
191 /**
192   * @}
193   */
194 
195 /**
196   * @}
197   */
198 
199