swaits f68e5d9be5 fix(host/uart): deliver RX to host and survive sustained bidirectional load
Two regressions on UART boards (heltec_v3_uart, etc.):

1. RADIO_THROTTLED was never cleared on UART. The throttle gate at
   src/radio.rs:2017 (added in 276f941, "chart-first restructure ...
   soak hardening") silently drops async RX while the flag is true.
   USB host_task clears it on first successful write_packet
   (src/host/usb.rs:354/373), but the UART path was never updated --
   every RX event was dropped from boot. The OLED bar lit up
   regardless because record_packet announces PacketRx before the
   gate. Mirror the USB pattern: clear on successful tx.write_all,
   re-arm on failure.

2. Once RX flowed, sustained bidirectional spam tripped the §3.4
   inactivity watchdog spuriously. The select3-based loop serialised
   read and write; tx.write_all (~25 ms per max frame at 115_200
   baud) blocked the read poll long enough for last_frame_at to age
   past 1000 ms under a saturated outbound queue. The Reset cascaded
   to radio (Unconfigured) and display (splash), leaving subsequent
   host TX commands timing out waiting for TX_DONE. Restructure
   host_task into two sub-loops joined in the same task: read_loop
   owns rx + watchdog, write_loop owns tx + throttle. The read future
   re-polls on every executor wake regardless of write progress.
   Same executor, disjoint borrows on the split rx/tx halves, no
   Mutex needed.

Also reset the FrameDecoder when the watchdog fires so a host that
resumes mid-frame resyncs cleanly on the next 0x00 sentinel (USB
gets this for free via DTR-drop reset; UART has no DTR).

Build: bump esp-hal/esp-rtos/esp-backtrace/esp-println version
requirements (1.0->1.1, 0.2->0.3, 0.18->0.19, 0.16->0.17) to match
what the upstream esp-rs/esp-hal main branch now publishes. cargo
update had invalidated the [patch.crates-io] entries since the
patched versions were no longer semver-compatible with the old
top-level requirements, which silently dropped the patches and fell
back to crates.io releases that pin embassy-executor 0.9 (mismatched
with our 0.10).
2026-04-29 22:26:16 -06:00
2026-04-03 10:28:38 -06:00
2026-04-25 20:23:39 -06:00
2026-04-07 19:52:52 -06:00
2026-04-25 20:23:39 -06:00

DongLoRa Firmware

Embedded Rust firmware for DongLoRa boards. Exposes the LoRa radio over USB CDC-ACM using a COBS-framed binary protocol.

Building

just setup              # one-time toolchain install
just build heltec_v4    # build for a specific board
just flash heltec_v4    # build + flash
just check-all          # compile-check all boards
just clippy heltec_v4   # lint
just test               # host-side protocol unit tests

All commands are run from the firmware/ directory.

Supported Boards

Board Feature MCU Radio USB Target
Heltec V3 heltec_v3 ESP32-S3 SX1262 Native CDC-ACM xtensa-esp32s3-none-elf
Heltec V3 (UART) heltec_v3_uart ESP32-S3 SX1262 CP2102 bridge xtensa-esp32s3-none-elf
Heltec V4 heltec_v4 ESP32-S3 SX1262 Native CDC-ACM xtensa-esp32s3-none-elf
ELECROW ThinkNode-M2 elecrow_thinknode_m2 ESP32-S3 SX1262 CP2102 bridge xtensa-esp32s3-none-elf
LilyGo T-Beam lilygo_tbeam ESP32 SX1276 CP2102 bridge xtensa-esp32-none-elf
LilyGo T-Beam S3 Supreme lilygo_tbeam_supreme ESP32-S3 SX1262 Native CDC-ACM xtensa-esp32s3-none-elf
RAK WisBlock 4631 rak_wisblock_4631 nRF52840 SX1262 Native CDC-ACM thumbv7em-none-eabihf
Waveshare RP2040-LoRa waveshare_rp2040_lora RP2040 SX1262 Native CDC-ACM thumbv6m-none-eabi
Wio Tracker L1 wio_tracker_l1 nRF52840 SX1262 Native CDC-ACM thumbv7em-none-eabihf

Heltec V3 USB Note

The default heltec_v3 build uses native USB CDC-ACM, which requires a hardware modification to your board. Stock Heltec V3 boards route USB through a CP2102 bridge chip to UART — the ESP32-S3's native USB pins (GPIO19/GPIO20) are routed to header pins but not connected to the USB connector.

To enable native USB on a Heltec V3:

  1. Solder 0-ohm (or 22-ohm) resistors at pads R29 (D+) and R3 (D-)
  2. Disconnect the CP2102 from the USB connector's D+/D- lines (cut traces or remove the CP2102 bridge resistors)

After this mod, the board appears as /dev/ttyACM0 with the DongLoRa VID:PID (1209:5741), just like the V4 and nRF boards.

If you have a stock (unmodified) V3, use heltec_v3_uart instead:

just build heltec_v3_uart
just flash heltec_v3_uart

This builds firmware that communicates via the CP2102 bridge (appears as /dev/ttyUSB0).

Adding a Board

See src/board/PORTING.md.

Protocol

See PROTOCOL.md for the complete wire format specification.

S
Description
No description provided
Readme MIT
575 KiB
0 Stars 1 Watchers 0 Forks
Languages
Rust 95.8%
Just 3.3%
RPC 0.5%
Jinja 0.2%
Linker Script 0.2%