From 88a067461030bcfa81d00032462c04a9125b1260 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Sat, 15 Aug 2026 09:47:50 +0200 Subject: [PATCH 1/2] doc: tighten cts/hw control flow wording In my latest understanding, I do optional "software-assisted" hardware control flow with this optional check. The proper "hardware control flow" would mean that on CTS I receive an ModemStatus change interrupt. For the synchronous nature of the driver, this is okay. If one builds a interrupt-driven asynchronous driver around it, one may disable that and perform the necessary checks in the "send on interrupt" handler. --- src/config.rs | 10 +++++----- src/lib.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 6777db4..b0bf0a7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -151,12 +151,12 @@ pub struct Config { pub extra_stop_bits: bool, /// Whether parity bits should be used. pub parity: Parity, - /// Whether to wait for CTS before sending. + /// Whether transmission should honor the remote CTS signal. /// /// Only activate this if your hardware connects the CTS/RTS flow control - /// signals and you wish to make use of them. Keep this setting disabled to - /// make sure that the UART works when CTS is left disconnected. - pub flow_control: bool, + /// signals and you wish to make use of them. Leave it disabled for + /// connections that only use TX/RX/GND, where CTS might remain deasserted. + pub check_cts_before_sending: bool, } impl Config { @@ -182,7 +182,7 @@ impl Config { data_bits: WordLength::EightBits, extra_stop_bits: false, parity: Parity::Disabled, - flow_control: false, + check_cts_before_sending: false, }; } diff --git a/src/lib.rs b/src/lib.rs index 7fb3281..d9a0788 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -398,6 +398,8 @@ impl Uart16550 { /// is done only in a context where such operations are valid and safe /// (e.g., you have exclusive device access). /// + /// It is recommended to disable interrupts before calling this function. + /// /// Further, the serial config must match the expectations of the receiver /// on the other side. Otherwise, garbage will be received. pub fn init(&mut self, config: Config) -> Result<(), InitError> { @@ -677,9 +679,7 @@ impl Uart16550 { return Err(ByteSendError::NoCapacity); } - // Software flow control. TODO, what to do with hardware flow control? - // Is this something we can and should support? - if self.config.flow_control { + if self.config.check_cts_before_sending { // The CTS line is meaningless when in loopback mode. let mcr = self.mcr(); if !mcr.contains(MCR::LOOP_BACK) { From 114d2ec8afe5be0465ccbc43017b8f01146e335e Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Sat, 15 Aug 2026 09:57:19 +0200 Subject: [PATCH 2/2] doc: tighten CTS/hardware flow control wording The optional CTS check implements software-assisted CTS flow control. On a synchronous driver, checking CTS before transmission is a reasonable way to honor the remote flow-control signal. An interrupt-driven driver can instead use ModemStatus interrupts to track CTS changes and stop/resume transmission accordingly. UARTs with automatic CTS support can handle this directly in hardware. In practice, this is uncommon for classic 16550/16550A UARTs and is mainly found in enhanced 16550-compatible implementations. --- src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index d9a0788..e30a207 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -285,6 +285,11 @@ mod tty; /// [`Uart16550::new_mmio()`] create an instance of a device with the /// corresponding backend. /// +/// # Synchronous, Asynchronous, and Interrupt-driven Operation +/// +/// This is a **synchronous** driver that exposes interrupt configuration, +/// making it possible to build an asynchronous, interrupt-driven driver on top. +/// /// # Hints for Usage on Real Hardware /// /// Please note that real hardware often behaves quite differently. Just because