From ae139d6c2262093fb2f20e0031b4d2c75cb6dec4 Mon Sep 17 00:00:00 2001 From: Laurent MEUNIER Date: Mon, 27 Feb 2017 13:47:34 +0100 Subject: [PATCH] STM32: pwm period and prescaler calculation Correct the while loop limit and add a safe guard to avoid infinite loop. --- targets/TARGET_STM/pwmout_api.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/targets/TARGET_STM/pwmout_api.c b/targets/TARGET_STM/pwmout_api.c index f8a22e7035..aa01556073 100644 --- a/targets/TARGET_STM/pwmout_api.c +++ b/targets/TARGET_STM/pwmout_api.c @@ -251,13 +251,19 @@ void pwmout_period_us(pwmout_t* obj, int us) TimHandle.Init.Period = (us - 1); /* In case period or pre-scalers are out of range, loop-in to get valid values */ - while ((TimHandle.Init.Period > 0xFFFF) || (TimHandle.Init.Period > 0xFFFF)) { + while ((TimHandle.Init.Period > 0xFFFF) || (TimHandle.Init.Prescaler > 0xFFFF)) { obj->prescaler = obj->prescaler * 2; if (APBxCLKDivider == RCC_HCLK_DIV1) TimHandle.Init.Prescaler = (((PclkFreq) / 1000000) * obj->prescaler) - 1; else TimHandle.Init.Prescaler = (((PclkFreq * 2) / 1000000) * obj->prescaler) - 1; TimHandle.Init.Period = (us - 1) / obj->prescaler; + /* Period decreases and prescaler increases over loops, so check for + * possible out of range cases */ + if ((TimHandle.Init.Period < 0xFFFF) && (TimHandle.Init.Prescaler > 0xFFFF)) { + error("Cannot initialize PWM\n"); + break; + } } TimHandle.Init.ClockDivision = 0;