Skip to content

pwm_mapping: reserve no output pad for a motor driven over a serial bus - #12140

Open
MrScothh wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:fix/srxl2-no-motor-pad
Open

MrScothh wants to merge 1 commit into
iNavFlight:maintenance-10.xfrom
MrScothh:fix/srxl2-no-motor-pad

Conversation

@MrScothh

@MrScothh MrScothh commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

The output table is built from the mixer's motor count before the motor protocol is looked at, so a Spektrum Smart ESC on a UART still took the first motor-capable pad and, with it, the timer that pad shares with its neighbours. On a TBS Lucid H7 Wing with an airplane mixer that is S1, and S2 went with it: the elevator and rudder servos wired there stayed silent until the phantom motor was parked on an unused pad with timer_output_mode, which nobody can be expected to work out from "my servos don't move".

With a protocol that has no timer waveform the table now reserves no motor pad, and the servos take the pads that can drive a servo from the first one. Nothing changes for PWM, Oneshot, Multishot, Brushed and DShot. pwmInitMotors() already returned before touching the timers for such a protocol, and its SRXL2 check still asks for one assigned port per motor; the output assignment reported over MSP simply has no motor entry.

A model set up for SRXL2 on 10.0.0-rc1 or rc2 has its servos one or two pads further along than this build assigns them (two on boards where the first motor pad shares its timer, like the Lucid). The docs now say to check every servo output after updating, or to set timer_output_mode to MOTORS for the timer of the old motor pad, which keeps the layout the model was wired for; a model that already used that workaround is unchanged. Worth a line in the release notes.

The Configurator draws the same assignment in the Mixer tab's Output Mapping preview while the rules are being edited; iNavFlight/inav-configurator#2831 teaches that preview the same rule and should go in together with this.

Testing

  • TBS Lucid H7 Wing on an E-flite T-28 (Avian Smart ESC on UART8, airplane mixer with eight servo rules on servos 1 to 8), running this change on top of maintenance-10.x with my other open PRs: with every timer on AUTO, MSP2_INAV_OUTPUT_ASSIGNMENT lists S1 to S8 as servos 1 to 8 and no motor. Before the change the motor took S1, S2 was lost and the servos started at S3; the model had been parked with timer_output_mode 0 MOTORS, which is no longer needed.
  • Sizes against 3f9fde4: MATEKF722SE flash +16 B, MATEKF405SE +32 B, KAKUTEF7 +32 B, KAKUTEF7HDV +16 B; RAM and ITCM unchanged everywhere.
  • Unit tests 620/620.
  • Trial merge with srxl2: a Smart ESC on a board's ESC connector #12087 (Smart ESC on a board's ESC connector) is clean; that PR's comment about the motor slot it keeps becomes moot once this is in.

The output table was built from the mixer's motor count before the protocol
was looked at, so a Smart ESC on a UART still took the first motor pad and
its timer, and the servos wired there went silent unless the slot was moved
to an unused pad by hand with timer_output_mode.
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Stop reserving motor pads for serial ESC protocols

🐞 Bug fix 📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Prevent serial-bus motors from claiming output pads and timers needed by servos.
• Preserve motor-pad assignment for timer-driven protocols.
• Warn SRXL2 users to verify servo wiring after upgrading from 10.0.0-rc1 or rc2.
Diagram

graph TD
  A["Motor protocol"] --> B{"Uses timer?"} -->|No| C["Zero motor slots"] --> E["Output mapper"] --> F["Servo pads"]
  B -->|Yes| D["Mixer motor count"] --> E
Loading
High-Level Assessment

Use the existing usesHwTimer protocol property at output-list construction, as this fixes the reservation at its source for any timerless protocol. A special case for SRXL2 would duplicate protocol knowledge and be less general.

Files changed (2) +8 / -7

Bug fix (1) +7 / -6
pwm_mapping.cSkip motor-pad reservation for protocols without hardware timers +7/-6

