From f28dc09b49f8040965c95a90c982b7dbae0dca0e Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Mon, 17 Feb 2020 14:54:40 +0100 Subject: [PATCH 1/2] HardwareTimer: Add API to get configured mode --- cores/arduino/HardwareTimer.cpp | 14 ++++++++++++++ cores/arduino/HardwareTimer.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/cores/arduino/HardwareTimer.cpp b/cores/arduino/HardwareTimer.cpp index be39331840..9a8962f819 100644 --- a/cores/arduino/HardwareTimer.cpp +++ b/cores/arduino/HardwareTimer.cpp @@ -690,6 +690,20 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin) } } +/** + * @brief Retrieves channel mode configured + * @param channel: Arduino channel [1..4] + * @retval returns configured mode + */ +TimerModes_t HardwareTimer::getMode(uint32_t channel) +{ + if ((1 <= channel) && (channel <= TIMER_CHANNELS)) { + return _ChannelMode[channel - 1]; + } else { + return TIMER_DISABLED; + } +} + /** * @brief Enable or disable preloading for overflow value * When disabled, changes to the overflow value take effect diff --git a/cores/arduino/HardwareTimer.h b/cores/arduino/HardwareTimer.h index 695f64b21b..4219412a53 100644 --- a/cores/arduino/HardwareTimer.h +++ b/cores/arduino/HardwareTimer.h @@ -118,6 +118,8 @@ class HardwareTimer { void setMode(uint32_t channel, TimerModes_t mode, PinName pin = NC); // Configure timer channel with specified mode on specified pin if available void setMode(uint32_t channel, TimerModes_t mode, uint32_t pin); + TimerModes_t getMode(uint32_t channel); // Retrieve configured mode + void setPreloadEnable(bool value); // Configure overflow preload enable setting uint32_t getCaptureCompare(uint32_t channel, TimerCompareFormat_t format = TICK_COMPARE_FORMAT); // return Capture/Compare register value of specified channel depending on format provided From bdcc98ed9bd0bdaad88dc295e1c106afd7f7fd82 Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Mon, 17 Feb 2020 14:57:54 +0100 Subject: [PATCH 2/2] analogWrite: Configure HardwareTimer mode only if not previously done This avoid glitch when calling analoWrite multiple time. Also don't start again timer otherwise ther is also some glitches Fixes #939 --- libraries/SrcWrapper/src/stm32/analog.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/SrcWrapper/src/stm32/analog.cpp b/libraries/SrcWrapper/src/stm32/analog.cpp index 84ce86ba28..ea8d0998b1 100644 --- a/libraries/SrcWrapper/src/stm32/analog.cpp +++ b/libraries/SrcWrapper/src/stm32/analog.cpp @@ -1028,6 +1028,7 @@ void pwm_start(PinName pin, uint32_t PWM_freq, uint32_t value, TimerCompareForma { TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(pin, PinMap_PWM); HardwareTimer *HT; + TimerModes_t previousMode; uint32_t index = get_timer_index(Instance); if (HardwareTimer_Handle[index] == NULL) { HardwareTimer_Handle[index]->__this = new HardwareTimer((TIM_TypeDef *)pinmap_peripheral(pin, PinMap_PWM)); @@ -1037,10 +1038,15 @@ void pwm_start(PinName pin, uint32_t PWM_freq, uint32_t value, TimerCompareForma uint32_t channel = STM_PIN_CHANNEL(pinmap_function(pin, PinMap_PWM)); - HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin); + previousMode = HT->getMode(channel); + if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) { + HT->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin); + } HT->setOverflow(PWM_freq, HERTZ_FORMAT); HT->setCaptureCompare(channel, value, resolution); - HT->resume(); + if (previousMode != TIMER_OUTPUT_COMPARE_PWM1) { + HT->resume(); + } } /** * @brief This function will disable the PWM