Skip to content

Commit dadfba3

Browse files
authored
Merge pull request #19 from stm32duino/issue_18
Fix #18 PWM frequency
2 parents 44f340f + 323f077 commit dadfba3

File tree

5 files changed

+80
-15
lines changed

5 files changed

+80
-15
lines changed

cores/arduino/stm32/analog.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,9 +711,9 @@ void pwm_start(PinName pin, uint32_t clock_freq,
711711
/* Compute the prescaler value to have TIM counter clock equal to clock_freq Hz */
712712
timHandle.Instance = pinmap_peripheral(pin, PinMap_PWM);
713713
if (timHandle.Instance == NC) return 0;
714-
timHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / clock_freq) - 1;
714+
timHandle.Init.Prescaler = (uint32_t)(getTimerClkFreq(timHandle.Instance) / clock_freq) - 1;
715715
timHandle.Init.Period = period;
716-
timHandle.Init.ClockDivision = 0;
716+
timHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
717717
timHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
718718
#ifndef STM32L0xx
719719
timHandle.Init.RepetitionCounter = 0;

cores/arduino/stm32/timer.c

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -414,21 +414,83 @@ void TimerHandleDeinit(stimer_t *obj)
414414
HAL_TIM_Base_Stop_IT(&(obj->handle));
415415
}
416416

417+
/**
418+
* @brief This function return the timer clock source.
419+
* @param tim: timer instance
420+
* @retval 1 = PCLK1 or 2 = PCLK2 or 0 = unknown
421+
*/
422+
uint8_t getTimerClkSrc(TIM_TypeDef* tim)
423+
{
424+
return (uint8_t)timermap_clkSrc(tim, TimerMap_CONFIG);
425+
}
426+
417427
/**
418428
* @brief This function return the timer clock frequency.
419-
* @param clkSrc: 1 = PCLK1 or 2 = PCLK2
429+
* @param tim: timer instance
420430
* @retval frequency in Hz
421431
*/
422-
uint32_t getTimerClkFreq(uint8_t clkSrc)
432+
uint32_t getTimerClkFreq(TIM_TypeDef* tim)
423433
{
424-
if(clkSrc == 1)
425-
return HAL_RCC_GetPCLK1Freq();
426-
#ifdef HAL_RCC_GetPCLK2Freq
427-
else if(clkSrc == 2)
428-
return HAL_RCC_GetPCLK2Freq();
434+
RCC_ClkInitTypeDef clkconfig = {};
435+
uint32_t pFLatency = 0U;
436+
uint32_t uwTimclock, uwAPBxPrescaler = 0U;
437+
438+
/* Get clock configuration */
439+
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
440+
switch(getTimerClkSrc(tim)) {
441+
case 1:
442+
uwAPBxPrescaler = clkconfig.APB1CLKDivider;
443+
uwTimclock = HAL_RCC_GetPCLK1Freq();
444+
break;
445+
#ifndef STM32F0xx
446+
case 2:
447+
uwAPBxPrescaler = clkconfig.APB2CLKDivider;
448+
uwTimclock = HAL_RCC_GetPCLK2Freq();
449+
break;
429450
#endif
451+
default:
452+
case 0:
453+
break;
454+
}
455+
/* When TIMPRE bit of the RCC_DCKCFGR register is reset,
456+
* if APBx prescaler is 1, then TIMxCLK = PCLKx,
457+
* otherwise TIMxCLK = 2x PCLKx.
458+
* When TIMPRE bit in the RCC_DCKCFGR register is set,
459+
* if APBx prescaler is 1,2 or 4, then TIMxCLK =HCLK,
460+
* otherwise TIMxCLK = 4x PCLKx
461+
*/
462+
#if defined(STM32F4xx) || defined(STM32F7xx)
463+
RCC_PeriphCLKInitTypeDef PeriphClkConfig = {};
464+
HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkConfig);
465+
466+
if (PeriphClkConfig.TIMPresSelection == RCC_TIMPRES_ACTIVATED)
467+
switch (uwAPBxPrescaler) {
468+
default:
469+
case RCC_HCLK_DIV1:
470+
case RCC_HCLK_DIV2:
471+
case RCC_HCLK_DIV4:
472+
uwTimclock=HAL_RCC_GetHCLKFreq();
473+
break;
474+
case RCC_HCLK_DIV8:
475+
case RCC_HCLK_DIV16:
476+
uwTimclock*=4;
477+
break;
478+
}
430479
else
431-
return 0;
480+
#endif
481+
switch (uwAPBxPrescaler) {
482+
default:
483+
case RCC_HCLK_DIV1:
484+
// uwTimclock*=1;
485+
break;
486+
case RCC_HCLK_DIV2:
487+
case RCC_HCLK_DIV4:
488+
case RCC_HCLK_DIV8:
489+
case RCC_HCLK_DIV16:
490+
uwTimclock*=2;
491+
break;
492+
}
493+
return uwTimclock;
432494
}
433495

