ELRS on UART1 works in Betaflight but not ArduPilot on MambaF405-2022 — what am I missing?

Hi everyone,

I’m setting up a hexacopter on a Diatone Mamba MK4 F405Mini and I’ve hit a wall with RC input. I’ve spent a good while on this and I suspect I’m overlooking something obvious, so I’d really appreciate a second pair of eyes.

The short version: my ExpressLRS receiver is wired to UART1 and works perfectly under Betaflight, but ArduCopter 4.7.0 never sees it. Same wiring, same receiver, same radio, same session.

Setup

  • FC: Diatone Mamba MK4 F405Mini (STM32F405, ICM42688P, DPS310 baro, MAX7456 OSD)
  • Firmware: ArduCopter 4.7.0 (1511f271), target MambaF405-2022, flashed via DFU with arducopter_with_bl.hex and full chip erase
  • RX: HappyModel ES900 RX target (sold as “Cyclone ELRS 900”), ExpressLRS 3.5.3, FCC915, Serial Protocol CRSF, UART baud 420000, bound
  • TX: RadioMaster TX16 MK3, internal ELRS 3.6.3, FCC915, 50Hz Low Band, Wide switch mode, Gemini
  • Frame: HEXA/X. No GPS, no compass.
  • Mission Planner 1.3.83

Wiring (unchanged throughout)

  • RX 5V → FC 5V, RX GND → FC GND
  • RX TX → FC RX1
  • RX RX → FC TX1

Continuity confirmed with a multimeter at both ends, no short between RX1 and TX1.

Why I’m confident it’s not the hardware

I had backed up the original Betaflight firmware as a full 1MB flash image before installing ArduPilot. When ArduPilot wouldn’t see the RX, I restored that image to test the physical path:

  • Betaflight 4.3.0 reads every channel correctly (sticks move, values change).
  • Betaflight’s Ports tab had Serial RX enabled on both UART1 and UART4. Turning off UART1 killed all stick input; turning it back on restored it. So the receiver is definitively on UART1 (UART4 was leftover config for an unused JST connector).
  • Telemetry sensors (1RSS, RQly, RSNR, TPWR) are live on the handset, so the RF link is healthy.

Then I re-flashed ArduPilot (full chip erase again) and the problem came back.

What I’ve tried in ArduPilot

Every test followed the same procedure: write params, physically unplug USB, power the radio on first and wait for a solid RX LED, plug USB back in, connect, check DATA → Messages.

Configuration Result
Factory defaults (SERIAL1_PROTOCOL=23, SERIAL1_OPTIONS=0, RC_PROTOCOLS=1, RC_OPTIONS=32, SERIAL1_BAUD=57, BRD_ALT_CONFIG=0) RC not found
BRD_ALT_CONFIG=1 RC not found
RC_OPTIONS=8224 (420kbaud + suppress CRSF msg) RC not found
RC_PROTOCOLS=512 (CRSF only) RC not found
SERIAL1_BAUD=115 RC not found
SERIAL1_OPTIONS=1 (InvertRX) RC not found
SERIAL1_OPTIONS=8 (SwapTXRX) RC not found
SERIAL1_OPTIONS=288 (RX_NoDMA + RX_PullUp) RC not found
RSSI_TYPE=3 no change

SERIAL1 is the only port set to 23 (SERIAL0=2, SERIAL2=5, SERIAL3=-1, SERIAL4=-1, SERIAL5=-1, SERIAL6=16).

Boot output is always the same, and RCInput: decoding CRSF never appears:

ArduCopter V4.7.0 (1511f271)
ChibiOS: 4f34e217
MambaF405-2022 00410047 33335118 37333831
RCOut: PWM:1-6 NeoP:7
IMU0: normal sampling 1.0kHz/1.0kHz
Frame: HEXA/X
PreArm: RC not found

One thing I noticed in the hwdef (might be nothing)

The parent MambaF405US-I2C/hwdef.dat defines UART1 RX as:

PB7 TIM4_CH2 TIM4 RCININT PULLDOWN
PB6 USART1_TX USART1 NODMA
PB7 USART1_RX USART1 NODMA ALT(1)
PC0 USART1_RXINV OUTPUT HIGH GPIO(78) POL(0)

The child MambaF405-2022/hwdef.dat undefines PB7/PB6 and redefines them as:

PB7 USART1_RX USART1
PB6 USART1_TX USART1

So NODMA and PULLDOWN are gone, while PC0 USART1_RXINV is inherited (Betaflight also lists resource INVERTER 1 C00 for this board, so there’s a hardware inverter on the UART1 RX line for SBUS). I tried working around both via SERIAL1_OPTIONS, without luck — but I may be misunderstanding how that inverter pin is driven at boot for an RCIN port.

Questions

  1. Is anyone running ELRS/CRSF successfully on UART1 with the MambaF405-2022 target? Which version and parameters?
  2. Could the inherited PC0 USART1_RXINV pin end up in the inverted state at boot here, and is there a way to force its level to test that?
  3. Is dropping NODMA on PB7 USART1_RX in the 2022 hwdef intentional, given DMA2 Stream 2 is also used by TIM8_CH3 (motor 4) on this board?
  4. Any way to check whether bytes are arriving on that UART at all — something like a raw byte counter for the RCIN port?

Moving the RX to another UART is the obvious workaround and I’ll do it if needed, but since the same wiring demonstrably works under Betaflight I’d like to understand the root cause first.

I have the full Betaflight diff all, the original flash image and screenshots of every step, so happy to run any test that would help. Thanks a lot for reading this far.

Here is everything You need.