66 * Change Logs:
77 * Date Author Notes
88 * 2018-12-10 zylx first version
9+ * 2020-06-16 thread-liu Porting for stm32mp1
10+ * 2020-08-25 linyongkang Fix the timer clock frequency doubling problem
911 */
1012
1113#include <board.h>
12- #include <rtthread.h>
13- #include <rtdevice.h>
14+ #include <rtthread.h>
15+ #include <rtdevice.h>
1416
1517#ifdef BSP_USING_TIM
1618#include "drv_config.h"
@@ -154,9 +156,56 @@ static struct stm32_hwtimer stm32_hwtimer_obj[] =
154156#endif
155157};
156158
159+ /* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
160+ static void pclkx_doubler_get (uint32_t * pclk1_doubler , uint32_t * pclk2_doubler )
161+ {
162+ uint32_t flatency = 0 ;
163+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0 };
164+
165+ RT_ASSERT (pclk1_doubler != RT_NULL );
166+ RT_ASSERT (pclk1_doubler != RT_NULL );
167+
168+ HAL_RCC_GetClockConfig (& RCC_ClkInitStruct , & flatency );
169+
170+ * pclk1_doubler = 1 ;
171+ * pclk2_doubler = 1 ;
172+
173+ #if defined(SOC_SERIES_STM32MP1 )
174+ if (RCC_ClkInitStruct .APB1_Div != RCC_APB1_DIV1 )
175+ {
176+ * pclk1_doubler = 2 ;
177+ }
178+ if (RCC_ClkInitStruct .APB2_Div != RCC_APB2_DIV1 )
179+ {
180+ * pclk2_doubler = 2 ;
181+ }
182+ #elif defined(SOC_SERIES_STM32H7 )
183+ if (RCC_ClkInitStruct .APB1CLKDivider != RCC_APB1_DIV1 )
184+ {
185+ * pclk1_doubler = 2 ;
186+ }
187+ if (RCC_ClkInitStruct .APB2CLKDivider != RCC_APB2_DIV1 )
188+ {
189+ * pclk2_doubler = 2 ;
190+ }
191+ #else
192+ if (RCC_ClkInitStruct .APB1CLKDivider != RCC_HCLK_DIV1 )
193+ {
194+ * pclk1_doubler = 2 ;
195+ }
196+ #if !defined(SOC_SERIES_STM32F0 ) && !defined(SOC_SERIES_STM32G0 )
197+ if (RCC_ClkInitStruct .APB2CLKDivider != RCC_HCLK_DIV1 )
198+ {
199+ * pclk2_doubler = 2 ;
200+ }
201+ #endif
202+ #endif
203+ }
204+
157205static void timer_init (struct rt_hwtimer_device * timer , rt_uint32_t state )
158206{
159207 uint32_t prescaler_value = 0 ;
208+ uint32_t pclk1_doubler , pclk2_doubler ;
160209 TIM_HandleTypeDef * tim = RT_NULL ;
161210 struct stm32_hwtimer * tim_device = RT_NULL ;
162211
@@ -166,22 +215,28 @@ static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
166215 tim = (TIM_HandleTypeDef * )timer -> parent .user_data ;
167216 tim_device = (struct stm32_hwtimer * )timer ;
168217
218+ pclkx_doubler_get (& pclk1_doubler , & pclk2_doubler );
219+
169220 /* time init */
170221#if defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
171222 if (tim -> Instance == TIM9 || tim -> Instance == TIM10 || tim -> Instance == TIM11 )
172223#elif defined(SOC_SERIES_STM32L4 )
173224 if (tim -> Instance == TIM15 || tim -> Instance == TIM16 || tim -> Instance == TIM17 )
225+ #elif defined(SOC_SERIES_STM32MP1 )
226+ if (tim -> Instance == TIM14 || tim -> Instance == TIM16 || tim -> Instance == TIM17 )
227+ #elif defined(SOC_SERIES_STM32H7 )
228+ if (tim -> Instance == TIM13 || tim -> Instance == TIM14 )
174229#elif defined(SOC_SERIES_STM32F1 ) || defined(SOC_SERIES_STM32F0 ) || defined(SOC_SERIES_STM32G0 )
175230 if (0 )
176231#endif
177232 {
178- #if !defined(SOC_SERIES_STM32F0 ) && !defined(SOC_SERIES_STM32G0 )
179- prescaler_value = (uint32_t )(HAL_RCC_GetPCLK2Freq () * 2 / 10000 ) - 1 ;
233+ #if !defined(SOC_SERIES_STM32F0 ) && !defined(SOC_SERIES_STM32G0 ) && !defined( SOC_SERIES_STM32H7 )
234+ prescaler_value = (uint32_t )(HAL_RCC_GetPCLK2Freq () * pclk2_doubler / 10000 ) - 1 ;
180235#endif
181236 }
182237 else
183238 {
184- prescaler_value = (uint32_t )(HAL_RCC_GetPCLK1Freq () * 2 / 10000 ) - 1 ;
239+ prescaler_value = (uint32_t )(HAL_RCC_GetPCLK1Freq () * pclk1_doubler / 10000 ) - 1 ;
185240 }
186241 tim -> Init .Period = 10000 - 1 ;
187242 tim -> Init .Prescaler = prescaler_value ;
@@ -195,7 +250,8 @@ static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
195250 tim -> Init .CounterMode = TIM_COUNTERMODE_DOWN ;
196251 }
197252 tim -> Init .RepetitionCounter = 0 ;
198- #if defined(SOC_SERIES_STM32F1 ) || defined(SOC_SERIES_STM32L4 ) || defined(SOC_SERIES_STM32F0 ) || defined(SOC_SERIES_STM32G0 )
253+ #if defined(SOC_SERIES_STM32F1 ) || defined(SOC_SERIES_STM32L4 ) || defined(SOC_SERIES_STM32F0 ) || defined(SOC_SERIES_STM32G0 ) || \
254+ defined(SOC_SERIES_STM32MP1 ) || defined(SOC_SERIES_STM32H7 )
199255 tim -> Init .AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE ;
200256#endif
201257 if (HAL_TIM_Base_Init (tim ) != HAL_OK )
@@ -244,7 +300,7 @@ static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_
244300 {
245301 tim -> Instance -> CR1 &= (~TIM_OPMODE_SINGLE );
246302 }
247-
303+
248304 /* start timer */
249305 if (HAL_TIM_Base_Start_IT (tim ) != HAL_OK )
250306 {
@@ -274,6 +330,7 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
274330{
275331 TIM_HandleTypeDef * tim = RT_NULL ;
276332 rt_err_t result = RT_EOK ;
333+ uint32_t pclk1_doubler , pclk2_doubler ;
277334
278335 RT_ASSERT (timer != RT_NULL );
279336 RT_ASSERT (arg != RT_NULL );
@@ -290,27 +347,27 @@ static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
290347 /* set timer frequence */
291348 freq = * ((rt_uint32_t * )arg );
292349
350+ pclkx_doubler_get (& pclk1_doubler , & pclk2_doubler );
351+
293352#if defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
294353 if (tim -> Instance == TIM9 || tim -> Instance == TIM10 || tim -> Instance == TIM11 )
295354#elif defined(SOC_SERIES_STM32L4 )
296355 if (tim -> Instance == TIM15 || tim -> Instance == TIM16 || tim -> Instance == TIM17 )
356+ #elif defined(SOC_SERIES_STM32MP1 )
357+ if (tim -> Instance == TIM14 || tim -> Instance == TIM16 || tim -> Instance == TIM17 )
358+ #elif defined(SOC_SERIES_STM32H7 )
359+ if (tim -> Instance == TIM13 || tim -> Instance == TIM14 )
297360#elif defined(SOC_SERIES_STM32F1 ) || defined(SOC_SERIES_STM32F0 ) || defined(SOC_SERIES_STM32G0 )
298361 if (0 )
299362#endif
300363 {
301- #if defined(SOC_SERIES_STM32L4 )
302- val = HAL_RCC_GetPCLK2Freq () / freq ;
303- #elif defined(SOC_SERIES_STM32F1 ) || defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
304- val = HAL_RCC_GetPCLK2Freq () * 2 / freq ;
364+ #if !defined(SOC_SERIES_STM32F0 ) && !defined(SOC_SERIES_STM32G0 )
365+ val = HAL_RCC_GetPCLK2Freq () * pclk2_doubler / freq ;
305366#endif
306367 }
307368 else
308369 {
309- #if defined(SOC_SERIES_STM32F1 ) || defined(SOC_SERIES_STM32F2 ) || defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
310- val = HAL_RCC_GetPCLK1Freq () * 2 / freq ;
311- #elif defined(SOC_SERIES_STM32F0 ) || defined(SOC_SERIES_STM32G0 )
312- val = HAL_RCC_GetPCLK1Freq () / freq ;
313- #endif
370+ val = HAL_RCC_GetPCLK1Freq () * pclk1_doubler / freq ;
314371 }
315372 __HAL_TIM_SET_PRESCALER (tim , val - 1 );
316373
@@ -413,7 +470,7 @@ void TIM8_UP_TIM13_IRQHandler(void)
413470#ifdef BSP_USING_TIM14
414471#if defined(SOC_SERIES_STM32F4 ) || defined(SOC_SERIES_STM32F7 )
415472 void TIM8_TRG_COM_TIM14_IRQHandler (void )
416- #elif defined(SOC_SERIES_STM32F0 )
473+ #elif defined(SOC_SERIES_STM32F0 ) || defined( SOC_SERIES_STM32MP1 ) || defined( SOC_SERIES_STM32H7 )
417474 void TIM14_IRQHandler (void )
418475#endif
419476{
@@ -437,7 +494,7 @@ void TIM1_BRK_TIM15_IRQHandler(void)
437494#ifdef BSP_USING_TIM16
438495#if defined(SOC_SERIES_STM32L4 )
439496 void TIM1_UP_TIM16_IRQHandler (void )
440- #elif defined(SOC_SERIES_STM32F0 )
497+ #elif defined(SOC_SERIES_STM32F0 ) || defined( SOC_SERIES_STM32MP1 )
441498 void TIM16_IRQHandler (void )
442499#endif
443500{
@@ -451,7 +508,7 @@ void TIM1_BRK_TIM15_IRQHandler(void)
451508#ifdef BSP_USING_TIM17
452509#if defined(SOC_SERIES_STM32L4 )
453510 void TIM1_TRG_COM_TIM17_IRQHandler (void )
454- #elif defined(SOC_SERIES_STM32F0 )
511+ #elif defined(SOC_SERIES_STM32F0 ) || defined( SOC_SERIES_STM32MP1 )
455512 void TIM17_IRQHandler (void )
456513#endif
457514{
0 commit comments