Skip motor-pad reservation for protocols without hardware timers

• Moves the existing timer-use helper before output-list construction and uses it to set the reserved motor count to zero for timerless protocols. Timer-driven protocols continue to reserve the mixer's motor count.

src/main/drivers/pwm_mapping.c

Documentation (1) +1 / -1
Spektrum Smart ESC.mdDocument the new servo-pad layout and upgrade precaution +1/-1

Document the new servo-pad layout and upgrade precaution

• Explains that Smart ESCs reserve no motor pad. Warns users upgrading from 10.0.0-rc1 or rc2 to check every servo output, with a timer override option to preserve their existing wiring layout.

docs/Spektrum Smart ESC.md

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can show, collapse, or hide each part of a finding: code, evidence, and all

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

RAM / Flash usage vs. base commit e87050f — commit d1797f5

Using the nearest available size baseline — the PR's exact base commit has no stored baseline yet.

Target Flash Δ RAM Δ
MATEKF405 -352 B (-0.05%) CCM: ±0 B (±0.00%)
RAM: +8 B (+0.01%)
MATEKF722 +72 B (+0.01%) ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)
TCM: ±0 B (±0.00%)
MATEKF765 +136 B (+0.02%) DTCM_RAM: ±0 B (±0.00%)
SRAM1: ±0 B (±0.00%)
MATEKH743 +64 B (+0.01%) D2_RAM: ±0 B (±0.00%)
DTCM_RAM: ±0 B (±0.00%)
ITCM_RAM: ±0 B (±0.00%)
RAM: ±0 B (±0.00%)

See RAM/flash optimization guide for techniques to reduce usage.

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

Test firmware build ready — commit d1797f5

Download firmware for PR #12140

251 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

@sensei-hacker

Copy link
Copy Markdown
Member

Thanks for this. Was any testing done to ensure it doesn't break everything that's not an Avian?

@MrScothh

Copy link
Copy Markdown
Contributor Author

@sensei-hacker Nothing changes for a motor that has a timer waveform: the output table takes getMotorProtocolProperties(...)->usesHwTimer, which is already true for PWM, Oneshot, Multishot, Brushed and DShot, and only when it is false (SRXL2 today) does the motor count used to build the table become 0. For every other protocol the table is built from the same motor count as before, line for line. What I ran: unit tests (620/620) and the T-28 on a Lucid H7 Wing with SRXL2, the case that changes; the same build has been on my flight branch since 15/10. I have not flown a DShot or PWM model on it. If you want a direct check, I can set a board to DSHOT300 and STANDARD with an airplane and a quad mixer and compare the output assignment reported over MSP before and after the change.

@sensei-hacker

sensei-hacker commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

I can set a board to DSHOT300 and STANDARD with an airplane and a quad mixer and compare the output assignment reported over MSP before and after the change.

I think it would be good to verify that.
We had an incident once ...

It's clear what we would EXPECT to happen. But just to verify.

@MrScothh

Copy link
Copy Markdown
Contributor Author

@sensei-hacker Direct check done on the bench, TBS Lucid H7 Wing on this change with every timer on AUTO, reading MSP2_INAV_OUTPUT_ASSIGNMENT after each reboot:

  • airplane mixer (one motor, four servos): DSHOT300 and STANDARD both give motor 1 on S1, S2 skipped because it shares TIM3 with S1, servos 1 to 4 on S3 to S6. That is the layout this board had before the change, which never looked at the protocol.
  • quad X mixer (four motors, in a second mixer profile): DSHOT300 and STANDARD both give motors 1 to 4 on S1 to S4 and the servos from S7 (S5 and S6 share TIM5 with S3 and S4).
  • SRXL2 with the airplane mixer: servos 1 to 4 on S1 to S4 and no motor, the case this PR changes.

So with a protocol that uses a timer the table is the one INAV built before; only the serial-bus case moves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants