diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h index 974f6a8066e..a1cba7d5836 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F303VC/objects.h @@ -99,6 +99,7 @@ struct i2c_s { struct pwmout_s { PWMName pwm; PinName pin; + uint32_t prescaler; uint32_t period; uint32_t pulse; uint32_t channel; diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h index 974f6a8066e..a1cba7d5836 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_DISCO_F334C8/objects.h @@ -99,6 +99,7 @@ struct i2c_s { struct pwmout_s { PWMName pwm; PinName pin; + uint32_t prescaler; uint32_t period; uint32_t pulse; uint32_t channel; diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h index 974f6a8066e..a1cba7d5836 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h @@ -99,6 +99,7 @@ struct i2c_s { struct pwmout_s { PWMName pwm; PinName pin; + uint32_t prescaler; uint32_t period; uint32_t pulse; uint32_t channel; diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h index 974f6a8066e..a1cba7d5836 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h @@ -99,6 +99,7 @@ struct i2c_s { struct pwmout_s { PWMName pwm; PinName pin; + uint32_t prescaler; uint32_t period; uint32_t pulse; uint32_t channel; diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h index 974f6a8066e..a1cba7d5836 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h @@ -99,6 +99,7 @@ struct i2c_s { struct pwmout_s { PWMName pwm; PinName pin; + uint32_t prescaler; uint32_t period; uint32_t pulse; uint32_t channel; diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h index 974f6a8066e..a1cba7d5836 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h @@ -99,6 +99,7 @@ struct i2c_s { struct pwmout_s { PWMName pwm; PinName pin; + uint32_t prescaler; uint32_t period; uint32_t pulse; uint32_t channel; diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/pwmout_api.c index 73a639e6590..c538e6474a3 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/pwmout_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3/pwmout_api.c @@ -96,7 +96,7 @@ void pwmout_write(pwmout_t* obj, float value) // Configure channels sConfig.OCMode = TIM_OCMODE_PWM1; - sConfig.Pulse = obj->pulse; + sConfig.Pulse = obj->pulse / obj->prescaler; sConfig.OCPolarity = TIM_OCPOLARITY_HIGH; sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfig.OCFastMode = TIM_OCFAST_DISABLE; @@ -161,8 +161,26 @@ void pwmout_period_us(pwmout_t* obj, int us) // Update the SystemCoreClock variable SystemCoreClockUpdate(); - TimHandle.Init.Period = us - 1; - TimHandle.Init.Prescaler = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick + /* To make it simple, we use to possible prescaler values which lead to: + * pwm unit = 1us, period/pulse can be from 1us to 65535us + * or + * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec + * Be careful that all the channels of a PWM shares the same prescaler + */ + if (us > 0xFFFF) { + obj->prescaler = 500; + } else { + obj->prescaler = 1; + } + TimHandle.Init.Prescaler = ((SystemCoreClock / 1000000) * obj->prescaler) - 1; + + if (TimHandle.Init.Prescaler > 0xFFFF) + error("PWM: out of range prescaler"); + + TimHandle.Init.Period = (us - 1) / obj->prescaler; + if (TimHandle.Init.Period > 0xFFFF) + error("PWM: out of range period"); + TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; diff --git a/libraries/tests/mbed/pwm/main.cpp b/libraries/tests/mbed/pwm/main.cpp index 30eab22d736..bdafaa8c6db 100644 --- a/libraries/tests/mbed/pwm/main.cpp +++ b/libraries/tests/mbed/pwm/main.cpp @@ -19,15 +19,15 @@ float value = 0.75; int main() { #if defined(TARGET_FF_ARDUINO) PwmOut pwm(D9); + int period_ms = 10; - pwm.period_ms(10); + pwm.period_ms(period_ms); pwm.write(value); float result = floor(pwm.read() * 100 + 0.5) / 100; // round it to 0.xx - printf("Initialize PWM on pin D9 with duty cycle: %.2f\n", result); + printf("PWM period = %dms with duty cycle: %d%%\n", period_ms, (int) (result * 100)); notify_completion(result == value ? true : false); - #elif defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) || defined(TARGET_LPC2460) PwmOut pwm_p25(p25); PwmOut pwm_p26(p26);