434496
/**
@@ -449,7 +511,7 @@ void TimerPulseInit(stimer_t *obj, uint16_t period, uint16_t pulseWidth, void (*
449511
//min pulse = 1us - max pulse = 65535us
450512
handle->Instance = obj->timer;
451513
handle->Init.Period = period;
452-
handle->Init.Prescaler = (uint32_t)(getTimerClkFreq(timermap_clkSrc(obj->timer, TimerMap_CONFIG)) / (1000000)) - 1;
514+
handle->Init.Prescaler = (uint32_t)(getTimerClkFreq(obj->timer) / (1000000)) - 1;
453515
handle->Init.ClockDivision = 0;
454516
handle->Init.CounterMode = TIM_COUNTERMODE_UP;
455517
#ifndef STM32L0xx
@@ -631,7 +693,7 @@ void TimerPinInit(stimer_t *obj, uint32_t frequency, uint32_t duration)
631693
digital_io_init(obj->pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL);
632694

633695
while(end == 0) {
634-
period = ((uint32_t)(getTimerClkFreq(timermap_clkSrc(obj->timer, TimerMap_CONFIG)) / frequency / prescaler)) - 1;
696+
period = ((uint32_t)(getTimerClkFreq(obj->timer) / frequency / prescaler)) - 1;
635697

636698
if((period >= 0xFFFF) && (prescaler < 0xFFFF))
637699
prescaler++; //prescaler *= 2;

cores/arduino/stm32/timer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ void setTimerCounter(stimer_t *obj, uint32_t value);
9595
void setCCRRegister(stimer_t *obj, uint32_t channel, uint32_t value);
9696
uint32_t getCCRRegister(stimer_t *obj, uint32_t channel);
9797

98+
uint8_t getTimerClkSrc(TIM_TypeDef* tim);
99+
uint32_t getTimerClkFreq(TIM_TypeDef* tim);
100+
98101
void attachIntHandle(stimer_t *obj, void (*irqHandle)(stimer_t *));
99102

100103
#ifdef __cplusplus

variants/NUCLEO_F091RC/PeripheralPins.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@ const PinMap PinMap_PWM[] = {
118118
{PB1, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM14, 1, 0)}, // TIM14_CH1
119119
// {PB1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1, 3, 1)}, // TIM1_CH3N
120120
// {PB1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 4, 0)}, // TIM3_CH4
121-
// {PB3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 2, 0)}, // TIM2_CH2
121+
{PB3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 2, 0)}, // TIM2_CH2
122122
{PB4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 1, 0)}, // TIM3_CH1 - D5
123123
{PB5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 2, 0)}, // TIM3_CH2 - D4
124124
{PB6, TIM16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM16, 1, 1)}, // TIM16_CH1N - D10
125125
{PB7, TIM17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM17, 1, 1)}, // TIM17_CH1N
126126
{PB8, TIM16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM16, 1, 0)}, // TIM16_CH1 - D15
127127
{PB9, TIM17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM17, 1, 0)}, // TIM17_CH1 - D14
128-
// {PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 3, 0)}, // TIM2_CH3 - D6
128+
{PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 3, 0)}, // TIM2_CH3 - D6
129129
// {PB11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 4, 0)}, // TIM2_CH4
130130
{PB13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1, 1, 1)}, // TIM1_CH1N
131131
// {PB14, TIM15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM15, 1, 0)}, // TIM15_CH1

variants/NUCLEO_F303RE/PeripheralPins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ const PinMap PinMap_PWM[] = {
160160
{PB9, TIM17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM17, 1, 0)}, // TIM17_CH1
161161
// {PB9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4
162162
// {PB9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_TIM8, 3, 0)}, // TIM8_CH3
163-
// {PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
163+
{PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3
164164
// {PB11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4
165165
{PB13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1, 1, 1)}, // TIM1_CH1N
166166
{PB14, TIM15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM15, 1, 0)}, // TIM15_CH1

0 commit comments

Comments
 (0)