diff --git a/cores/arduino/stm32/analog.c b/cores/arduino/stm32/analog.c index b1d4db473b..9028ab4bb7 100644 --- a/cores/arduino/stm32/analog.c +++ b/cores/arduino/stm32/analog.c @@ -711,9 +711,9 @@ void pwm_start(PinName pin, uint32_t clock_freq, /* Compute the prescaler value to have TIM counter clock equal to clock_freq Hz */ timHandle.Instance = pinmap_peripheral(pin, PinMap_PWM); if (timHandle.Instance == NC) return 0; - timHandle.Init.Prescaler = (uint32_t)(SystemCoreClock / clock_freq) - 1; + timHandle.Init.Prescaler = (uint32_t)(getTimerClkFreq(timHandle.Instance) / clock_freq) - 1; timHandle.Init.Period = period; - timHandle.Init.ClockDivision = 0; + timHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; timHandle.Init.CounterMode = TIM_COUNTERMODE_UP; #ifndef STM32L0xx timHandle.Init.RepetitionCounter = 0; diff --git a/cores/arduino/stm32/timer.c b/cores/arduino/stm32/timer.c index 4e12d20043..c45ba3e486 100644 --- a/cores/arduino/stm32/timer.c +++ b/cores/arduino/stm32/timer.c @@ -414,21 +414,83 @@ void TimerHandleDeinit(stimer_t *obj) HAL_TIM_Base_Stop_IT(&(obj->handle)); } +/** + * @brief This function return the timer clock source. + * @param tim: timer instance + * @retval 1 = PCLK1 or 2 = PCLK2 or 0 = unknown + */ +uint8_t getTimerClkSrc(TIM_TypeDef* tim) +{ + return (uint8_t)timermap_clkSrc(tim, TimerMap_CONFIG); +} + /** * @brief This function return the timer clock frequency. - * @param clkSrc: 1 = PCLK1 or 2 = PCLK2 + * @param tim: timer instance * @retval frequency in Hz */ -uint32_t getTimerClkFreq(uint8_t clkSrc) +uint32_t getTimerClkFreq(TIM_TypeDef* tim) { - if(clkSrc == 1) - return HAL_RCC_GetPCLK1Freq(); -#ifdef HAL_RCC_GetPCLK2Freq - else if(clkSrc == 2) - return HAL_RCC_GetPCLK2Freq(); + RCC_ClkInitTypeDef clkconfig = {}; + uint32_t pFLatency = 0U; + uint32_t uwTimclock, uwAPBxPrescaler = 0U; + + /* Get clock configuration */ + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + switch(getTimerClkSrc(tim)) { + case 1: + uwAPBxPrescaler = clkconfig.APB1CLKDivider; + uwTimclock = HAL_RCC_GetPCLK1Freq(); + break; +#ifndef STM32F0xx + case 2: + uwAPBxPrescaler = clkconfig.APB2CLKDivider; + uwTimclock = HAL_RCC_GetPCLK2Freq(); + break; #endif + default: + case 0: + break; + } +/* When TIMPRE bit of the RCC_DCKCFGR register is reset, + * if APBx prescaler is 1, then TIMxCLK = PCLKx, + * otherwise TIMxCLK = 2x PCLKx. + * When TIMPRE bit in the RCC_DCKCFGR register is set, + * if APBx prescaler is 1,2 or 4, then TIMxCLK =HCLK, + * otherwise TIMxCLK = 4x PCLKx + */ +#if defined(STM32F4xx) || defined(STM32F7xx) + RCC_PeriphCLKInitTypeDef PeriphClkConfig = {}; + HAL_RCCEx_GetPeriphCLKConfig(&PeriphClkConfig); + + if (PeriphClkConfig.TIMPresSelection == RCC_TIMPRES_ACTIVATED) + switch (uwAPBxPrescaler) { + default: + case RCC_HCLK_DIV1: + case RCC_HCLK_DIV2: + case RCC_HCLK_DIV4: + uwTimclock=HAL_RCC_GetHCLKFreq(); + break; + case RCC_HCLK_DIV8: + case RCC_HCLK_DIV16: + uwTimclock*=4; + break; + } else - return 0; +#endif + switch (uwAPBxPrescaler) { + default: + case RCC_HCLK_DIV1: + // uwTimclock*=1; + break; + case RCC_HCLK_DIV2: + case RCC_HCLK_DIV4: + case RCC_HCLK_DIV8: + case RCC_HCLK_DIV16: + uwTimclock*=2; + break; + } + return uwTimclock; } /** @@ -449,7 +511,7 @@ void TimerPulseInit(stimer_t *obj, uint16_t period, uint16_t pulseWidth, void (* //min pulse = 1us - max pulse = 65535us handle->Instance = obj->timer; handle->Init.Period = period; - handle->Init.Prescaler = (uint32_t)(getTimerClkFreq(timermap_clkSrc(obj->timer, TimerMap_CONFIG)) / (1000000)) - 1; + handle->Init.Prescaler = (uint32_t)(getTimerClkFreq(obj->timer) / (1000000)) - 1; handle->Init.ClockDivision = 0; handle->Init.CounterMode = TIM_COUNTERMODE_UP; #ifndef STM32L0xx @@ -631,7 +693,7 @@ void TimerPinInit(stimer_t *obj, uint32_t frequency, uint32_t duration) digital_io_init(obj->pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL); while(end == 0) { - period = ((uint32_t)(getTimerClkFreq(timermap_clkSrc(obj->timer, TimerMap_CONFIG)) / frequency / prescaler)) - 1; + period = ((uint32_t)(getTimerClkFreq(obj->timer) / frequency / prescaler)) - 1; if((period >= 0xFFFF) && (prescaler < 0xFFFF)) prescaler++; //prescaler *= 2; diff --git a/cores/arduino/stm32/timer.h b/cores/arduino/stm32/timer.h index d9421a321c..9c77993a30 100644 --- a/cores/arduino/stm32/timer.h +++ b/cores/arduino/stm32/timer.h @@ -95,6 +95,9 @@ void setTimerCounter(stimer_t *obj, uint32_t value); void setCCRRegister(stimer_t *obj, uint32_t channel, uint32_t value); uint32_t getCCRRegister(stimer_t *obj, uint32_t channel); +uint8_t getTimerClkSrc(TIM_TypeDef* tim); +uint32_t getTimerClkFreq(TIM_TypeDef* tim); + void attachIntHandle(stimer_t *obj, void (*irqHandle)(stimer_t *)); #ifdef __cplusplus diff --git a/variants/NUCLEO_F091RC/PeripheralPins.c b/variants/NUCLEO_F091RC/PeripheralPins.c index 4af2b80504..7d0f218cb2 100644 --- a/variants/NUCLEO_F091RC/PeripheralPins.c +++ b/variants/NUCLEO_F091RC/PeripheralPins.c @@ -118,14 +118,14 @@ const PinMap PinMap_PWM[] = { {PB1, TIM14, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_TIM14, 1, 0)}, // TIM14_CH1 // {PB1, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1, 3, 1)}, // TIM1_CH3N // {PB1, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 4, 0)}, // TIM3_CH4 -// {PB3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 2, 0)}, // TIM2_CH2 + {PB3, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 2, 0)}, // TIM2_CH2 {PB4, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 1, 0)}, // TIM3_CH1 - D5 {PB5, TIM3, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM3, 2, 0)}, // TIM3_CH2 - D4 {PB6, TIM16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM16, 1, 1)}, // TIM16_CH1N - D10 {PB7, TIM17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM17, 1, 1)}, // TIM17_CH1N {PB8, TIM16, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM16, 1, 0)}, // TIM16_CH1 - D15 {PB9, TIM17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM17, 1, 0)}, // TIM17_CH1 - D14 -// {PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 3, 0)}, // TIM2_CH3 - D6 + {PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 3, 0)}, // TIM2_CH3 - D6 // {PB11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM2, 4, 0)}, // TIM2_CH4 {PB13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM1, 1, 1)}, // TIM1_CH1N // {PB14, TIM15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM15, 1, 0)}, // TIM15_CH1 diff --git a/variants/NUCLEO_F303RE/PeripheralPins.c b/variants/NUCLEO_F303RE/PeripheralPins.c index 844865a3da..aa4ada02f5 100644 --- a/variants/NUCLEO_F303RE/PeripheralPins.c +++ b/variants/NUCLEO_F303RE/PeripheralPins.c @@ -160,7 +160,7 @@ const PinMap PinMap_PWM[] = { {PB9, TIM17, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM17, 1, 0)}, // TIM17_CH1 // {PB9, TIM4, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF2_TIM4, 4, 0)}, // TIM4_CH4 // {PB9, TIM8, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF10_TIM8, 3, 0)}, // TIM8_CH3 -// {PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 + {PB10, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 3, 0)}, // TIM2_CH3 // {PB11, TIM2, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM2, 4, 0)}, // TIM2_CH4 {PB13, TIM1, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF6_TIM1, 1, 1)}, // TIM1_CH1N {PB14, TIM15, STM_PIN_DATA_EXT(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_TIM15, 1, 0)}, // TIM15_CH1