From 3e313f9e5f964440639e37a2ab8ff241fe7f0ee1 Mon Sep 17 00:00:00 2001 From: Alexandre Bourdiol Date: Tue, 1 Dec 2020 09:17:06 +0100 Subject: [PATCH] HardwareTimer: Fix assert failed when using TIMER_OUTPUT_COMPARE When assert is activated there may be assert failed, specially when using Tone or Servo with TIM6 or TIM7. "assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));" This is due to the fact that when using timer instances without output (like TIM6 and TIM7 specially used for Tone and Servo) in TIMER_OUTPUT_COMPARE mode, the API setMode() requires a channel, even if it is not used. This was made like this to simplify the HardwareTimer driver, and there is no functional issue, but as there is an assert failed reported when assert is activated, this should be fixed. TIMER_OUTPUT_COMPARE becomes obsolete, but kept for compatibility reason. When only timing configuration is needed, no need to set mode, just keep the default TIMER_DISABLED. Fixes #1244 Signed-off-by: Alexandre Bourdiol --- cores/arduino/HardwareTimer.cpp | 21 ++++++++++++++------- cores/arduino/HardwareTimer.h | 4 ++-- cores/arduino/Tone.cpp | 1 - libraries/Servo/src/stm32/Servo.cpp | 1 - 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/cores/arduino/HardwareTimer.cpp b/cores/arduino/HardwareTimer.cpp index d26e8342b8..3df3d12f0e 100644 --- a/cores/arduino/HardwareTimer.cpp +++ b/cores/arduino/HardwareTimer.cpp @@ -371,7 +371,6 @@ void HardwareTimer::resumeChannel(uint32_t channel) } } break; - case TIMER_OUTPUT_COMPARE: case TIMER_OUTPUT_COMPARE_ACTIVE: case TIMER_OUTPUT_COMPARE_INACTIVE: case TIMER_OUTPUT_COMPARE_TOGGLE: @@ -406,6 +405,7 @@ void HardwareTimer::resumeChannel(uint32_t channel) } break; case TIMER_NOT_USED: + case TIMER_OUTPUT_COMPARE: default : break; } @@ -598,9 +598,6 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin) Error_Handler(); } - // Save channel selected mode to object attribute - _ChannelMode[channel - 1] = mode; - /* Configure some default values. Maybe overwritten later */ channelOC.OCMode = TIMER_NOT_USED; channelOC.Pulse = __HAL_TIM_GET_COMPARE(&(_timerObj.handle), timChannel); // keep same value already written in hardware setMode(1, TIMER_OUTPUT_COMPARE, NC); TimerTone->setOverflow(timFreq, HERTZ_FORMAT); TimerTone->attachInterrupt(tonePeriodElapsedCallback); TimerTone->resume(); diff --git a/libraries/Servo/src/stm32/Servo.cpp b/libraries/Servo/src/stm32/Servo.cpp index 41c77c7584..850ca74f54 100644 --- a/libraries/Servo/src/stm32/Servo.cpp +++ b/libraries/Servo/src/stm32/Servo.cpp @@ -80,7 +80,6 @@ static void TimerServoInit() // prescaler is computed so that timer tick correspond to 1 microseconde uint32_t prescaler = TimerServo.getTimerClkFreq() / 1000000; - TimerServo.setMode(1, TIMER_OUTPUT_COMPARE, NC); TimerServo.setPrescaleFactor(prescaler); TimerServo.setOverflow(REFRESH_INTERVAL); // thanks to prescaler Tick = microsec TimerServo.attachInterrupt(Servo_PeriodElapsedCallback);