Skip to content

Commit 672881e

Browse files
authored
Merge pull request #3846 from ynkan/master
修复STM32的硬件定时器的时钟配置问题
2 parents 07ee531 + 9eb2275 commit 672881e

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

bsp/stm32/libraries/HAL_Drivers/drv_hwtimer.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Date Author Notes
88
* 2018-12-10 zylx first version
99
* 2020-06-16 thread-liu Porting for stm32mp1
10+
* 2020-08-25 linyongkang Fix the timer clock frequency doubling problem
1011
*/
1112

1213
#include <board.h>
@@ -152,9 +153,35 @@ static struct stm32_hwtimer stm32_hwtimer_obj[] =
152153
#endif
153154
};
154155

156+
/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
157+
static void pclkx_doubler_get(uint32_t *pclk1_doubler, uint32_t *pclk2_doubler)
158+
{
159+
uint32_t flatency = 0;
160+
RCC_ClkInitTypeDef RCC_ClkInitStruct;
161+
162+
RT_ASSERT(pclk1_doubler != RT_NULL);
163+
RT_ASSERT(pclk1_doubler != RT_NULL);
164+
165+
HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &flatency);
166+
167+
*pclk1_doubler = 1;
168+
*pclk2_doubler = 1;
169+
170+
if(RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1)
171+
{
172+
*pclk1_doubler = 2;
173+
}
174+
175+
if(RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1)
176+
{
177+
*pclk2_doubler = 2;
178+
}
179+
}
180+
155181
static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
156182
{
157183
uint32_t prescaler_value = 0;
184+
uint32_t pclk1_doubler, pclk2_doubler;
158185
TIM_HandleTypeDef *tim = RT_NULL;
159186
struct stm32_hwtimer *tim_device = RT_NULL;
160187

@@ -164,6 +191,8 @@ static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
164191
tim = (TIM_HandleTypeDef *)timer->parent.user_data;
165192
tim_device = (struct stm32_hwtimer *)timer;
166193

194+
pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
195+
167196
/* time init */
168197
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
169198
if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11)
@@ -176,12 +205,12 @@ static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
176205
#endif
177206
{
178207
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
179-
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * 2 / 10000) - 1;
208+
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK2Freq() * pclk2_doubler / 10000) - 1;
180209
#endif
181210
}
182211
else
183212
{
184-
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * 2 / 10000) - 1;
213+
prescaler_value = (uint32_t)(HAL_RCC_GetPCLK1Freq() * pclk1_doubler / 10000) - 1;
185214
}
186215
tim->Init.Period = 10000 - 1;
187216
tim->Init.Prescaler = prescaler_value;
@@ -274,6 +303,7 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
274303
{
275304
TIM_HandleTypeDef *tim = RT_NULL;
276305
rt_err_t result = RT_EOK;
306+
uint32_t pclk1_doubler, pclk2_doubler;
277307

278308
RT_ASSERT(timer != RT_NULL);
279309
RT_ASSERT(arg != RT_NULL);
@@ -290,6 +320,8 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
290320
/* set timer frequence */
291321
freq = *((rt_uint32_t *)arg);
292322

323+
pclkx_doubler_get(&pclk1_doubler, &pclk2_doubler);
324+
293325
#if defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
294326
if (tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11)
295327
#elif defined(SOC_SERIES_STM32L4)
@@ -300,19 +332,13 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
300332
if (0)
301333
#endif
302334
{
303-
#if defined(SOC_SERIES_STM32L4)
304-
val = HAL_RCC_GetPCLK2Freq() / freq;
305-
#elif defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1)
306-
val = HAL_RCC_GetPCLK2Freq() * 2 / freq;
335+
#if !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32G0)
336+
val = HAL_RCC_GetPCLK2Freq() * pclk2_doubler / freq;
307337
#endif
308338
}
309339
else
310340
{
311-
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32MP1)
312-
val = HAL_RCC_GetPCLK1Freq() * 2 / freq;
313-
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
314-
val = HAL_RCC_GetPCLK1Freq() / freq;
315-
#endif
341+
val = HAL_RCC_GetPCLK1Freq() * pclk1_doubler / freq;
316342
}
317343
__HAL_TIM_SET_PRESCALER(tim, val - 1);
318344

0 commit comments

Comments
 (0)