@@ -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