Skip to content

Conversation

@functionpointer
Copy link
Contributor

@functionpointer functionpointer commented Sep 28, 2025

User description

Adds support for Radiomaster Nexus X and Nexus XR.

Fixes #10983

Testing

I have tested:

  • all servo output pins
  • "A" port UART
  • "B" port UART
  • UART1 on SBUS and AUX pins
  • internal receiver works
  • calibrated EXT-V using a multimeter
  • verified both gyro and accelerometer work and have correct orientation
  • verified barometer works
  • test flight
  • Blackbox

Choice of pin functions

Many pins can have multiple functions, see the second table in README.md.
I have chosen three targets NEXUSX, NEXUSX_9SERVOS and NEXUSX_NOI2C that I hope will cover most use cases. NEXUSX has 7 servo/motor outputs spread over 4 timers, 3 accessible UARTs and 1 accessible non-shared I2C bus. NEXUSX_9SERVOS trades 1 UART for 2 more servo/motor outputs. NEXUSX_NOI2C trades the I2C for another UART.

Update:
I have created one target NEXUSX that enables several combinations of pin usages.

Specifically, the RPM/TLM and AUX/SBUS pins can either be Servo/Motor or UART.
See the readme for more details.

Additionally, the "C" port can switch between I2C and UART3 pending correct priority handling of the pins.

The most extreme possible configs are:

  • 9 Servo/Motor outputs, 2 accessible UARTs, 1 I2C
  • 5 Servo/Motor outputs, 5 accessible UARTs, no I2C

PR Type

Other


Description

This description is generated by an AI tool. It may have inaccuracies

  • Adds support for Radiomaster Nexus X and XR flight controllers

  • Implements three target variants with different pin configurations

  • Configures STM32F722 hardware with IMU, barometer, and UART support

  • Includes built-in ELRS receiver support for Nexus XR


Diagram Walkthrough

flowchart LR
  A["New Target Files"] --> B["Hardware Configuration"]
  B --> C["Timer/PWM Setup"]
  B --> D["UART Configuration"]
  B --> E["I2C/Sensor Setup"]
  C --> F["Servo Outputs"]
  D --> G["Serial Ports"]
  E --> H["IMU/Baro/Flash"]
Loading

File Walkthrough

Relevant files
Configuration changes
config.c
Target configuration setup                                                             

src/main/target/NEXUSX/config.c

  • Implements target configuration function
  • Sets up permanent ID for USER1 pinio box
+39/-0   
target.c
Timer hardware configuration                                                         

src/main/target/NEXUSX/target.c

  • Defines timer hardware mappings for servo outputs
  • Configures 7-9 servo channels across multiple timers
  • Conditional compilation for different target variants
+45/-0   
target.h
Complete hardware pin definitions                                               

src/main/target/NEXUSX/target.h

  • Defines complete hardware configuration for STM32F722
  • Configures SPI, I2C, UART, ADC, and GPIO pins
  • Sets up IMU, barometer, flash memory, and ELRS receiver
  • Implements three target variants with different pin assignments
+165/-0 
CMakeLists.txt
Build system configuration                                                             

src/main/target/NEXUSX/CMakeLists.txt

  • Defines three target variants for STM32F722XE
  • NEXUSX, NEXUSX_9SERVOS, and NEXUSX_NOI2C configurations
+3/-0     
Documentation
README.md
Hardware documentation                                                                     

src/main/target/NEXUSX/README.md

  • Documents hardware specifications and pin configurations
  • Provides detailed pinout tables for all target variants
  • Explains differences between NEXUS X and XR models
+61/-0   

@qodo-merge-pro
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

10983 - Partially compliant

Compliant requirements:

  • Add new INAV target(s) to support RadioMaster Nexus X and Nexus XR flight controllers
  • Expose practical UARTs and servo outputs per hardware capabilities
  • Provide variants to cover common use cases (e.g., more servos vs more UARTs, with/without I2C)
  • Configure onboard sensors: IMU (ICM42688P), barometer (SPL06)
  • Support built-in ELRS receiver on Nexus XR, including power control
  • Include documentation for pinout, features, and differences between X and XR
  • Ensure default features and serial RX settings are sensible for XR and do not break X

Non-compliant requirements:

  • Configure blackbox flash (W25N02K/W25N02KVZEIR) with working driver support

Requires further human verification:

  • Verify at-runtime that UART/I2C conflicts are correctly handled across variants on real hardware
  • Validate IMU orientation (CW180) and baro operation on both models
  • Confirm ELRS power pin (PINIO1 PC8 inverted) and USER1 box mapping works across boots
  • Flight test on both Nexus X and Nexus XR (including servo outputs across all timers)
⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
⚡ Recommended focus areas for review

