sl-firmware created pull request seb/saltylab-firmware#111

sl-firmware
Mon, 02 Mar 2026 08:37:06 -0500

111#feat(rc): CRSF/ELRS RC integration — telemetry uplink + channel fix (Issue #103)#

Summary

Closes #103 — CRSF/ELRS 2.4GHz RC receiver integration on STM32F722.

What was already done (from crsf-elrs branch)

CRSF frame decoder on UART4, 420000 baud, DMA circular buffer + IDLE interrupt

Channel map, arm switch (CH5), failsafe disarm, mode manager (CH6 3-pos blend)

RC override of autonomous: mode_manager blends steer/speed per CH6 mode

New in this PR

include/config.h

CH1[0]=steer, CH2[1]=throttle (corrected from CH4/CH3)

CRSF_FAILSAFE_MS 300→500ms per spec

VBAT_SCALE_NUM, VBAT_AREF_MV, VBAT_ADC_BITS — Mamba F722 11:1 divider

CRSF_TELEMETRY_HZ = 1 — telemetry TX rate

include/battery.h + src/battery.c (new)

ADC3 single-shot on PC1 (ADC123_IN11), 480-cycle sampling

battery_read_mv() → Vbat in millivolts

battery_estimate_pct() → 0–100% SoC, auto-detects 3S vs 4S

include/crsf.h + src/crsf.c — CRSF telemetry TX uplink

crsf_send_battery(voltage_mv, current_ma, remaining_pct) — type 0x08
voltage in 100mV units, current in 100mA units, big-endian, CRC8-DVB-S2

crsf_send_flight_mode(armed) — type 0x21, "ARMED\0"/"DISARM\0" string

crsf_build_frame() shared internal helper

src/main.c

battery_init() called after crsf_init()

1Hz telemetry tick: crsf_send_battery(vbat_mv, 0, soc_pct) + crsf_send_flight_mode(armed)

test/test_crsf_frames.py — 28 pytest tests

CRC8-DVB-S2 correctness

Battery frame: sync, type, voltage/current encoding, capacity=0, SoC byte, length

Flight-mode frame: text payload, null terminator, length, CRC

battery_estimate_pct: 3S/4S full/empty/mid, auto-detection boundary

Test plan

pytest test/test_crsf_frames.py -v — 28 tests pass

Connect ELRS receiver on UART4 (PA0/PA1 at 420000 baud)

Verify /uwb/ranges RC channels on USB telemetry stream (ch1–ch4 µs values)

Confirm failsafe: unplug RX → robot disarms within 500ms

Confirm arm hold: CH5 high → hold 3s → armed; CH5 low → disarm

Confirm CH6 mode switch: low=RC manual, mid=assisted, high=autonomous

Verify handset OSD shows battery voltage and ARMED/DISARM state

🤖 Generated with Claude Code