From a339084684951cd9758d9efda9a0037b773f7c16 Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Thu, 6 Jun 2019 17:12:11 +0200 Subject: [PATCH] STM32: pwmout_write: configure channel only when not already enabled Fix PWM glitch on write(), TARGET_STM/pwmout_api.c, #10734 --- .../TARGET_STM32F0/common_objects.h | 1 + .../TARGET_STM32F1/common_objects.h | 1 + targets/TARGET_STM/TARGET_STM32F2/objects.h | 1 + .../TARGET_STM32F3/common_objects.h | 1 + .../TARGET_STM32F4/common_objects.h | 1 + .../TARGET_STM32F7/common_objects.h | 1 + targets/TARGET_STM/TARGET_STM32H7/objects.h | 1 + .../TARGET_STM32L0/common_objects.h | 1 + .../TARGET_STM32L1/common_objects.h | 1 + .../TARGET_STM32L4/common_objects.h | 1 + .../TARGET_STM32WB/common_objects.h | 1 + targets/TARGET_STM/pwmout_api.c | 48 +++++++++++++++++-- 12 files changed, 56 insertions(+), 3 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h index f0566041a6..1aa7002ec2 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32f0xx_ll_usart.h" +#include "stm32f0xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32F1/common_objects.h b/targets/TARGET_STM/TARGET_STM32F1/common_objects.h index 7c31e2d829..fa962a4726 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32f1xx_ll_usart.h" +#include "stm32f1xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32F2/objects.h b/targets/TARGET_STM/TARGET_STM32F2/objects.h index ac1a37984b..c9d7da1a64 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F2/objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32f2xx_ll_usart.h" +#include "stm32f2xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h index 74c54ca530..7e6d472154 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32f3xx_ll_usart.h" +#include "stm32f3xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32F4/common_objects.h b/targets/TARGET_STM/TARGET_STM32F4/common_objects.h index e906b3ec29..963e913353 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32f4xx_ll_usart.h" +#include "stm32f4xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h index 99ccff6352..972bd60ee9 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32f7xx_ll_usart.h" +#include "stm32f7xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32H7/objects.h b/targets/TARGET_STM/TARGET_STM32H7/objects.h index eec655c3e0..5cbd0ed911 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32H7/objects.h @@ -36,6 +36,7 @@ #include "PinNames.h" #include "stm32h7xx_ll_usart.h" #include "stm32h7xx_ll_rtc.h" +#include "stm32h7xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32L0/common_objects.h b/targets/TARGET_STM/TARGET_STM32L0/common_objects.h index fd58e98f19..43c401ac64 100644 --- a/targets/TARGET_STM/TARGET_STM32L0/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L0/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32l0xx_ll_usart.h" +#include "stm32l0xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32L1/common_objects.h b/targets/TARGET_STM/TARGET_STM32L1/common_objects.h index ab5c5b56d4..9334aa7ae4 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L1/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32l1xx_ll_usart.h" +#include "stm32l1xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h index 829dd14878..540311f1da 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/common_objects.h @@ -35,6 +35,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32l4xx_ll_usart.h" +#include "stm32l4xx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/TARGET_STM32WB/common_objects.h b/targets/TARGET_STM/TARGET_STM32WB/common_objects.h index c6eabfacac..6bbfb80164 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/common_objects.h +++ b/targets/TARGET_STM/TARGET_STM32WB/common_objects.h @@ -37,6 +37,7 @@ #include "PeripheralNames.h" #include "PinNames.h" #include "stm32wbxx_ll_usart.h" +#include "stm32wbxx_ll_tim.h" #ifdef __cplusplus extern "C" { diff --git a/targets/TARGET_STM/pwmout_api.c b/targets/TARGET_STM/pwmout_api.c index f59a22fa0d..cb21b22ac1 100644 --- a/targets/TARGET_STM/pwmout_api.c +++ b/targets/TARGET_STM/pwmout_api.c @@ -39,6 +39,43 @@ static TIM_HandleTypeDef TimHandle; +/* Convert STM32 Cube HAL channel to LL channel */ +uint32_t TIM_ChannelConvert_HAL2LL(uint32_t channel, pwmout_t *obj) +{ +#if !defined(PWMOUT_INVERTED_NOT_SUPPORTED) + if (obj->inverted) { + switch (channel) { + case TIM_CHANNEL_1 : + return LL_TIM_CHANNEL_CH1N; + case TIM_CHANNEL_2 : + return LL_TIM_CHANNEL_CH2N; + case TIM_CHANNEL_3 : + return LL_TIM_CHANNEL_CH3N; +#if defined(LL_TIM_CHANNEL_CH4N) + case TIM_CHANNEL_4 : + return LL_TIM_CHANNEL_CH4N; +#endif + default : /* Optional */ + return 0; + } + } else +#endif + { + switch (channel) { + case TIM_CHANNEL_1 : + return LL_TIM_CHANNEL_CH1; + case TIM_CHANNEL_2 : + return LL_TIM_CHANNEL_CH2; + case TIM_CHANNEL_3 : + return LL_TIM_CHANNEL_CH3; + case TIM_CHANNEL_4 : + return LL_TIM_CHANNEL_CH4; + default : /* Optional */ + return 0; + } + } +} + void pwmout_init(pwmout_t *obj, PinName pin) { // Get the peripheral name from the pin and assign it to the object @@ -214,10 +251,15 @@ void pwmout_write(pwmout_t *obj, float value) return; } - if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel) != HAL_OK) { - error("Cannot initialize PWM\n"); + if (LL_TIM_CC_IsEnabledChannel(TimHandle.Instance, TIM_ChannelConvert_HAL2LL(channel, obj)) == 0) { + // If channel is not enabled, proceed to channel configuration + if (HAL_TIM_PWM_ConfigChannel(&TimHandle, &sConfig, channel) != HAL_OK) { + error("Cannot initialize PWM\n"); + } + } else { + // If channel already enabled, only update compare value to avoid glitch + __HAL_TIM_SET_COMPARE(&TimHandle, channel, sConfig.Pulse); } - #if !defined(PWMOUT_INVERTED_NOT_SUPPORTED) if (obj->inverted) { HAL_TIMEx_PWMN_Start(&TimHandle, channel);