Skip to content

HardwareTimer: Fix assert failed when using TIMER_OUTPUT_COMPARE #1247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions cores/arduino/HardwareTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -406,6 +405,7 @@ void HardwareTimer::resumeChannel(uint32_t channel)
}
break;
case TIMER_NOT_USED:
case TIMER_OUTPUT_COMPARE:
default :
break;
}
Expand Down Expand Up @@ -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 <register
Expand All @@ -626,9 +623,16 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin)
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
break;
case TIMER_OUTPUT_COMPARE:
channelOC.OCMode = TIM_OCMODE_TIMING;
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
break;
/* In case of TIMER_OUTPUT_COMPARE, there is no output and thus no pin to
* configure, and no channel. So nothing to do. For compatibility reason
* restore TIMER_DISABLED if necessary.
*/
if (_ChannelMode[channel - 1] != TIMER_DISABLED) {
_ChannelMode[channel - 1] = TIMER_DISABLED;
channelOC.OCMode = TIM_OCMODE_TIMING;
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
}
return;
case TIMER_OUTPUT_COMPARE_ACTIVE:
channelOC.OCMode = TIM_OCMODE_ACTIVE;
HAL_TIM_OC_ConfigChannel(&(_timerObj.handle), &channelOC, timChannel);
Expand Down Expand Up @@ -688,6 +692,9 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin)
break;
}

// Save channel selected mode to object attribute
_ChannelMode[channel - 1] = mode;

if (pin != NC) {
if ((int)get_pwm_channel(pin) == timChannel) {
/* Configure PWM GPIO pins */
Expand Down
4 changes: 2 additions & 2 deletions cores/arduino/HardwareTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
#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

typedef enum {
TIMER_DISABLED,
TIMER_DISABLED, // == TIM_OCMODE_TIMING no output, useful for only-interrupt
// Output Compare
TIMER_OUTPUT_COMPARE, // == TIM_OCMODE_TIMING no output, useful for only-interrupt
TIMER_OUTPUT_COMPARE, // == Obsolete, use TIMER_DISABLED instead. Kept for compatibility reason
TIMER_OUTPUT_COMPARE_ACTIVE, // == TIM_OCMODE_ACTIVE pin is set high when counter == channel compare
TIMER_OUTPUT_COMPARE_INACTIVE, // == TIM_OCMODE_INACTIVE pin is set low when counter == channel compare
TIMER_OUTPUT_COMPARE_TOGGLE, // == TIM_OCMODE_TOGGLE pin toggles when counter == channel compare
Expand Down
1 change: 0 additions & 1 deletion cores/arduino/Tone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ static void timerTonePinInit(PinName p, uint32_t frequency, uint32_t duration)

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

TimerTone->setMode(1, TIMER_OUTPUT_COMPARE, NC);
TimerTone->setOverflow(timFreq, HERTZ_FORMAT);
TimerTone->attachInterrupt(tonePeriodElapsedCallback);
TimerTone->resume();
Expand Down
1 change: 0 additions & 1 deletion libraries/Servo/src/stm32/Servo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down