Possible Misdetection

IMU is declared as ICM42605 with comment indicating actual ICM42688P; ensure correct driver selection and compatibility for ICM42688P to avoid sensor init/orientation issues.

#define USE_IMU_ICM42605 // is actually ICM42688P
#define IMU_ICM42605_ALIGN     CW180_DEG
#define ICM42605_CS_PIN        PA4
#define ICM42605_EXTI_PIN      PB8
#define ICM42605_SPI_BUS       BUS_SPI1
Flash/Blackbox

Flash is defined as W25N01G while comment says W25N02KVZEIR; blackbox enabled by default but PR notes driver not present. Confirm part compatibility mapping and consider disabling default blackbox until supported.

#define USE_FLASHFS
#define USE_FLASH_W25N01G // is actually W25N02KVZEIR
#define W25N01G_SPI_BUS          BUS_SPI2
#define W25N01G_CS_PIN           PB12
#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT
Variant Macro Typo

Conditional uses NEXUS_9SERVOS (missing 'X'), which likely prevents the intended I2C2 default on 9-servos variant; verify and correct macro to NEXUSX_9SERVOS.

#if defined(NEXUSX) || defined(NEXUS_9SERVOS)
#define USE_I2C_DEVICE_2 // clashes with UART3
#define I2C2_SCL                PB10
#define I2C2_SDA                PB11
#define DEFAULT_I2C BUS_I2C2
#else
#define DEFAULT_I2C BUS_I2C3
#endif

@qodo-merge-pro
Copy link

qodo-merge-pro bot commented Sep 28, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix typo in preprocessor directive
Suggestion Impact:The commit changes the preprocessor check to use NEXUSX_9SERVOS instead of NEXUS_9SERVOS, matching the suggested fix.

code diff:

-#if defined(NEXUSX) || defined(NEXUS_9SERVOS)
+#if defined(NEXUSX) || defined(NEXUSX_9SERVOS)
 #define USE_I2C_DEVICE_2 // clashes with UART3
 #define I2C2_SCL                PB10
 #define I2C2_SDA                PB11

Fix the typo NEXUS_9SERVOS to NEXUSX_9SERVOS in the preprocessor directive to
ensure correct I2C configuration for that target variant.

src/main/target/NEXUSX/target.h [50-57]

-#if defined(NEXUSX) || defined(NEXUS_9SERVOS)
+#if defined(NEXUSX) || defined(NEXUSX_9SERVOS)
 #define USE_I2C_DEVICE_2 // clashes with UART3
 #define I2C2_SCL                PB10
 #define I2C2_SDA                PB11
 #define DEFAULT_I2C BUS_I2C2
 #else
 #define DEFAULT_I2C BUS_I2C3
 #endif

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a typo in a preprocessor directive (NEXUS_9SERVOS instead of NEXUSX_9SERVOS) that would cause an incorrect I2C bus to be selected for a specific build variant, breaking its functionality.

High
Correct maximum PWM output ports
Suggestion Impact:The commit modified MAX_PWM_OUTPUT_PORTS to be conditional, setting it to 9 for NEXUSX_9SERVOS and NEXUSX_NOI2C, addressing the suggestion (and additionally set 7 for NEXUSX).

code diff:

-#define MAX_PWM_OUTPUT_PORTS        8
+#if defined(NEXUSX)
+#define MAX_PWM_OUTPUT_PORTS        7
+#elif defined(NEXUSX_9SERVOS) || defined(NEXUSX_NOI2C)
+#define MAX_PWM_OUTPUT_PORTS        9
+#endif

Conditionally define MAX_PWM_OUTPUT_PORTS to 9 for the NEXUSX_9SERVOS and
NEXUSX_NOI2C variants to match their 9 defined servo outputs.

src/main/target/NEXUSX/target.h [161]

+#if defined(NEXUSX_9SERVOS) || defined(NEXUSX_NOI2C)
+#define MAX_PWM_OUTPUT_PORTS        9
+#else
 #define MAX_PWM_OUTPUT_PORTS        8
+#endif

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: The suggestion correctly points out that MAX_PWM_OUTPUT_PORTS is hardcoded to 8, while two target variants define 9 servo outputs, which would prevent the 9th servo from functioning on those variants.

High
Remove unsupported magnetometer from sensors
Suggestion Impact:The commit updated SENSORS_SET to remove SENSOR_MAG, leaving only SENSOR_ACC and SENSOR_BARO as suggested.

code diff:

-#define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO)
+#define SENSORS_SET (SENSOR_ACC|SENSOR_BARO)

Remove the unsupported SENSOR_MAG from the SENSORS_SET macro, as the target
hardware does not include a magnetometer.

src/main/target/NEXUSX/target.h [129]

-#define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO)
+#define SENSORS_SET (SENSOR_ACC|SENSOR_BARO)

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that an unsupported magnetometer (SENSOR_MAG) is enabled in SENSORS_SET, which could cause initialization issues. This is a valid bug fix that improves the target's stability.

Medium
High-level
Consider a single target instead

Instead of creating three separate firmware targets for different pin
configurations, consolidate them into a single target. Document how users can
achieve the alternative setups using CLI commands for resource remapping to
reduce maintenance overhead.

Examples:

src/main/target/NEXUSX/CMakeLists.txt [1-3]
target_stm32f722xe(NEXUSX)
target_stm32f722xe(NEXUSX_9SERVOS)
target_stm32f722xe(NEXUSX_NOI2C)
src/main/target/NEXUSX/target.h [85-123]
#ifdef NEXUSX
#define USE_UART1 // clashes with I2C1
#define UART1_TX_PIN            PB6
#define UART1_RX_PIN            PB7 // pin labelled "SBUS"
#endif

//#define USE_UART2 // clashes with 2 servo outputs
//#define UART2_TX_PIN            PA2 // pin labelled as "RPM"
//#define UART2_RX_PIN            PA3 // pin labelled as "TLM"


 ... (clipped 29 lines)

Solution Walkthrough:

Before:

// src/main/target/NEXUSX/CMakeLists.txt
target_stm32f722xe(NEXUSX)
target_stm32f722xe(NEXUSX_9SERVOS)
target_stm32f722xe(NEXUSX_NOI2C)

// src/main/target/NEXUSX/target.h
#ifdef NEXUSX
#define USE_UART1
...
#endif

#ifdef NEXUSX_NOI2C
#define USE_UART3
...
#endif

#if defined(NEXUSX_9SERVOS) || defined(NEXUSX_NOI2C)
// define extra servo outputs
#endif

After:

// src/main/target/NEXUSX/CMakeLists.txt
target_stm32f722xe(NEXUSX)

// src/main/target/NEXUSX/target.h
// Default configuration (e.g., NEXUSX)
#define USE_UART1
...
#define USE_I2C_DEVICE_2
...
// All possible timer outputs are defined
DEF_TIM(TIM4, CH1, PB6, ...),
DEF_TIM(TIM4, CH2, PB7, ...),

// src/main/target/NEXUSX/README.md
// Add instructions for alternative configurations
/*
To get 9 servo outputs, run in CLI:
resource SERIAL_TX 1 NONE
resource SERIAL_RX 1 NONE
resource MOTOR 8 PB6
resource MOTOR 9 PB7
*/
Suggestion importance[1-10]: 7

__

Why: This is a valid architectural suggestion that correctly identifies the trade-off between user convenience and long-term project maintenance, which is significant for a large project like iNav.

Medium
  • Update

@sensei-hacker
Copy link
Collaborator

@functionpointer are you associated with the manufacturer?

@functionpointer
Copy link
Contributor Author

No, i am not.

@sensei-hacker sensei-hacker added Testing Required New target This PR adds a new target labels Oct 11, 2025
@todwmosle
Copy link

what is the function/purpose of the 'Blackbox" feature ?

@sensei-hacker
Copy link
Collaborator

what is the function/purpose of the 'Blackbox" feature ?

https://github.com/iNavFlight/inav/blob/master/docs/Blackbox.md

@todwmosle
Copy link

Thanks Sensei. My goal is rather simple, and I would not use that feature. I am just looking to get a wind rejection feature going in the RX.

@todwmosle
Copy link

I am a github noob. where do I find the files to down load?

@MrD-RC
Copy link
Member

MrD-RC commented Oct 14, 2025

Just a note to say that hopefully hardware will be on its way to @sensei-hacker and I for testing. Ideally I would like to see Blackbox support before the targets get merged in to master. Perhaps this can be ported from RotorFlight?

@functionpointer
Copy link
Contributor Author

I can take a look at the Blackbox. I assume the driver for it should go into a separate PR?

Unfortunately, I am not in a position where I can donate hardware. Hopefully someone else is willing to do so.

@functionpointer
Copy link
Contributor Author

I am a github noob. where do I find the files to down load?

As of now, you have to compile both iNav and iNav configurator yourself. The only way it gets easier is if this pull request gets merged.

@MrD-RC
Copy link
Member

MrD-RC commented Oct 14, 2025

Unfortunately, I am not in a position where I can donate hardware. Hopefully someone else is willing to do so.

RadioMaster should be sending the hardware out. So no need to worry about that.

@MrD-RC
Copy link
Member

MrD-RC commented Oct 14, 2025

