fix(mesh): deassert DTR/RTS before serial probes to avoid ESP32-S3 native-USB resets
Heltec V3/V4-class boards use the ESP32-S3's native USB-Serial-JTAG peripheral (no discrete USB-UART bridge chip), which resets the chip on a DTR/RTS transition — the same mechanism esptool uses to force bootloader entry. The Meshcore/Meshtastic/RNode serial probes all open the port with library defaults (DTR/RTS asserted), so each probe attempt was likely rebooting a real, correctly RNode-flashed Heltec board mid-handshake, surfacing as an endless "No supported mesh radio found" retry loop. Deassert both lines immediately after open and let the board settle before writing, in all three probe paths. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
7f657ab099
commit
9bbbb046a8
@ -180,6 +180,12 @@ impl MeshtasticDevice {
|
|||||||
"Failed to open serial port {} (permission denied? device busy?)",
|
"Failed to open serial port {} (permission denied? device busy?)",
|
||||||
path
|
path
|
||||||
))?;
|
))?;
|
||||||
|
// See probe_rnode() in reticulum.rs for why: ESP32-S3 native-USB
|
||||||
|
// boards reset on a DTR/RTS transition, so deassert both and settle
|
||||||
|
// before the handshake below.
|
||||||
|
let _ = port.set_dtr(false);
|
||||||
|
let _ = port.set_rts(false);
|
||||||
|
tokio::time::sleep(Duration::from_millis(300)).await;
|
||||||
info!(path = %path, baud = BAUD_RATE, "Opened Meshtastic serial port");
|
info!(path = %path, baud = BAUD_RATE, "Opened Meshtastic serial port");
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|||||||
@ -1005,6 +1005,14 @@ fn parse_hash16(hex_str: &str) -> Result<[u8; 16]> {
|
|||||||
async fn probe_rnode(path: &str) -> Result<()> {
|
async fn probe_rnode(path: &str) -> Result<()> {
|
||||||
let port = serial2_tokio::SerialPort::open(path, PROBE_BAUD)
|
let port = serial2_tokio::SerialPort::open(path, PROBE_BAUD)
|
||||||
.with_context(|| format!("Failed to open {} for Reticulum probe", path))?;
|
.with_context(|| format!("Failed to open {} for Reticulum probe", path))?;
|
||||||
|
// ESP32-S3 native-USB boards (Heltec V3/V4 etc. — no separate USB-UART
|
||||||
|
// bridge chip) treat a DTR/RTS transition on open as a reset signal, the
|
||||||
|
// same mechanism esptool uses to force bootloader entry. Deassert both
|
||||||
|
// and let the board settle before writing the probe, or the reboot eats
|
||||||
|
// the DETECT_RESP window below.
|
||||||
|
let _ = port.set_dtr(false);
|
||||||
|
let _ = port.set_rts(false);
|
||||||
|
tokio::time::sleep(Duration::from_millis(300)).await;
|
||||||
let probe: [u8; 13] = [
|
let probe: [u8; 13] = [
|
||||||
KISS_FEND,
|
KISS_FEND,
|
||||||
KISS_CMD_DETECT,
|
KISS_CMD_DETECT,
|
||||||
|
|||||||
@ -57,6 +57,12 @@ impl MeshcoreDevice {
|
|||||||
"Failed to open serial port {} (permission denied? device busy?)",
|
"Failed to open serial port {} (permission denied? device busy?)",
|
||||||
path
|
path
|
||||||
))?;
|
))?;
|
||||||
|
// See probe_rnode() in reticulum.rs for why: ESP32-S3 native-USB
|
||||||
|
// boards reset on a DTR/RTS transition, so deassert both and settle
|
||||||
|
// before the handshake below.
|
||||||
|
let _ = port.set_dtr(false);
|
||||||
|
let _ = port.set_rts(false);
|
||||||
|
tokio::time::sleep(Duration::from_millis(300)).await;
|
||||||
|
|
||||||
info!(path = %path, baud = BAUD_RATE, "Opened serial port");
|
info!(path = %path, baud = BAUD_RATE, "Opened serial port");
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user