Skip to content

Commit 8888918

Browse files
ABOSTMfpistm
authored andcommitted
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 <alexandre.bourdiol@st.com>
1 parent d856484 commit 8888918

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

cores/arduino/HardwareTimer.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,6 @@ void HardwareTimer::resumeChannel(uint32_t channel)
371371
}
372372
}
373373
break;
374-
case TIMER_OUTPUT_COMPARE:
375374
case TIMER_OUTPUT_COMPARE_ACTIVE:
376375
case TIMER_OUTPUT_COMPARE_INACTIVE:
377376
case TIMER_OUTPUT_COMPARE_TOGGLE:
@@ -406,6 +405,7 @@ void HardwareTimer::resumeChannel(uint32_t channel)
406405
}
407406
break;
408407
case TIMER_NOT_USED:
408+
case TIMER_OUTPUT_COMPARE:
409409
default :
410410
break;
411411
}
@@ -598,9 +598,6 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin)
598598
Error_Handler();
599599
}
600600

601-
// Save channel selected mode to object attribute
602-
_ChannelMode[channel - 1] = mode;
603-
604601
/* Configure some default values. Maybe overwritten later */
605602
channelOC.OCMode = TIMER_NOT_USED;
606603
channelOC.Pulse = __HAL_TIM_GET_COMPARE(&(_timerObj.handle), timChannel); // keep same value already written in hardware <register
@@ -626,9 +623,16 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin)
626623
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
627624
break;
628625
case TIMER_OUTPUT_COMPARE:
629-
channelOC.OCMode = TIM_OCMODE_TIMING;
630-
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
631-
break;
626+
/* In case of TIMER_OUTPUT_COMPARE, there is no output and thus no pin to
627+
* configure, and no channel. So nothing to do. For compatibility reason
628+
* restore TIMER_DISABLED if necessary.
629+
*/
630+
if (_ChannelMode[channel - 1] != TIMER_DISABLED) {
631+
_ChannelMode[channel - 1] = TIMER_DISABLED;
632+
channelOC.OCMode = TIM_OCMODE_TIMING;
633+
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
634+
}
635+
return;
632636
case TIMER_OUTPUT_COMPARE_ACTIVE:
633637
channelOC.OCMode = TIM_OCMODE_ACTIVE;
634638
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
@@ -688,6 +692,9 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin)
688692
break;
689693
}
690694

695+
// Save channel selected mode to object attribute
696+
_ChannelMode[channel - 1] = mode;
697+
691698
if (pin != NC) {
692699
if ((int)get_pwm_channel(pin) == timChannel) {
693700
/* Configure PWM GPIO pins */

cores/arduino/HardwareTimer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@
3636
#define TIMER_CHANNELS 4 // channel5 and channel 6 are not considered here has they don't have gpio output and they don't have interrupt
3737

3838
typedef enum {
39-
TIMER_DISABLED,
39+
TIMER_DISABLED, // == TIM_OCMODE_TIMING no output, useful for only-interrupt
4040
// Output Compare
41-
TIMER_OUTPUT_COMPARE, // == TIM_OCMODE_TIMING no output, useful for only-interrupt
41+
TIMER_OUTPUT_COMPARE, // == Obsolete, use TIMER_DISABLED instead. Kept for compatibility reason
4242
TIMER_OUTPUT_COMPARE_ACTIVE, // == TIM_OCMODE_ACTIVE pin is set high when counter == channel compare
4343
TIMER_OUTPUT_COMPARE_INACTIVE, // == TIM_OCMODE_INACTIVE pin is set low when counter == channel compare
4444
TIMER_OUTPUT_COMPARE_TOGGLE, // == TIM_OCMODE_TOGGLE pin toggles when counter == channel compare

cores/arduino/Tone.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ static void timerTonePinInit(PinName p, uint32_t frequency, uint32_t duration)
9595

9696
pin_function(TimerTone_pinInfo.pin, STM_PIN_DATA(STM_MODE_OUTPUT_PP, GPIO_NOPULL, 0));
9797

98-
TimerTone->setMode(1, TIMER_OUTPUT_COMPARE, NC);
9998
TimerTone->setOverflow(timFreq, HERTZ_FORMAT);
10099
TimerTone->attachInterrupt(tonePeriodElapsedCallback);
101100
TimerTone->resume();

libraries/Servo/src/stm32/Servo.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ static void TimerServoInit()
8080
// prescaler is computed so that timer tick correspond to 1 microseconde
8181
uint32_t prescaler = TimerServo.getTimerClkFreq() / 1000000;
8282

83-
TimerServo.setMode(1, TIMER_OUTPUT_COMPARE, NC);
8483
TimerServo.setPrescaleFactor(prescaler);
8584
TimerServo.setOverflow(REFRESH_INTERVAL); // thanks to prescaler Tick = microsec
8685
TimerServo.attachInterrupt(Servo_PeriodElapsedCallback);

0 commit comments

Comments
 (0)