I can take a look at the Blackbox. I assume the driver for it should go into a separate PR?

I think this PR would be fine. As it's being introduced for this target. Maybe have it as a separate commit with it labelled as adding that driver.

@todwmosle
Copy link

I am a github noob. where do I find the files to down load?

As of now, you have to compile both iNav and iNav configurator yourself. The only way it gets easier is if this pull request gets merged.

I am willing to risk a plane/hardware in this effort. That being said, I would need some guidance on how to compile/install/configure the suite. If these questions are out of order for this project, please advise.

@MrD-RC
Copy link
Member

MrD-RC commented Oct 14, 2025

I am willing to risk a plane/hardware in this effort. That being said, I would need some guidance on how to compile/install/configure the suite. If these questions are out of order for this project, please advise.

With all due respect. From these posts. You should wait until the official target is released.

It isn't just risking a plane/hardware. That risk also adds the possibility of injuring people or damaging property. The developers will go through everything possible before flying the aircraft to minimise any risk. Also, where this is still developmental. The blackbox is extremely useful. If something bad does occur. It can provide insight in to what happened.

This is being done as part of support for NEXUSX target.
The previously introduced target ORBITH743 has already
introduced support for the Winbond w25n02k 2Gbit/256MByte
array. This commit refactors it to increase code quality.

flash_w25n01g.c is renamed to flash_w25n.c.
The driver no longer supports just w25n01g,
but two chips of the w25n family now.
More chips might be added in future targets.
The name change reflects this new larger family support.

Cleanup of some magic numbers in flash_w25n.c

Removal of w25n01g_readExtensionBytes.
It had a magic number in it and was unused.
Rather than fixing the magic number it just gets removed.

Addition of USE_FLASH_W25N02K and use of it in targets.
Keeps target definitions more accurate and independent of
flash driver implementation details.
@functionpointer
Copy link
Contributor Author

I have added support for the Blackbox chip.
Turns out it was already there, added just a few days ago in #10889

To make use of that, I rebased this PR on the latest master.

However, I found some issues with the code supporting the new W25N02K Blackbox chip.
It added support into the flash_w25n01g.c without renaming it. This means the filename
no longer accurately depicts what the driver is capable of.
I fixed that by renaming it to flash_w25n.c.

I removed some magic numbers by placing them in properly organized preprocessor constants.
Additionally, I found the function w25n01g_readExtensionBytes was unused, so i removed it.

Finally, the USE_FLASH_W25N01G directive was being reused for the W25N02K.

This leads to inaccurate target definitions, possibly causing issues in future Blackbox code changes.
I fixed it by introducing a new USE_FLASH_W25N02K directive.
Targets can now use the correct directive for their respective chip.

However, as of now, both directives call the same code. The actual chip is detected at runtime.
This means targets using the wrong directive will still work without apparent issue.
If there is interest, I could adjust the chip ID detection to only accept the expected chip.
This would force every target to use the correct directive.

@robthomson
Copy link

20251019_174546.mp4

So my initial tests show this is 100% viable as a board.

Issue I have had is around the timers.

When set to auto, my servos would not all work.

When manually set.. The channel order no longer matches what your readme has.

Rest of it all seems good.

@sensei-hacker
Copy link
Collaborator

sensei-hacker commented Oct 19, 2025

Thanks so much for the additional work @functionpointer and for the testing @robthomson !

I do have a board or two now and will do a full test of every pin soon, hopefully taking care of the issue regarding the ordering of outputs.

@sensei-hacker
Copy link
Collaborator

I am a github noob. where do I find the files to down load?

As of now, you have to compile both iNav and iNav configurator yourself. The only way it gets easier is if this pull request gets merged.

Binaries for this PR can be found buried under the "checks" tab for the PR. If you click through it ends up showing the artifact URL as

https://github.com/iNavFlight/inav/actions/runs/18606734711/artifacts/4304815389

@todwmosle
Copy link

I got a board today. Hopefully all of your dedicated, and hard work will make it into v9. I really appreciate you guys.

@functionpointer
Copy link
Contributor Author

functionpointer commented Nov 1, 2025

Thanks to the discussion over on #11082 i was able to unify the targets while enabling even more pin combinations.

Specifically, the RPM/TLM and AUX/SBUS pins can either be Servo/Motor or UART.
See the readme for more details.

Additionally, the "C" port can switch between I2C and UART3 pending correct priority handling of the pins.
See #11082 (comment) for more info.

The most extreme possible configs are:

  • 9 Servo/Motor outputs, 2 accessible UARTs, 1 I2C
  • 5 Servo/Motor outputs, 5 accessible UARTs, no I2C

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Please add support for the RadioMaster NEXUS-x and NEXUS-XR flight controller

5 participants