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