Skip to content

Commit 824f582

Browse files
Merge pull request #11559 from sensei-hacker/revert/pwm-timer-priority
Revert "use explicitly assigned motor and servo timers before auto timers" (#11445)
2 parents 308b243 + 5837d2c commit 824f582

1 file changed

Lines changed: 77 additions & 57 deletions

File tree

src/main/drivers/pwm_mapping.c

Lines changed: 77 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -270,23 +270,43 @@ uint8_t pwmClaimTimer(HAL_Timer_t *tim, uint32_t usageFlags) {
270270
return changed;
271271
}
272272

273-
static void pwmAssignOutput(timMotorServoHardware_t *timOutputs, timerHardware_t *timHw, int type)
273+
void pwmEnsureEnoughtMotors(uint8_t motorCount)
274274
{
275-
switch (type) {
276-
case MAP_TO_MOTOR_OUTPUT:
277-
timHw->usageFlags &= TIM_USE_MOTOR;
278-
timOutputs->timMotors[timOutputs->maxTimMotorCount++] = timHw;
279-
pwmClaimTimer(timHw->tim, timHw->usageFlags);
280-
break;
281-
case MAP_TO_SERVO_OUTPUT:
282-
timHw->usageFlags &= TIM_USE_SERVO;
283-
timOutputs->timServos[timOutputs->maxTimServoCount++] = timHw;
284-
pwmClaimTimer(timHw->tim, timHw->usageFlags);
285-
break;
286-
case MAP_TO_LED_OUTPUT:
287-
timHw->usageFlags &= TIM_USE_LED;
288-
pwmClaimTimer(timHw->tim, timHw->usageFlags);
289-
break;
275+
uint8_t motorOnlyOutputs = 0;
276+
277+
for (int idx = 0; idx < timerHardwareCount; idx++) {
278+
timerHardware_t *timHw = &timerHardware[idx];
279+
280+
timerHardwareOverride(timHw);
281+
282+
if (checkPwmTimerConflicts(timHw)) {
283+
continue;
284+
}
285+
286+
if (TIM_IS_MOTOR_ONLY(timHw->usageFlags)) {
287+
motorOnlyOutputs++;
288+
motorOnlyOutputs += pwmClaimTimer(timHw->tim, timHw->usageFlags);
289+
}
290+
}
291+
292+
for (int idx = 0; idx < timerHardwareCount; idx++) {
293+
timerHardware_t *timHw = &timerHardware[idx];
294+
295+
if (checkPwmTimerConflicts(timHw)) {
296+
continue;
297+
}
298+
299+
if (TIM_IS_MOTOR(timHw->usageFlags) && !TIM_IS_MOTOR_ONLY(timHw->usageFlags)) {
300+
if (motorOnlyOutputs < motorCount) {
301+
timHw->usageFlags &= ~TIM_USE_SERVO;
302+
timHw->usageFlags |= TIM_USE_MOTOR;
303+
motorOnlyOutputs++;
304+
motorOnlyOutputs += pwmClaimTimer(timHw->tim, timHw->usageFlags);
305+
} else {
306+
timHw->usageFlags &= ~TIM_USE_MOTOR;
307+
pwmClaimTimer(timHw->tim, timHw->usageFlags);
308+
}
309+
}
290310
}
291311
}
292312

@@ -296,54 +316,54 @@ void pwmBuildTimerOutputList(timMotorServoHardware_t * timOutputs, bool isMixerU
296316
timOutputs->maxTimMotorCount = 0;
297317
timOutputs->maxTimServoCount = 0;
298318

299-
const uint8_t motorCount = getMotorCount();
319+
uint8_t motorCount = getMotorCount();
320+
uint8_t motorIdx = 0;
300321

301-
// Apply configurator overrides to all timer outputs
302-
for (int idx = 0; idx < timerHardwareCount; idx++) {
303-
timerHardwareOverride(&timerHardware[idx]);
304-
}
322+
pwmEnsureEnoughtMotors(motorCount);
305323

306-
// Assign outputs in priority order: dedicated first, then auto.
307-
// Within each pass, array order (S1, S2, ...) is preserved.
308-
// Motors and servos cannot share a timer, enforced by pwmHasMotorOnTimer/pwmHasServoOnTimer.
309-
for (int priority = 0; priority < 2; priority++) {
310-
uint8_t motorIdx = timOutputs->maxTimMotorCount;
324+
for (int idx = 0; idx < timerHardwareCount; idx++) {
325+
timerHardware_t *timHw = &timerHardware[idx];
311326

312-
for (int idx = 0; idx < timerHardwareCount; idx++) {
313-
timerHardware_t *timHw = &timerHardware[idx];
314-
outputMode_e mode = timerOverrides(timer2id(timHw->tim))->outputMode;
315-
bool isDedicated = (priority == 0);
327+
int type = MAP_TO_NONE;
316328

317-
if (checkPwmTimerConflicts(timHw)) {
318-
if (priority == 0) {
319-
LOG_WARNING(PWM, "Timer output %d skipped", idx);
320-
}
321-
continue;
322-
}
329+
// Check for known conflicts (i.e. UART, LEDSTRIP, Rangefinder and ADC)
330+
if (checkPwmTimerConflicts(timHw)) {
331+
LOG_WARNING(PWM, "Timer output %d skipped", idx);
332+
continue;
333+
}
323334

324-
// Motors: dedicated (OUTPUT_MODE_MOTORS) first, then auto
325-
if (TIM_IS_MOTOR(timHw->usageFlags) && motorIdx < motorCount
326-
&& !pwmHasServoOnTimer(timOutputs, timHw->tim)
327-
&& (isDedicated ? mode == OUTPUT_MODE_MOTORS : mode != OUTPUT_MODE_MOTORS)) {
328-
pwmAssignOutput(timOutputs, timHw, MAP_TO_MOTOR_OUTPUT);
329-
motorIdx++;
330-
continue;
331-
}
335+
// Make sure first motorCount motor outputs get assigned to motor
336+
if (TIM_IS_MOTOR(timHw->usageFlags) && (motorIdx < motorCount)) {
337+
timHw->usageFlags &= ~TIM_USE_SERVO;
338+
pwmClaimTimer(timHw->tim, timHw->usageFlags);
339+
motorIdx += 1;
340+
}
332341

333-
// Servos: dedicated (OUTPUT_MODE_SERVOS) first, then auto
334-
if (TIM_IS_SERVO(timHw->usageFlags)
335-
&& !pwmHasMotorOnTimer(timOutputs, timHw->tim)
336-
&& (isDedicated ? mode == OUTPUT_MODE_SERVOS : mode != OUTPUT_MODE_SERVOS)) {
337-
pwmAssignOutput(timOutputs, timHw, MAP_TO_SERVO_OUTPUT);
338-
continue;
339-
}
342+
if (TIM_IS_SERVO(timHw->usageFlags) && !pwmHasMotorOnTimer(timOutputs, timHw->tim)) {
343+
type = MAP_TO_SERVO_OUTPUT;
344+
} else if (TIM_IS_MOTOR(timHw->usageFlags) && !pwmHasServoOnTimer(timOutputs, timHw->tim)) {
345+
type = MAP_TO_MOTOR_OUTPUT;
346+
} else if (TIM_IS_LED(timHw->usageFlags) && !pwmHasMotorOnTimer(timOutputs, timHw->tim) && !pwmHasServoOnTimer(timOutputs, timHw->tim)) {
347+
type = MAP_TO_LED_OUTPUT;
348+
}
340349

341-
// LEDs: only on the auto pass, and only if timer is uncontested
342-
if (!isDedicated && TIM_IS_LED(timHw->usageFlags)
343-
&& !pwmHasMotorOnTimer(timOutputs, timHw->tim)
344-
&& !pwmHasServoOnTimer(timOutputs, timHw->tim)) {
345-
pwmAssignOutput(timOutputs, timHw, MAP_TO_LED_OUTPUT);
346-
}
350+
switch(type) {
351+
case MAP_TO_MOTOR_OUTPUT:
352+
timHw->usageFlags &= TIM_USE_MOTOR;
353+
timOutputs->timMotors[timOutputs->maxTimMotorCount++] = timHw;
354+
pwmClaimTimer(timHw->tim, timHw->usageFlags);
355+
break;
356+
case MAP_TO_SERVO_OUTPUT:
357+
timHw->usageFlags &= TIM_USE_SERVO;
358+
timOutputs->timServos[timOutputs->maxTimServoCount++] = timHw;
359+
pwmClaimTimer(timHw->tim, timHw->usageFlags);
360+
break;
361+
case MAP_TO_LED_OUTPUT:
362+
timHw->usageFlags &= TIM_USE_LED;
363+
pwmClaimTimer(timHw->tim, timHw->usageFlags);
364+
break;
365+
default:
366+
break;
347367
}
348368
}
349369
}

0 commit comments

Comments
 (0)