Skip to content

Conversation

functionpointer
Copy link

@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
  • calibrated EXT-V using a multimeter
  • verified both gyro and accelerometer work and have correct orientation
  • verified barometer works
  • test flight

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.

Limitations

Blackbox is currently not supported, as there is no driver for the W25N02K chip in iNav yet.


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   

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

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
Author

No, i am not.

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

2 participants