Skip to content

Commit 4955d49

Browse files
Merge pull request #11445 from sensei-hacker/mixer_use_explicit_timers_first
use explicitly assigned motor and servo timers before auto timers
2 parents 978a521 + f6281a6 commit 4955d49

File tree

1 file changed

+57
-77
lines changed

1 file changed

+57
-77
lines changed

src/main/drivers/pwm_mapping.c

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

273-
void pwmEnsureEnoughtMotors(uint8_t motorCount)
273+
static void pwmAssignOutput(timMotorServoHardware_t *timOutputs, timerHardware_t *timHw, int type)
274274
{
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-
}
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;
310290
}
311291
}
312292

@@ -316,54 +296,54 @@ void pwmBuildTimerOutputList(timMotorServoHardware_t * timOutputs, bool isMixerU
316296
timOutputs->maxTimMotorCount = 0;
317297
timOutputs->maxTimServoCount = 0;
318298

319-
uint8_t motorCount = getMotorCount();
320-
uint8_t motorIdx = 0;
321-
322-
pwmEnsureEnoughtMotors(motorCount);
299+
const uint8_t motorCount = getMotorCount();
323300

301+
// Apply configurator overrides to all timer outputs
324302
for (int idx = 0; idx < timerHardwareCount; idx++) {
325-
timerHardware_t *timHw = &timerHardware[idx];
303+
timerHardwareOverride(&timerHardware[idx]);
304+
}
326305

327-
int type = MAP_TO_NONE;
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;
328311

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-
}
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);
334316

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-
}
317+
if (checkPwmTimerConflicts(timHw)) {
318+
if (priority == 0) {
319+
LOG_WARNING(PWM, "Timer output %d skipped", idx);
320+
}
321+
continue;
322+
}
341323

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-
}
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+
}
332+
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+
}
349340

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;
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+
}
367347
}
368348
}
369349
}

0 commit comments

Comments
 (0)