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>
@@ -164,6 +165,12 @@ static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
164165 tim = (TIM_HandleTypeDef * )timer -> parent .user_data ;
165166 tim_device = (struct stm32_hwtimer * )timer ;
166167
168+ uint32_t FLatency = 0 ;
169+ RCC_ClkInitTypeDef RCC_ClkInitStruct ;
170+ HAL_RCC_GetClockConfig (& RCC_ClkInitStruct , & FLatency );
171+ uint32_t pclk1_doubler = 1 + ( RCC_ClkInitStruct .APB1CLKDivider != RCC_HCLK_DIV1 );
172+ uint32_t pclk2_doubler = 1 + ( RCC_ClkInitStruct .APB2CLKDivider != RCC_HCLK_DIV1 );
173+
167174 /* time init */
168175#if defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
169176 if (tim -> Instance == TIM9 || tim -> Instance == TIM10 || tim -> Instance == TIM11 )
@@ -176,12 +183,12 @@ static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
176183#endif
177184 {
178185#if !defined(SOC_SERIES_STM32F0 ) && !defined(SOC_SERIES_STM32G0 )
179- prescaler_value = (uint32_t )(HAL_RCC_GetPCLK2Freq () * 2 / 10000 ) - 1 ;
186+ prescaler_value = (uint32_t )(HAL_RCC_GetPCLK2Freq () * pclk2_doubler / 10000 ) - 1 ;
180187#endif
181188 }
182189 else
183190 {
184- prescaler_value = (uint32_t )(HAL_RCC_GetPCLK1Freq () * 2 / 10000 ) - 1 ;
191+ prescaler_value = (uint32_t )(HAL_RCC_GetPCLK1Freq () * pclk1_doubler / 10000 ) - 1 ;
185192 }
186193 tim -> Init .Period = 10000 - 1 ;
187194 tim -> Init .Prescaler = prescaler_value ;
@@ -290,6 +297,12 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
290297 /* set timer frequence */
291298 freq = * ((rt_uint32_t * )arg );
292299
300+ uint32_t FLatency = 0 ;
301+ RCC_ClkInitTypeDef RCC_ClkInitStruct ;
302+ HAL_RCC_GetClockConfig (& RCC_ClkInitStruct , & FLatency );
303+ uint32_t pclk1_doubler = 1 + ( RCC_ClkInitStruct .APB1CLKDivider != RCC_HCLK_DIV1 );
304+ uint32_t pclk2_doubler = 1 + ( RCC_ClkInitStruct .APB2CLKDivider != RCC_HCLK_DIV1 );
305+
293306#if defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
294307 if (tim -> Instance == TIM9 || tim -> Instance == TIM10 || tim -> Instance == TIM11 )
295308#elif defined(SOC_SERIES_STM32L4 )
@@ -300,19 +313,13 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
300313 if (0 )
301314#endif
302315 {
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 ;
316+ #if !defined(SOC_SERIES_STM32F0 ) && !defined(SOC_SERIES_STM32G0 )
317+ val = (uint32_t )(HAL_RCC_GetPCLK2Freq () * pclk2_doubler / 10000 ) - 1 ;
307318#endif
308319 }
309320 else
310321 {
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
322+ val = HAL_RCC_GetPCLK1Freq () * pclk1_doubler / freq ;
316323 }
317324 __HAL_TIM_SET_PRESCALER (tim , val - 1 );
318325
0 commit comments