Motivation
picocom -b 921600 /dev/ttyACM0 --lower-dtr --lower-rts is the canonical
"open the port without resetting the MCU" recipe for embedded developers
working with Arduino-style boards (where DTR/RTS are wired to the
reset / boot pins). Today rtcom has no equivalent, forcing users to
either:
- Open the port (which asserts both lines via the OS default), then
manually press ^A t and ^A g to deassert. Two extra
keystrokes plus a brief high-level pulse on each line — enough to
reset some boards.
- Live with the reset.
Neither matches what picocom --lower-dtr --lower-rts does atomically
right after open().
Proposal
Add four boolean CLI flags mirroring picocom 1:1:
- `--lower-dtr` — deassert DTR immediately after opening the device.
- `--lower-rts` — deassert RTS immediately after opening the device.
- `--raise-dtr` — assert DTR immediately after opening the device.
- `--raise-rts` — assert RTS immediately after opening the device.
`--lower-X` and `--raise-X` for the same line are mutually exclusive
(clap can enforce via `conflicts_with`). Default behaviour is unchanged
from today (whatever the OS / driver gives us at `open()`, which is
typically both lines asserted).
Implementation sketch
`crates/rtcom-cli/src/args.rs`:
```rust
/// Deassert DTR immediately after opening the device.
#[arg(long, conflicts_with = "raise_dtr")]
pub lower_dtr: bool,
/// Assert DTR immediately after opening the device.
#[arg(long, conflicts_with = "lower_dtr")]
pub raise_dtr: bool,
// ... rts equivalents ...
```
`crates/rtcom-cli/src/main.rs::async_main` — between
`SerialPortDevice::open` and `Session::new`:
```rust
if cli.lower_dtr { device.set_dtr(false)?; }
else if cli.raise_dtr { device.set_dtr(true)?; }
if cli.lower_rts { device.set_rts(false)?; }
else if cli.raise_rts { device.set_rts(true)?; }
```
`crates/rtcom-core/src/session.rs` — accept the initial DTR/RTS state
via builders so the cached `dtr_asserted` / `rts_asserted` matches
reality and the first `^A t` toggle does the right thing:
```rust
session = session.with_initial_dtr(false).with_initial_rts(false);
```
Or simpler: have main set the lines directly and call
`session.with_initial_lines(dtr, rts)` (one builder, two args).
Acceptance
Out of scope (separate issue if anyone asks)
- `--dtr=low|high|toggle` value-style flag. More flexible but the
boolean pair already covers the picocom muscle-memory case; defer
until someone needs the runtime-toggle-at-startup variant.
- Honouring `--no-reset` semantics. `--no-reset` currently means
"don't toggle DTR at startup"; with this issue landed it can be
documented as equivalent to `--lower-dtr` for Arduino-reset wiring.
References
- picocom(1) man page, `--lower-dtr` / `--lower-rts` / `--raise-*`
- Real-hardware session that surfaced the gap: see the smoke-test
log on local dev, late v0.1 polish.
Tracker: planned for v0.2.
Motivation
picocom -b 921600 /dev/ttyACM0 --lower-dtr --lower-rtsis the canonical"open the port without resetting the MCU" recipe for embedded developers
working with Arduino-style boards (where DTR/RTS are wired to the
reset / boot pins). Today rtcom has no equivalent, forcing users to
either:
manually press
^A tand^A gto deassert. Two extrakeystrokes plus a brief high-level pulse on each line — enough to
reset some boards.
Neither matches what
picocom --lower-dtr --lower-rtsdoes atomicallyright after
open().Proposal
Add four boolean CLI flags mirroring picocom 1:1:
`--lower-X` and `--raise-X` for the same line are mutually exclusive
(clap can enforce via `conflicts_with`). Default behaviour is unchanged
from today (whatever the OS / driver gives us at `open()`, which is
typically both lines asserted).
Implementation sketch
`crates/rtcom-cli/src/args.rs`:
```rust
/// Deassert DTR immediately after opening the device.
#[arg(long, conflicts_with = "raise_dtr")]
pub lower_dtr: bool,
/// Assert DTR immediately after opening the device.
#[arg(long, conflicts_with = "lower_dtr")]
pub raise_dtr: bool,
// ... rts equivalents ...
```
`crates/rtcom-cli/src/main.rs::async_main` — between
`SerialPortDevice::open` and `Session::new`:
```rust
if cli.lower_dtr { device.set_dtr(false)?; }
else if cli.raise_dtr { device.set_dtr(true)?; }
if cli.lower_rts { device.set_rts(false)?; }
else if cli.raise_rts { device.set_rts(true)?; }
```
`crates/rtcom-core/src/session.rs` — accept the initial DTR/RTS state
via builders so the cached `dtr_asserted` / `rts_asserted` matches
reality and the first `^A t` toggle does the right thing:
```rust
session = session.with_initial_dtr(false).with_initial_rts(false);
```
Or simpler: have main set the lines directly and call
`session.with_initial_lines(dtr, rts)` (one builder, two args).
Acceptance
runs cleanly.
`DTR: asserted`); next `^A t` deasserts again.
doing the second one wins.
single-flag parses, mutual exclusion errors.
via builder and asserts `session.dtr_asserted` / `rts_asserted`
reflect the value.
callouts.
Out of scope (separate issue if anyone asks)
boolean pair already covers the picocom muscle-memory case; defer
until someone needs the runtime-toggle-at-startup variant.
"don't toggle DTR at startup"; with this issue landed it can be
documented as equivalent to `--lower-dtr` for Arduino-reset wiring.
References
log on local dev, late v0.1 polish.
Tracker: planned for v0.2.