Skip to content

Offer the board's ESC connector for a Smart ESC in the Outputs tab - #2814

Closed
MrScothh wants to merge 6 commits into
iNavFlight:maintenance-10.xfrom
MrScothh:feature/srxl2-esc-connector
Closed

MrScothh wants to merge 6 commits into
iNavFlight:maintenance-10.xfrom
MrScothh:feature/srxl2-esc-connector

Conversation

@MrScothh

Copy link
Copy Markdown

The Configurator side of iNavFlight/inav#12087, which lets a Spektrum Smart ESC run on the ESC connector of the few boards that can route a UART's TX there (NEXUS, NEXUS X/XR, Vantac RF007). It was asked for in iNavFlight/inav#11184.

What changes

  • MSP2_INAV_ESC_SRXL2_STATUS: reads the board's connectors that the firmware appends (a count, then the serial port identifier behind each). Older firmware sends none, and then nothing below appears.
  • Outputs tab, with the ESC protocol SRXL2 on a board that reports a connector: a toggle "ESC on the board's ESC connector (uses UARTn)", bound to the new setting esc_srxl2_connector, off by default. The SRXL2 texts then describe both routes, count the connector as motor 1 when the board uses it, and warn when the connector's UART has a function in Ports, because the firmware then leaves the connector unused.
  • The board applies the toggle at startup. The count of open ports therefore follows the saved value, and while the toggle differs from it the tab says to save and reboot, whichever way it was changed.
  • Ports tab: while the connector carries the ESC, its UART shows "SRXL2 via ESC connector" in the Peripherals column, locked, with the reason in the row's tooltip. The entry has an empty value, so saving the tab keeps the port free of functions, which is what the firmware needs. A UART that has a function stays editable, so it can be cleared.
  • Boards without a connector, and older firmware, look and behave as before: the toggle row is dropped when the setting does not exist, and every new text depends on a connector being reported.

Tested

  • SITL, with a local firmware patch that makes UART2 stand in for a connector (part of neither PR): protocol changes, the toggle on and off, UART2 with and without MSP, save and reboot, both tabs in each state, and the toggle changed without saving in both directions.
  • npm test: 290 of 291 pass. The one failure, "unused MZTC writes remain unused and conservatively blocked", fails the same way on maintenance-10.x.

Screenshots (SITL, UART2 standing in for the connector)

Outputs tab, the connector in use:

outputs_connettore.png

The toggle turned off and not saved yet:

outputs_connettore_da_riavviare.png

Ports tab, UART2 locked while it carries the ESC:

ports_connettore.png

On boards whose ESC connector can also be a UART's TX, the firmware reports
the connector in MSP2_INAV_ESC_SRXL2_STATUS and has esc_srxl2_connector. With
the protocol set to SRXL2 the Outputs tab offers it, off by default, names the
UART behind it, and its messages count the connector as motor 1. The Ports tab
lists that UART as "SRXL2 via ESC connector", locked, while the connector
carries the ESC; a UART with a function stays editable, and the Outputs tab
says the connector stays unused until it is cleared.

The board applies the option and the protocol at startup, so the count of open
ports describes it by the saved values, and while the checkbox differs the tab
says to save and reboot, whichever way it was changed.
@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

Offer the board ESC connector for Spektrum Smart ESC

✨ Enhancement 🕐 20-40 Minutes

Grey Divider

AI Description

• Offer supported boards an Outputs toggle for routing motor 1 through the ESC connector.
• Explain UART conflicts, motor ordering, and when connector changes require a reboot.
• Mark the connector’s free UART as reserved in Ports without assigning it a function.
Diagram

graph TD
  FW["Firmware status"] --> MSP["MSP parser"] --> FC["SRXL2 state"] --> OUT["Outputs tab"] --> SET["Connector setting"] --> PORT["Ports tab"] --> UART["Connector UART"]
  FC --> PORT
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Model the connector as a synthetic Ports assignment
  • ➕ Keeps all ESC routing choices in one tab.
  • ➖ Misrepresents a firmware option that requires the underlying UART to have no assigned function.
  • ➖ Complicates serial-port saving and startup-state handling.

Recommendation: Keep the connector toggle in Outputs and display its UART as reserved in Ports. This matches the firmware’s separate routing setting while making the otherwise surprising UART constraint visible.

Files changed (7) +151 / -10

Enhancement (6) +115 / -10
fc.jsInitialize reported SRXL2 connectors +2/-1

Initialize reported SRXL2 connectors

• Adds an empty connector list to SRXL2 status so tabs have a safe default before a status response arrives.

js/fc.js

MSPHelper.jsParse connector UARTs from SRXL2 status +9/-0

Parse connector UARTs from SRXL2 status

• Reads the appended connector count and available UART identifiers. Older, shorter firmware responses continue to yield no connectors.

js/msp/MSPHelper.js

ports.cssDim controls on a reserved UART row +4/-0

Dim controls on a reserved UART row

• Visually distinguishes disabled cells while keeping the UART identifier and connector reservation label legible.

src/css/tabs/ports.css

outputs.htmlAdd the Outputs connector toggle and warning area +10/-1

Add the Outputs connector toggle and warning area

• Introduces a setting-bound toggle, UART-specific label, help tooltip, and conflict warning within the SRXL2 section.

tabs/outputs.html

outputs.jsAccount for connector routing in Outputs guidance +60/-8

Account for connector routing in Outputs guidance

• Shows the toggle only for reported connectors, includes an eligible connector in ESC counts, and warns when its UART has another function. Compares the toggle with the startup setting to explain when saving and rebooting is needed.

tabs/outputs.js

ports.jsReserve the connector UART without assigning a function +30/-0

Reserve the connector UART without assigning a function

• When SRXL2 connector routing is enabled, locks its function-free UART and displays a peripheral label with an empty saved value. A UART with an existing function remains editable so that function can be cleared.

tabs/ports.js

Documentation (1) +36 / -0
messages.jsonExplain connector routing and UART reservation +36/-0

Explain connector routing and UART reservation

• Adds English labels, help text, counts, reboot warnings, conflict guidance, and the Ports reservation message.

locale/en/messages.json

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

qodo-free-for-open-source-projects Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. A locked ESC port retains new functions ✓ Resolved
Description
lockEscConnectorPort() checks the row's original port.functions after an asynchronous setting
request, then disables its controls without clearing functions selected in the meantime. If a user
checks a function before the request completes, the row appears locked but saving still collects
that checked input and assigns the function to the connector UART.
Code

tabs/ports.js[R209-214]

+            $('.tab-ports .portConfiguration').each(function () {
+                const port = $(this).data('serialPort');
+                if (port && connectors.includes(port.identifier) && port.functions.length === 0) {
+                    $(this).addClass('srxl2-connector-locked')
+                        .attr('title', i18n.getMessage('portsUsedByEscConnector'))
+                        .find('input, select').prop('disabled', true);
Evidence
Change handlers are installed and rows are rendered before the new asynchronous lock runs. The lock
tests the stored row data, whereas saving reads checked inputs without excluding disabled ones.

tabs/ports.js[103-154]
tabs/ports.js[184-222]
tabs/ports.js[304-335]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The connector UART remains editable while `getSetting()` is pending. The lock then checks the original port data rather than the user's current selections, so saving can assign a function to a row displayed as locked.
## Fix Focus Areas
- tabs/ports.js[184-222]
- tabs/ports.js[304-335]
## Recommended Fix
Resolve the connector setting before exposing the relevant row to edits, or prevent edits while it loads. When locking, reconcile the row's current selections so no checked function can survive on a locked UART.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. A second ESC connector is hidden in Outputs 🐞 Bug ≡ Correctness
Description
srxl2ConnectorPortBusy() and the Outputs label use only connectors[0], although status decoding
retains every reported identifier. When a board reports multiple connectors, Outputs neither names
the later UARTs nor notices a function assigned to one, while Ports treats every reported UART as a
connector UART.
Code

tabs/outputs.js[R243-246]

+        function srxl2ConnectorPortBusy() {
+            const id = FC.SRXL2_STATUS.connectors[0];
+            const port = FC.SERIAL_CONFIG?.ports?.find(p => p.identifier === id);
+            return Boolean(port && port.functions.length > 0);
Evidence
The decoder appends up to the reported connector count, and Ports checks membership against the
whole array. Outputs reads only the first element for its label and busy decision.

js/msp/MSPHelper.js[1978-1983]
tabs/ports.js[200-220]
tabs/outputs.js[239-260]
tabs/outputs.js[319-333]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Outputs uses only the first reported connector UART, but the status decoder and Ports tab handle the complete list. A later connector can therefore be treated differently across the two tabs.
## Fix Focus Areas
- tabs/outputs.js[237-260]
- tabs/outputs.js[319-333]
- tabs/ports.js[200-220]
## Recommended Fix
Handle all reported connector identifiers consistently in Outputs, including labels, busy checks, and counts, or explicitly limit both tabs to one connector if that is the supported protocol contract.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can add REVIEW.md to your repo root and Qodo follows it on every PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread tabs/ports.js
Comment thread tabs/outputs.js
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Configurator test build ready — commit 4ede7ac

Download build artifacts for PR #2814

Available platforms (scroll to the Artifacts section at the bottom of the run page):

  • Windows x64 (ZIP, MSI) and x32 (ZIP, MSI)
  • macOS arm64 (ZIP, DMG) and x64 (ZIP, DMG)
  • Linux x64 (DEB, RPM, ZIP) and aarch64 (DEB, RPM, ZIP)

A GitHub login is required to download artifacts. Build is for testing only.

The lock waited for the connector setting and then looked at the functions
the port was loaded with, so one picked in the row meanwhile survived on a
row shown as locked and was saved. It now looks at the row as it stands.
SonarCloud put srxl2UpdateVisibility() at a cognitive complexity of 33 once
the connector was in it. The connector row, the warning and the port count
are now three small functions, and the nested ternary on the count is gone.
Nothing shown changes.
The firmware drives four, the ESC connector counting as one, and refuses to
arm with a port left over. The tab counted four open ports for the motors and
gave no reason for the refusal; it now says what is wrong.
portRowHasFunction() moves to module scope, as it needs nothing of the tab's,
and the setting check uses an optional chain. Nothing shown changes.
@sensei-hacker sensei-hacker added the New Feature Entirely new feature or major feature change label Oct 3, 2026
@sonarqubecloud

sonarqubecloud Bot commented Oct 6, 2026

Copy link
Copy Markdown

@MrScothh

Copy link
Copy Markdown
Author

Closing this together with iNavFlight/inav#12087. Its replacement, iNavFlight/inav#12143, puts any UART's TX or RX on an output pad, and #2833 is its Configurator side: a Pins column in the Ports tab instead of the ESC connector toggle in Outputs.

@MrScothh MrScothh closed this Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New Feature Entirely new feature or major feature change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants