Skip to main content

esp_hal/uart/
mod.rs

1//! # Universal Asynchronous Receiver/Transmitter (UART)
2//!
3//! ## Overview
4//!
5//! The UART is a hardware peripheral which handles communication using serial
6//! communication interfaces, such as RS232 and RS485. This peripheral provides!
7//! a cheap and ubiquitous method for full- and half-duplex communication
8//! between devices.
9//!
10//! Depending on your device, two or more UART controllers are available for
11//! use, all of which can be configured and used in the same way. All UART
12//! controllers are compatible with UART-enabled devices from various
13//! manufacturers, and can also support Infrared Data Association (IrDA)
14//! protocols.
15//!
16//! ## Configuration
17//!
18//! Each UART controller is individually configurable, and the usual setting
19//! such as baud rate, data bits, parity, and stop bits can easily be
20//! configured. Additionally, the receive (RX) and transmit (TX) pins need to
21//! be specified.
22//!
23//! The UART controller can be configured to invert the polarity of the pins.
24//! This is achieved by inverting the desired pins, and then constructing the
25//! UART instance using the inverted pins.
26//!
27//! ## Usage
28//!
29//! The UART driver implements a number of third-party traits, with the
30//! intention of making the HAL inter-compatible with various device drivers
31//! from the community. This includes, but is not limited to, the [embedded-hal]
32//! and [embedded-io] blocking traits, and the [embedded-hal-async] and
33//! [embedded-io-async] asynchronous traits.
34//!
35//! In addition to the interfaces provided by these traits, native APIs are also
36//! available. See the examples below for more information on how to interact
37//! with this driver.
38//!
39//! [embedded-hal]: embedded_hal
40//! [embedded-io]: embedded_io_07
41//! [embedded-hal-async]: embedded_hal_async
42//! [embedded-io-async]: embedded_io_async_07
43
44crate::unstable_driver! {
45    #[cfg(uhci_driver_supported)]
46    pub mod uhci;
47
48    #[cfg(lp_uart_driver_supported)]
49    pub mod lp_uart;
50}
51
52#[cfg_attr(uart_version = "1", path = "clocks/v1.rs")]
53#[cfg_attr(soc_has_pcr, path = "clocks/v2_pcr.rs")]
54#[cfg_attr(esp32p4, path = "clocks/v2_esp32p4.rs")]
55#[cfg_attr(esp32s31, path = "clocks/v2_esp32s31.rs")]
56mod clocks;
57
58mod compat;
59mod low_level;
60
61use core::{marker::PhantomData, sync::atomic::Ordering};
62
63use embedded_hal_async::delay::DelayNs;
64use enumset::{EnumSet, EnumSetType};
65pub use low_level::Instance;
66use low_level::{
67    Info,
68    RxEvent,
69    State,
70    TxEvent,
71    UartClockGuard,
72    UartRxFuture,
73    UartTxFuture,
74    rx_event_check_for_error,
75    sync_regs,
76};
77
78use crate::{
79    Async,
80    Blocking,
81    DriverMode,
82    gpio::{
83        InputConfig,
84        OutputConfig,
85        PinGuard,
86        Pull,
87        interconnect::{PeripheralInput, PeripheralOutput},
88    },
89    interrupt::InterruptHandler,
90    pac::uart0::RegisterBlock,
91    private::DropGuard,
92    rtc_cntl::WakeLock,
93    system::PeripheralGuard,
94};
95
96crate::any_peripheral! {
97    /// Any UART peripheral.
98    pub peripheral AnyUart<'d> {
99        #[cfg(soc_has_uart0)]
100        Uart0(crate::peripherals::UART0<'d>),
101        #[cfg(soc_has_uart1)]
102        Uart1(crate::peripherals::UART1<'d>),
103        #[cfg(soc_has_uart2)]
104        Uart2(crate::peripherals::UART2<'d>),
105        #[cfg(soc_has_uart3)]
106        Uart3(crate::peripherals::UART3<'d>),
107        #[cfg(soc_has_uart4)]
108        Uart4(crate::peripherals::UART4<'d>),
109    }
110}
111
112impl Instance for AnyUart<'_> {
113    #[inline]
114    fn parts(&self) -> (&'static Info, &'static State) {
115        any::delegate!(self, uart => { uart.parts() })
116    }
117}
118
119impl AnyUart<'_> {
120    pub(super) fn bind_peri_interrupt(&self, handler: InterruptHandler) {
121        any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
122    }
123
124    pub(super) fn disable_peri_interrupt_on_all_cores(&self) {
125        any::delegate!(self, uart => { uart.disable_peri_interrupt_on_all_cores() })
126    }
127
128    pub(super) fn set_interrupt_handler(&self, handler: InterruptHandler) {
129        self.disable_peri_interrupt_on_all_cores();
130
131        self.info().enable_listen(EnumSet::all(), false);
132        self.info().clear_interrupts(EnumSet::all());
133
134        self.bind_peri_interrupt(handler);
135    }
136}
137
138/// UART RX Error
139#[derive(Debug, Clone, Copy, PartialEq)]
140#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141#[non_exhaustive]
142pub enum RxError {
143    /// An RX FIFO overflow happened.
144    ///
145    /// This error occurs when RX FIFO is full and a new byte is received. The
146    /// RX FIFO is then automatically reset by the driver.
147    FifoOverflowed,
148
149    /// A glitch was detected on the RX line.
150    ///
151    /// This error occurs when an unexpected or erroneous signal (glitch) is
152    /// detected on the UART RX line, which could lead to incorrect data
153    /// reception.
154    GlitchOccurred,
155
156    /// A framing error was detected on the RX line.
157    ///
158    /// This error occurs when the received data does not conform to the
159    /// expected UART frame format.
160    FrameFormatViolated,
161
162    /// A parity error was detected on the RX line.
163    ///
164    /// This error occurs when the parity bit in the received data does not
165    /// match the expected parity configuration.
166    ParityMismatch,
167}
168
169impl core::error::Error for RxError {}
170
171/// UART RX error conditions that can be reported by read operations.
172///
173/// This enum can be used with [`RxConfig::with_reported_errors`] to choose
174/// which hardware RX error conditions should make read operations return an
175/// [`RxError`].
176#[derive(Debug, EnumSetType)]
177#[cfg_attr(feature = "defmt", derive(defmt::Format))]
178#[instability::unstable]
179#[non_exhaustive]
180pub enum RxErrorKind {
181    /// An RX FIFO overflow happened.
182    FifoOverflowed,
183    /// A glitch was detected on the RX line.
184    GlitchOccurred,
185    /// A framing error was detected on the RX line.
186    FrameFormatViolated,
187    /// A parity error was detected on the RX line.
188    ParityMismatch,
189}
190
191impl From<RxErrorKind> for RxError {
192    fn from(value: RxErrorKind) -> Self {
193        match value {
194            RxErrorKind::FifoOverflowed => RxError::FifoOverflowed,
195            RxErrorKind::GlitchOccurred => RxError::GlitchOccurred,
196            RxErrorKind::FrameFormatViolated => RxError::FrameFormatViolated,
197            RxErrorKind::ParityMismatch => RxError::ParityMismatch,
198        }
199    }
200}
201
202impl core::fmt::Display for RxError {
203    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
204        match self {
205            RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
206            RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
207            RxError::FrameFormatViolated => {
208                write!(f, "A framing error was detected on the RX line")
209            }
210            RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
211        }
212    }
213}
214
215/// UART TX Error
216#[derive(Debug, Clone, Copy, PartialEq)]
217#[cfg_attr(feature = "defmt", derive(defmt::Format))]
218#[non_exhaustive]
219pub enum TxError {}
220
221impl core::fmt::Display for TxError {
222    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
223        write!(f, "Tx error")
224    }
225}
226
227impl core::error::Error for TxError {}
228
229#[instability::unstable]
230pub use crate::soc::clocks::UartFunctionClockSclk as ClockSource;
231
232/// Number of data bits
233///
234/// This enum represents the various configurations for the number of data
235/// bits used in UART communication. The number of data bits defines the
236/// length of each transmitted or received data frame.
237#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
238#[cfg_attr(feature = "defmt", derive(defmt::Format))]
239pub enum DataBits {
240    /// 5 data bits per frame.
241    _5,
242    /// 6 data bits per frame.
243    _6,
244    /// 7 data bits per frame.
245    _7,
246    /// 8 data bits per frame.
247    #[default]
248    _8,
249}
250
251/// Parity check
252///
253/// Parity is a form of error detection in UART communication, used to
254/// ensure that the data has not been corrupted during transmission. The
255/// parity bit is added to the data bits to make the number of 1-bits
256/// either even or odd.
257#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
258#[cfg_attr(feature = "defmt", derive(defmt::Format))]
259pub enum Parity {
260    /// No parity bit is used.
261    #[default]
262    None,
263    /// Even parity: the parity bit is set to make the total number of
264    /// 1-bits even.
265    Even,
266    /// Odd parity: the parity bit is set to make the total number of 1-bits
267    /// odd.
268    Odd,
269}
270
271/// Number of stop bits
272///
273/// The stop bit(s) signal the end of a data packet in UART communication.
274/// This enum defines the possible configurations for the number of stop
275/// bits.
276#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
277#[cfg_attr(feature = "defmt", derive(defmt::Format))]
278pub enum StopBits {
279    /// 1 stop bit.
280    #[default]
281    _1,
282    /// 1.5 stop bits.
283    _1p5,
284    /// 2 stop bits.
285    _2,
286}
287
288/// Software flow control settings.
289#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
290#[cfg_attr(feature = "defmt", derive(defmt::Format))]
291#[instability::unstable]
292pub enum SwFlowControl {
293    #[default]
294    /// Disables software flow control.
295    Disabled,
296    /// Enables software flow control with configured parameters
297    Enabled {
298        /// Xon flow control byte.
299        xon_char: u8,
300        /// Xoff flow control byte.
301        xoff_char: u8,
302        /// If the software flow control is enabled and the data amount in
303        /// rxfifo is less than xon_thrd, an xon_char will be sent.
304        xon_threshold: u8,
305        /// If the software flow control is enabled and the data amount in
306        /// rxfifo is more than xoff_thrd, an xoff_char will be sent
307        xoff_threshold: u8,
308    },
309}
310
311/// Configuration for CTS (Clear To Send) flow control.
312#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
313#[cfg_attr(feature = "defmt", derive(defmt::Format))]
314#[instability::unstable]
315pub enum CtsConfig {
316    /// Enable CTS flow control (TX).
317    Enabled,
318    #[default]
319    /// Disable CTS flow control (TX).
320    Disabled,
321}
322
323/// Configuration for RTS (Request To Send) flow control.
324#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
325#[cfg_attr(feature = "defmt", derive(defmt::Format))]
326#[instability::unstable]
327pub enum RtsConfig {
328    /// Enable RTS flow control with a FIFO threshold (RX).
329    Enabled(u8),
330    #[default]
331    /// Disable RTS flow control.
332    Disabled,
333}
334
335/// Hardware flow control configuration.
336#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
337#[cfg_attr(feature = "defmt", derive(defmt::Format))]
338#[instability::unstable]
339pub struct HwFlowControl {
340    /// CTS configuration.
341    pub cts: CtsConfig,
342    /// RTS configuration.
343    pub rts: RtsConfig,
344}
345
346/// Defines how strictly the requested baud rate must be met.
347#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
348#[cfg_attr(feature = "defmt", derive(defmt::Format))]
349#[instability::unstable]
350pub enum BaudrateTolerance {
351    /// Accept the closest achievable baud rate without restriction.
352    #[default]
353    Closest,
354    /// In this setting, the deviation of only 1% from the desired baud value is
355    /// tolerated.
356    Exact,
357    /// Allow a certain percentage of deviation.
358    ErrorPercent(u8),
359}
360
361/// UART Configuration
362#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
363#[cfg_attr(feature = "defmt", derive(defmt::Format))]
364#[non_exhaustive]
365pub struct Config {
366    /// The baud rate (speed) of the UART communication in bits per second
367    /// (bps).
368    baudrate: u32,
369    /// Determines how close to the desired baud rate value the driver should
370    /// set the baud rate.
371    #[builder_lite(unstable)]
372    baudrate_tolerance: BaudrateTolerance,
373    /// Number of data bits in each frame (5, 6, 7, or 8 bits).
374    data_bits: DataBits,
375    /// Parity setting (None, Even, or Odd).
376    parity: Parity,
377    /// Number of stop bits in each frame (1, 1.5, or 2 bits).
378    stop_bits: StopBits,
379    /// Software flow control.
380    #[builder_lite(unstable)]
381    sw_flow_ctrl: SwFlowControl,
382    /// Hardware flow control.
383    #[builder_lite(unstable)]
384    hw_flow_ctrl: HwFlowControl,
385    /// Clock source used by the UART peripheral.
386    #[builder_lite(unstable)]
387    clock_source: ClockSource,
388    /// UART Receive part configuration.
389    rx: RxConfig,
390    /// UART Transmit part configuration.
391    tx: TxConfig,
392}
393
394impl Default for Config {
395    fn default() -> Config {
396        Config {
397            rx: RxConfig::default(),
398            tx: TxConfig::default(),
399            baudrate: 115_200,
400            baudrate_tolerance: BaudrateTolerance::default(),
401            data_bits: Default::default(),
402            parity: Default::default(),
403            stop_bits: Default::default(),
404            sw_flow_ctrl: Default::default(),
405            hw_flow_ctrl: Default::default(),
406            clock_source: Default::default(),
407        }
408    }
409}
410
411impl Config {
412    fn validate(&self) -> Result<(), ConfigError> {
413        if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
414            assert!(percentage > 0 && percentage <= 100);
415        }
416
417        // Max supported baud rate is 5Mbaud
418        if self.baudrate == 0 || self.baudrate > 5_000_000 {
419            return Err(ConfigError::BaudrateNotSupported);
420        }
421        Ok(())
422    }
423}
424
425/// UART Receive part configuration.
426#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
427#[cfg_attr(feature = "defmt", derive(defmt::Format))]
428#[non_exhaustive]
429pub struct RxConfig {
430    /// Threshold level at which the RX FIFO is considered full.
431    fifo_full_threshold: u16,
432    /// Optional timeout value for RX operations.
433    timeout: Option<u8>,
434    /// RX error conditions that read operations should report.
435    ///
436    /// Error conditions not present in this set are cleared and ignored by
437    /// UART read operations.
438    #[builder_lite(unstable, into)]
439    reported_errors: EnumSet<RxErrorKind>,
440    /// Whether received bytes with UART errors are discarded by the hardware.
441    ///
442    /// When set to `true` (the default), bytes with UART errors (for example
443    /// parity or framing errors) are not stored in the RX FIFO. Set this to
444    /// `false` to keep those bytes in the RX FIFO. Use
445    /// [`Self::with_reported_errors`] to control whether those error
446    /// conditions make read operations fail.
447    #[builder_lite(unstable)]
448    discard_erroneous_bytes: bool,
449}
450
451impl Default for RxConfig {
452    fn default() -> RxConfig {
453        RxConfig {
454            // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L61>
455            fifo_full_threshold: 120,
456            // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L63>
457            timeout: Some(10),
458            reported_errors: EnumSet::all(),
459            discard_erroneous_bytes: true,
460        }
461    }
462}
463
464/// UART Transmit part configuration.
465#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
466#[cfg_attr(feature = "defmt", derive(defmt::Format))]
467#[non_exhaustive]
468pub struct TxConfig {
469    /// Threshold level at which the TX FIFO is considered empty.
470    fifo_empty_threshold: u16,
471}
472
473impl Default for TxConfig {
474    fn default() -> TxConfig {
475        TxConfig {
476            // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L59>
477            fifo_empty_threshold: 10,
478        }
479    }
480}
481
482/// Configuration for the AT-CMD detection functionality
483#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
484#[cfg_attr(feature = "defmt", derive(defmt::Format))]
485#[instability::unstable]
486#[non_exhaustive]
487pub struct AtCmdConfig {
488    /// Optional idle time before the AT command detection begins, in clock
489    /// cycles.
490    pre_idle_count: Option<u16>,
491    /// Optional idle time after the AT command detection ends, in clock
492    /// cycles.
493    post_idle_count: Option<u16>,
494    /// Optional timeout between bytes in the AT command, in clock
495    /// cycles.
496    gap_timeout: Option<u16>,
497    /// The byte (character) that triggers the AT command detection.
498    cmd_char: u8,
499    /// Optional number of bytes to detect as part of the AT command.
500    char_num: u8,
501}
502
503impl Default for AtCmdConfig {
504    fn default() -> Self {
505        Self {
506            pre_idle_count: None,
507            post_idle_count: None,
508            gap_timeout: None,
509            cmd_char: b'+',
510            char_num: 1,
511        }
512    }
513}
514
515/// The number of edges that the hardware counts before the threshold register starts.
516#[cfg(sleep_driver_supported)]
517const WAKEUP_EDGE_OFFSET: u16 = cfg_select! {
518    esp32 => 2,
519    esp32p4 => 6,
520    _ => 3,
521};
522
523/// The smallest number of rising edges that the hardware can wake on.
524#[cfg(sleep_driver_supported)]
525const MIN_WAKEUP_EDGES: u16 = cfg_select! {
526    // With a threshold of zero, esp32 wakes again and again.
527    esp32 => WAKEUP_EDGE_OFFSET + 1,
528    _ => WAKEUP_EDGE_OFFSET,
529};
530
531/// The largest number of rising edges that the hardware can count in its 10-bit field.
532#[cfg(sleep_driver_supported)]
533const MAX_WAKEUP_EDGES: u16 = WAKEUP_EDGE_OFFSET + 0x3FF;
534
535/// Configures how the UART wakes the chip from light sleep.
536///
537/// See [`UartRx::enable_wakeup`].
538#[cfg(sleep_driver_supported)]
539#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
540#[cfg_attr(feature = "defmt", derive(defmt::Format))]
541#[instability::unstable]
542#[non_exhaustive]
543pub struct WakeupConfig {
544    /// The number of rising edges on the RX line that wakes the chip.
545    ///
546    /// The hardware counts edges, and not bytes, so the number of bytes that the chip needs
547    /// depends on the data of the sender. Each byte gives one rising edge at its stop bit, and
548    /// one more edge for each change from 0 to 1 in the data. The number of edges is therefore
549    /// the smallest possible number of bytes. The default is the smallest value that the
550    /// hardware accepts.
551    ///
552    /// The permitted range on this chip is
553    #[cfg_attr(esp32, doc = "`3..=1025`.")]
554    #[cfg_attr(esp32p4, doc = "`6..=1029`.")]
555    #[cfg_attr(not(any(esp32, esp32p4)), doc = "`3..=1026`.")]
556    rising_edges: u16,
557}
558
559#[cfg(sleep_driver_supported)]
560impl Default for WakeupConfig {
561    fn default() -> Self {
562        Self {
563            rising_edges: MIN_WAKEUP_EDGES,
564        }
565    }
566}
567
568/// A wakeup configuration error.
569#[cfg(sleep_driver_supported)]
570#[derive(Debug, Clone, Copy, PartialEq, Eq)]
571#[cfg_attr(feature = "defmt", derive(defmt::Format))]
572#[instability::unstable]
573#[non_exhaustive]
574pub enum WakeConfigError {
575    /// This UART instance cannot wake the chip.
576    NotAWakeupSource,
577
578    /// The hardware cannot count the requested number of rising edges.
579    EdgeCountUnsupported,
580}
581
582#[cfg(sleep_driver_supported)]
583#[instability::unstable]
584impl core::error::Error for WakeConfigError {}
585
586#[cfg(sleep_driver_supported)]
587#[instability::unstable]
588impl core::fmt::Display for WakeConfigError {
589    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
590        match self {
591            WakeConfigError::NotAWakeupSource => {
592                write!(f, "This UART instance cannot wake the chip")
593            }
594            WakeConfigError::EdgeCountUnsupported => {
595                write!(
596                    f,
597                    "The requested number of rising edges is not supported, it must be {MIN_WAKEUP_EDGES}..={MAX_WAKEUP_EDGES}"
598                )
599            }
600        }
601    }
602}
603
604struct UartBuilder<'d, Dm: DriverMode> {
605    uart: AnyUart<'d>,
606    phantom: PhantomData<Dm>,
607}
608
609impl<'d, Dm> UartBuilder<'d, Dm>
610where
611    Dm: DriverMode,
612{
613    fn new(uart: impl Instance + 'd) -> Self {
614        let uart = uart.degrade();
615
616        // Make sure inputs are well-defined.
617        // Connect RX to an idle high level.
618        uart.info().rx_signal.connect_to(&crate::gpio::Level::High);
619        uart.info().cts_signal.connect_to(&crate::gpio::Level::Low);
620
621        Self {
622            uart,
623            phantom: PhantomData,
624        }
625    }
626
627    fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
628        let rx_guard = PeripheralGuard::new(self.uart.info().peripheral);
629        let tx_guard = PeripheralGuard::new(self.uart.info().peripheral);
630
631        let peri_clock_guard = UartClockGuard::new(unsafe { self.uart.clone_unchecked() });
632
633        let rts_pin = PinGuard::new_unconnected();
634        let tx_pin = PinGuard::new_unconnected();
635
636        let mut serial = Uart {
637            rx: UartRx {
638                uart: unsafe { self.uart.clone_unchecked() },
639                phantom: PhantomData,
640                guard: rx_guard,
641                peri_clock_guard: peri_clock_guard.clone(),
642                // Receiving data continuously, the peripheral can't let the system sleep.
643                _wake_lock: WakeLock::new(),
644                reported_errors: config.rx.reported_errors,
645            },
646            tx: UartTx {
647                uart: self.uart,
648                phantom: PhantomData,
649                guard: tx_guard,
650                peri_clock_guard,
651                rts_pin,
652                tx_pin,
653                baudrate: config.baudrate,
654            },
655        };
656        serial.init(config)?;
657
658        Ok(serial)
659    }
660}
661
662#[procmacros::doc_replace]
663/// UART (Full-duplex)
664///
665/// ## Example
666///
667/// ```rust, no_run
668/// # {before_snippet}
669/// use esp_hal::uart::{Config, Uart};
670/// let mut uart = Uart::new(peripherals.UART0, Config::default())?
671///     .with_rx(peripherals.GPIO1)
672///     .with_tx(peripherals.GPIO2);
673///
674/// uart.write(b"Hello world!")?;
675/// # {after_snippet}
676/// ```
677pub struct Uart<'d, Dm: DriverMode> {
678    rx: UartRx<'d, Dm>,
679    tx: UartTx<'d, Dm>,
680}
681
682/// UART (Transmit)
683#[instability::unstable]
684pub struct UartTx<'d, Dm: DriverMode> {
685    uart: AnyUart<'d>,
686    phantom: PhantomData<Dm>,
687    guard: PeripheralGuard,
688    peri_clock_guard: UartClockGuard<'d>,
689    rts_pin: PinGuard,
690    tx_pin: PinGuard,
691    baudrate: u32,
692}
693
694/// UART (Receive)
695#[instability::unstable]
696pub struct UartRx<'d, Dm: DriverMode> {
697    uart: AnyUart<'d>,
698    phantom: PhantomData<Dm>,
699    guard: PeripheralGuard,
700    peri_clock_guard: UartClockGuard<'d>,
701    // Receiving data continuously, the peripheral can't let the system sleep.
702    _wake_lock: WakeLock,
703    reported_errors: EnumSet<RxErrorKind>,
704}
705
706/// A configuration error.
707#[derive(Debug, Clone, Copy, PartialEq, Eq)]
708#[cfg_attr(feature = "defmt", derive(defmt::Format))]
709#[non_exhaustive]
710pub enum ConfigError {
711    /// The requested baud rate is not achievable.
712    #[cfg(feature = "unstable")]
713    #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
714    BaudrateNotAchievable,
715
716    /// The requested baud rate is not supported.
717    ///
718    /// This error is returned if:
719    ///  * the baud rate exceeds 5MBaud or is equal to zero.
720    ///  * the user has specified an exact baud rate or with some percentage of deviation to the
721    ///    desired value, and the driver cannot reach this speed.
722    BaudrateNotSupported,
723
724    /// The requested timeout exceeds the maximum value (
725    #[cfg_attr(esp32, doc = "127")]
726    #[cfg_attr(not(esp32), doc = "1023")]
727    /// ).
728    TimeoutTooLong,
729
730    /// The requested RX FIFO threshold exceeds the maximum value (127 bytes).
731    RxFifoThresholdNotSupported,
732
733    /// The requested TX FIFO threshold exceeds the maximum value (127 bytes).
734    TxFifoThresholdNotSupported,
735}
736
737impl core::error::Error for ConfigError {}
738
739impl core::fmt::Display for ConfigError {
740    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
741        match self {
742            #[cfg(feature = "unstable")]
743            ConfigError::BaudrateNotAchievable => {
744                write!(f, "The requested baud rate is not achievable")
745            }
746            ConfigError::BaudrateNotSupported => {
747                write!(f, "The requested baud rate is not supported")
748            }
749            ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
750            ConfigError::RxFifoThresholdNotSupported => {
751                write!(f, "The requested RX FIFO threshold is not supported")
752            }
753            ConfigError::TxFifoThresholdNotSupported => {
754                write!(f, "The requested TX FIFO threshold is not supported")
755            }
756        }
757    }
758}
759
760impl<'d> UartTx<'d, Blocking> {
761    #[procmacros::doc_replace(
762        "note" => {
763            cfg(esp32) => "**esp32-specific ⚠️**: `UART2` is not recommended for use.",
764            _ => ""
765        }
766    )]
767    /// Create a new UART TX instance in [`Blocking`] mode.
768    ///
769    /// __note__
770    ///
771    /// ## Errors
772    ///
773    /// This function returns a [`ConfigError`] if the configuration is not
774    /// supported by the hardware.
775    ///
776    /// ## Example
777    ///
778    /// ```rust, no_run
779    /// # {before_snippet}
780    /// use esp_hal::uart::{Config, UartTx};
781    /// let tx = UartTx::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO1);
782    /// # {after_snippet}
783    /// ```
784    #[instability::unstable]
785    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
786        let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
787
788        Ok(uart_tx)
789    }
790
791    /// Reconfigures the driver to operate in [`Async`] mode.
792    #[instability::unstable]
793    pub fn into_async(self) -> UartTx<'d, Async> {
794        if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
795            self.uart
796                .set_interrupt_handler(self.uart.info().async_handler);
797        }
798        self.uart.state().is_tx_async.store(true, Ordering::Release);
799
800        UartTx {
801            uart: self.uart,
802            phantom: PhantomData,
803            guard: self.guard,
804            peri_clock_guard: self.peri_clock_guard,
805            rts_pin: self.rts_pin,
806            tx_pin: self.tx_pin,
807            baudrate: self.baudrate,
808        }
809    }
810}
811
812impl<'d> UartTx<'d, Async> {
813    /// Reconfigures the driver to operate in [`Blocking`] mode.
814    #[instability::unstable]
815    pub fn into_blocking(self) -> UartTx<'d, Blocking> {
816        self.uart
817            .state()
818            .is_tx_async
819            .store(false, Ordering::Release);
820        if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
821            self.uart.disable_peri_interrupt_on_all_cores();
822        }
823
824        UartTx {
825            uart: self.uart,
826            phantom: PhantomData,
827            guard: self.guard,
828            peri_clock_guard: self.peri_clock_guard,
829            rts_pin: self.rts_pin,
830            tx_pin: self.tx_pin,
831            baudrate: self.baudrate,
832        }
833    }
834
835    /// Write data into the TX buffer.
836    ///
837    /// This function writes the provided buffer `bytes` into the UART transmit
838    /// buffer. If the buffer is full, the function waits asynchronously for
839    /// space in the buffer to become available.
840    ///
841    /// The function returns the number of bytes written into the buffer. This
842    /// may be less than the length of the buffer.
843    ///
844    /// Upon an error, the function returns immediately and the contents of the
845    /// internal FIFO are not modified.
846    ///
847    /// ## Cancellation
848    ///
849    /// This function is cancellation safe.
850    pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
851        // We need to loop in case the TX empty interrupt was fired but not cleared
852        // before, but the FIFO itself was filled up by a previous write.
853        let space = loop {
854            let tx_fifo_count = self.uart.info().tx_fifo_count();
855            let space = Info::UART_FIFO_SIZE - tx_fifo_count;
856            if space != 0 {
857                break space;
858            }
859            UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
860        };
861
862        let free = (space as usize).min(bytes.len());
863
864        for &byte in &bytes[..free] {
865            self.uart
866                .info()
867                .regs()
868                .fifo()
869                .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
870        }
871
872        Ok(free)
873    }
874
875    /// Asynchronously flushes the UART transmit buffer.
876    ///
877    /// This function ensures that all pending data in the transmit FIFO has
878    /// been sent over the UART. If the FIFO contains data, it waits for the
879    /// transmission to complete before returning.
880    ///
881    /// ## Cancellation
882    ///
883    /// This function is cancellation safe.
884    pub async fn flush_async(&mut self) -> Result<(), TxError> {
885        // Nothing is guaranteed to clear the Done status, so let's loop here in case Tx
886        // was Done before the last write operation that pushed data into the
887        // FIFO.
888        while self.uart.info().tx_fifo_count() > 0 {
889            UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
890        }
891
892        self.flush_last_byte();
893
894        Ok(())
895    }
896
897    /// Sends a break signal for a specified duration in bit time.
898    ///
899    /// Duration is in bits, the time it takes to transfer one bit at the
900    /// current baud rate.
901    ///
902    /// This function restores the original TX line state after the break signal is sent, even if
903    /// the future is cancelled.
904    #[instability::unstable]
905    pub async fn send_break_async<D: DelayNs>(&mut self, delay: &mut D, bits: u32) {
906        // Calculate total delay in microseconds
907        let total_delay_us = (bits as u64 * 1_000_000) / self.baudrate as u64;
908        let delay_us = (total_delay_us as u32).max(1);
909
910        let break_guard = self.start_break();
911
912        delay.delay_us(delay_us).await;
913
914        core::mem::drop(break_guard);
915    }
916}
917
918impl<'d, Dm> UartTx<'d, Dm>
919where
920    Dm: DriverMode,
921{
922    /// Configure RTS pin
923    #[instability::unstable]
924    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
925        let rts = rts.into();
926
927        rts.apply_output_config(&OutputConfig::default());
928        rts.set_output_enable(true);
929
930        self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
931
932        self
933    }
934
935    /// Assign the TX pin for UART instance.
936    ///
937    /// Sets the specified pin to push-pull output and connects it to the UART
938    /// TX signal.
939    ///
940    /// Disconnects the previous pin that was assigned with `with_tx`.
941    #[instability::unstable]
942    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
943        let tx = tx.into();
944
945        // Make sure we don't cause an unexpected low pulse on the pin.
946        tx.set_output_high(true);
947        tx.apply_output_config(&OutputConfig::default());
948        tx.set_output_enable(true);
949
950        self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
951
952        self
953    }
954
955    /// Change the configuration.
956    ///
957    /// ## Errors
958    ///
959    /// This function returns a [`ConfigError`] if the configuration is not
960    /// supported by the hardware.
961    #[instability::unstable]
962    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
963        self.uart
964            .info()
965            .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
966        self.uart.info().txfifo_reset();
967        Ok(())
968    }
969
970    /// Returns whether the UART buffer is ready to accept more data.
971    ///
972    /// If this function returns `true`, [`Self::write`] will not block.
973    #[instability::unstable]
974    pub fn write_ready(&self) -> bool {
975        self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
976    }
977
978    /// Write bytes.
979    ///
980    /// This function writes data to the internal TX FIFO of the UART
981    /// peripheral. The data is then transmitted over the UART TX line.
982    ///
983    /// The function returns the number of bytes written to the FIFO. This may
984    /// be less than the length of the provided data. The function may only
985    /// return 0 if the provided data is empty.
986    ///
987    /// ## Errors
988    ///
989    /// This function returns a [`TxError`] if an error occurred during the
990    /// write operation.
991    #[instability::unstable]
992    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
993        self.uart.info().write(data)
994    }
995
996    fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
997        while !data.is_empty() {
998            let bytes_written = self.write(data)?;
999            data = &data[bytes_written..];
1000        }
1001        Ok(())
1002    }
1003
1004    /// Flush the transmit buffer.
1005    ///
1006    /// This function blocks until all data in the TX FIFO has been
1007    /// transmitted.
1008    #[instability::unstable]
1009    pub fn flush(&mut self) -> Result<(), TxError> {
1010        while self.uart.info().tx_fifo_count() > 0 {}
1011        self.flush_last_byte();
1012        Ok(())
1013    }
1014
1015    fn flush_last_byte(&mut self) {
1016        // This function handles an edge case that happens when the TX FIFO count
1017        // changes to 0. The FSM is in the Idle state for a short while after
1018        // the last byte is moved out of the FIFO. It is unclear how long this
1019        // takes, but 10us seems to be a good enough duration to wait, for both
1020        // fast and slow baud rates.
1021        crate::rom::ets_delay_us(10);
1022        while !self.is_tx_idle() {}
1023    }
1024
1025    /// Sends a break signal for a specified duration in bit time.
1026    ///
1027    /// Duration is in bits, the time it takes to transfer one bit at the
1028    /// current baud rate. The delay during the break is just busy-waiting.
1029    #[instability::unstable]
1030    pub fn send_break(&mut self, bits: u32) {
1031        // Calculate total delay in microseconds
1032        let total_delay_us = (bits as u64 * 1_000_000) / self.baudrate as u64;
1033        let delay_us = (total_delay_us as u32).max(1);
1034
1035        let break_guard = self.start_break();
1036
1037        crate::rom::ets_delay_us(delay_us);
1038
1039        core::mem::drop(break_guard);
1040    }
1041
1042    fn start_break(&mut self) -> impl Drop + '_ {
1043        // Read the current TX inversion state
1044        let original_conf0 = self.uart.info().regs().conf0().read();
1045        let original_txd_inv = original_conf0.txd_inv().bit();
1046
1047        // Invert the TX line (toggle the current state)
1048        self.uart
1049            .info()
1050            .regs()
1051            .conf0()
1052            .modify(|_, w| w.txd_inv().bit(!original_txd_inv));
1053
1054        sync_regs(self.uart.info().regs());
1055
1056        // Restore the original register state when dropped.
1057        DropGuard::new(self, move |this| {
1058            this.uart
1059                .info()
1060                .regs()
1061                .conf0()
1062                .write(|w| unsafe { w.bits(original_conf0.bits()) });
1063            sync_regs(this.uart.info().regs());
1064        })
1065    }
1066
1067    /// Checks if the TX line is idle for this UART instance.
1068    ///
1069    /// Returns `true` if the transmit line is idle, meaning no data is
1070    /// currently being transmitted.
1071    fn is_tx_idle(&self) -> bool {
1072        self.uart.info().is_tx_idle()
1073    }
1074
1075    /// Disables all TX-related interrupts for this UART instance.
1076    ///
1077    /// This function clears and disables the `transmit FIFO empty` interrupt,
1078    /// `transmit break done`, `transmit break idle done`, and `transmit done`
1079    /// interrupts.
1080    fn disable_tx_interrupts(&self) {
1081        self.regs().int_clr().write(|w| {
1082            w.txfifo_empty().clear_bit_by_one();
1083            w.tx_brk_done().clear_bit_by_one();
1084            w.tx_brk_idle_done().clear_bit_by_one();
1085            w.tx_done().clear_bit_by_one()
1086        });
1087
1088        self.regs().int_ena().write(|w| {
1089            w.txfifo_empty().clear_bit();
1090            w.tx_brk_done().clear_bit();
1091            w.tx_brk_idle_done().clear_bit();
1092            w.tx_done().clear_bit()
1093        });
1094    }
1095
1096    fn regs(&self) -> &RegisterBlock {
1097        self.uart.info().regs()
1098    }
1099}
1100
1101impl<'d> UartRx<'d, Blocking> {
1102    #[procmacros::doc_replace(
1103        "note" => {
1104            cfg(esp32) => "**esp32-specific ⚠️**: `UART2` is not recommended for use.",
1105            _ => ""
1106        }
1107    )]
1108    /// Create a new UART RX instance in [`Blocking`] mode.
1109    ///
1110    /// __note__
1111    ///
1112    /// ## Errors
1113    ///
1114    /// This function returns a [`ConfigError`] if the configuration is not
1115    /// supported by the hardware.
1116    ///
1117    /// ```rust, no_run
1118    /// # {before_snippet}
1119    /// use esp_hal::uart::{Config, UartRx};
1120    /// let rx = UartRx::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO2);
1121    /// # {after_snippet}
1122    /// ```
1123    #[instability::unstable]
1124    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1125        let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
1126
1127        Ok(uart_rx)
1128    }
1129
1130    /// Waits for a break condition to be detected.
1131    ///
1132    /// This function polls the break-detection interrupt status and returns once
1133    /// the receiver has detected a break condition. After detection, the break
1134    /// status is automatically cleared.
1135    #[instability::unstable]
1136    pub fn wait_for_break(&mut self) {
1137        while !self.is_break_detected() {
1138            // wait
1139        }
1140
1141        self.clear_break_detected();
1142    }
1143
1144    /// Waits for a break condition to be detected with a timeout.
1145    ///
1146    /// This function polls the break-detection interrupt status until a break is
1147    /// detected or the specified timeout expires. Returns `true` if a break was
1148    /// detected, `false` if the timeout elapsed. After successful detection, the
1149    /// break status is automatically cleared.
1150    ///
1151    /// ## Arguments
1152    /// * `timeout` - Maximum time to wait for a break condition
1153    #[instability::unstable]
1154    pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1155        let start = crate::time::Instant::now();
1156
1157        while !self.is_break_detected() {
1158            if crate::time::Instant::now() - start >= timeout {
1159                return false;
1160            }
1161        }
1162
1163        self.clear_break_detected();
1164        true
1165    }
1166
1167    /// Reconfigures the driver to operate in [`Async`] mode.
1168    #[instability::unstable]
1169    pub fn into_async(self) -> UartRx<'d, Async> {
1170        if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1171            self.uart
1172                .set_interrupt_handler(self.uart.info().async_handler);
1173        }
1174        self.uart.state().is_rx_async.store(true, Ordering::Release);
1175
1176        UartRx {
1177            uart: self.uart,
1178            phantom: PhantomData,
1179            guard: self.guard,
1180            peri_clock_guard: self.peri_clock_guard,
1181            _wake_lock: self._wake_lock,
1182            reported_errors: self.reported_errors,
1183        }
1184    }
1185}
1186
1187impl<'d> UartRx<'d, Async> {
1188    /// Reconfigures the driver to operate in [`Blocking`] mode.
1189    #[instability::unstable]
1190    pub fn into_blocking(self) -> UartRx<'d, Blocking> {
1191        self.uart
1192            .state()
1193            .is_rx_async
1194            .store(false, Ordering::Release);
1195        if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1196            self.uart.disable_peri_interrupt_on_all_cores();
1197        }
1198
1199        UartRx {
1200            uart: self.uart,
1201            phantom: PhantomData,
1202            guard: self.guard,
1203            peri_clock_guard: self.peri_clock_guard,
1204            _wake_lock: self._wake_lock,
1205            reported_errors: self.reported_errors,
1206        }
1207    }
1208
1209    async fn wait_for_buffered_data(
1210        &mut self,
1211        minimum: usize,
1212        max_threshold: usize,
1213        listen_for_timeout: bool,
1214    ) -> Result<(), RxError> {
1215        let current_threshold = self.uart.info().rx_fifo_full_threshold();
1216
1217        // User preference takes priority.
1218        let max_threshold = max_threshold.min(current_threshold as usize) as u16;
1219        let minimum = minimum.min(Info::RX_FIFO_MAX_THRHD as usize) as u16;
1220
1221        // The effective threshold must be >= minimum. We ensure this by lowering the minimum number
1222        // of returnable bytes.
1223        let minimum = minimum.min(max_threshold);
1224
1225        // loop to prevent returning 0 bytes
1226        while self.uart.info().rx_fifo_count() < minimum {
1227            // We're ignoring the user configuration here to ensure that this is not waiting
1228            // for more data than the buffer. We'll restore the original value after the
1229            // future resolved.
1230            let info = self.uart.info();
1231            unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
1232            let _guard = DropGuard::new((), |_| {
1233                unwrap!(info.set_rx_fifo_full_threshold(current_threshold));
1234            });
1235
1236            // Wait for space or event
1237            let mut events = RxEvent::FifoFull
1238                | RxEvent::FifoOvf
1239                | RxEvent::FrameError
1240                | RxEvent::GlitchDetected
1241                | RxEvent::ParityError;
1242
1243            if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1244                events |= RxEvent::CmdCharDetected;
1245            }
1246
1247            if listen_for_timeout && self.uart.info().rx_timeout_enabled() {
1248                events |= RxEvent::FifoTout;
1249            }
1250
1251            let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1252
1253            if events.contains(RxEvent::FifoOvf) {
1254                self.uart.info().rxfifo_reset();
1255            }
1256            rx_event_check_for_error(events, self.reported_errors)?;
1257        }
1258
1259        Ok(())
1260    }
1261
1262    /// Read data asynchronously.
1263    ///
1264    /// This function reads data from the UART receive buffer into the
1265    /// provided buffer. If the buffer is empty, the function waits
1266    /// asynchronously for data to become available, or for an error to occur.
1267    ///
1268    /// The function returns the number of bytes read into the buffer. This may
1269    /// be less than the length of the buffer.
1270    ///
1271    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1272    /// to ensure that it does not wait for more data than the buffer can hold.
1273    ///
1274    /// Upon an error, the function returns immediately and the contents of the
1275    /// internal FIFO are not modified.
1276    ///
1277    /// ## Cancellation
1278    ///
1279    /// This function is cancellation safe.
1280    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1281        if buf.is_empty() {
1282            return Ok(0);
1283        }
1284
1285        self.wait_for_buffered_data(1, buf.len(), true).await?;
1286
1287        self.read_buffered(buf)
1288    }
1289
1290    /// Fill buffer asynchronously.
1291    ///
1292    /// This function reads data into the provided buffer. If the internal FIFO
1293    /// does not contain enough data, the function waits asynchronously for data
1294    /// to become available, or for an error to occur.
1295    ///
1296    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1297    /// to ensure that it does not wait for more data than the buffer can hold.
1298    ///
1299    /// ## Cancellation
1300    ///
1301    /// This function is **not** cancellation safe. If the future is dropped
1302    /// before it resolves, or if an error occurs during the read operation,
1303    /// previously read data may be lost.
1304    pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1305        if buf.is_empty() {
1306            return Ok(());
1307        }
1308
1309        // Drain the buffer first, there's no point in waiting for data we've already received.
1310        let read = self.read_buffered(buf)?;
1311        buf = &mut buf[read..];
1312
1313        while !buf.is_empty() {
1314            // No point in listening for timeouts, as we're waiting for an exact amount of
1315            // data. On ESP32 and S2, the timeout interrupt can't be cleared unless the FIFO
1316            // is empty, so listening could cause an infinite loop here.
1317            self.wait_for_buffered_data(buf.len(), buf.len(), false)
1318                .await?;
1319
1320            let read = self.read_buffered(buf)?;
1321            buf = &mut buf[read..];
1322        }
1323
1324        Ok(())
1325    }
1326
1327    /// Waits for a break condition to be detected asynchronously.
1328    ///
1329    /// This is an async function that will await until a break condition is
1330    /// detected on the RX line. After detection, the break interrupt flag is
1331    /// automatically cleared.
1332    #[instability::unstable]
1333    pub async fn wait_for_break_async(&mut self) {
1334        UartRxFuture::new(self.uart.reborrow(), RxEvent::BreakDetected).await;
1335    }
1336}
1337
1338impl<'d, Dm> UartRx<'d, Dm>
1339where
1340    Dm: DriverMode,
1341{
1342    fn regs(&self) -> &RegisterBlock {
1343        self.uart.info().regs()
1344    }
1345
1346    /// Assign the CTS pin for UART instance.
1347    ///
1348    /// Sets the specified pin to input and connects it to the UART CTS signal.
1349    #[instability::unstable]
1350    pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1351        let cts = cts.into();
1352
1353        cts.apply_input_config(&InputConfig::default());
1354        cts.set_input_enable(true);
1355
1356        self.uart.info().cts_signal.connect_to(&cts);
1357
1358        self
1359    }
1360
1361    /// Assign the RX pin for UART instance.
1362    ///
1363    /// Sets the specified pin to input and connects it to the UART RX signal.
1364    ///
1365    /// Note: when you listen for the output of the UART peripheral, you should
1366    /// configure the driver side (i.e. the TX pin), or ensure that the line is
1367    /// initially high, to avoid receiving a non-data byte caused by an
1368    /// initial low signal level.
1369    #[instability::unstable]
1370    pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1371        let rx = rx.into();
1372
1373        rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1374        rx.set_input_enable(true);
1375
1376        self.uart.info().rx_signal.connect_to(&rx);
1377
1378        self
1379    }
1380
1381    /// Returns whether a break condition has been detected.
1382    ///
1383    /// The returned status is sticky and remains set until
1384    /// [`Self::clear_break_detected`] is called, or until one of the
1385    /// `wait_for_break` methods observes and clears it.
1386    #[instability::unstable]
1387    pub fn is_break_detected(&self) -> bool {
1388        self.uart.info().check_rx_break_detected()
1389    }
1390
1391    /// Clears the break-detection status.
1392    #[instability::unstable]
1393    pub fn clear_break_detected(&mut self) {
1394        self.uart.info().clear_rx_break_detected();
1395    }
1396
1397    /// Change the configuration.
1398    ///
1399    /// ## Errors
1400    ///
1401    /// This function returns a [`ConfigError`] if the configuration is not
1402    /// supported by the hardware.
1403    #[instability::unstable]
1404    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1405        self.uart
1406            .info()
1407            .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1408        self.uart
1409            .info()
1410            .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1411        self.uart
1412            .info()
1413            .set_discard_erroneous_bytes(config.rx.discard_erroneous_bytes);
1414        self.reported_errors = config.rx.reported_errors;
1415
1416        self.uart.info().rxfifo_reset();
1417        Ok(())
1418    }
1419
1420    /// Lets activity on the RX line wake the chip from light sleep.
1421    ///
1422    /// The chip wakes when it counts the number of rising edges that
1423    /// [`WakeupConfig::with_rising_edges`] gives. Deep sleep powers the UART down, so this source
1424    /// ends a light sleep only.
1425    ///
1426    /// The chip loses the bytes that cause the wake. It also loses the bytes that arrive during the
1427    /// wake, and at a typical baud rate that wake is long enough to lose several bytes. A sender
1428    /// must therefore first send data that the receiver can lose, and then send the data again.
1429    /// The first data after the wake also clears the internal wakeup indication. Without that
1430    /// write, the next wake occurs two edges early.
1431    ///
1432    /// The peripheral counts the edges itself, so a light sleep keeps the high-performance
1433    /// peripherals powered instead of powering them down. This increases the sleep current.
1434    ///
1435    /// The configuration stays after the driver is dropped, so that the UART continues to wake the
1436    /// chip while no driver owns it. Call [`Self::disable_wakeup`] to remove it.
1437    ///
1438    /// # Errors
1439    ///
1440    /// Returns [`WakeConfigError::NotAWakeupSource`] if this UART instance cannot wake the chip,
1441    /// and [`WakeConfigError::EdgeCountUnsupported`] if the hardware cannot count the requested
1442    /// number of edges.
1443    #[cfg(sleep_driver_supported)]
1444    #[instability::unstable]
1445    pub fn enable_wakeup(&mut self, config: &WakeupConfig) -> Result<(), WakeConfigError> {
1446        self.uart.info().enable_wakeup(config)
1447    }
1448
1449    /// Stops the UART from waking the chip.
1450    #[cfg(sleep_driver_supported)]
1451    #[instability::unstable]
1452    pub fn disable_wakeup(&mut self) {
1453        self.uart.info().disable_wakeup();
1454    }
1455
1456    /// Reads and clears RX error conditions set by received data.
1457    ///
1458    /// Only errors enabled in [`RxConfig::with_reported_errors`] are returned;
1459    /// disabled errors are cleared and ignored.
1460    ///
1461    /// If a FIFO overflow is detected, the RX FIFO is reset.
1462    #[instability::unstable]
1463    pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1464        self.uart.info().check_for_errors(self.reported_errors)
1465    }
1466
1467    /// Returns whether the UART buffer has data.
1468    ///
1469    /// If this function returns `true`, [`Self::read`] will not block.
1470    #[instability::unstable]
1471    pub fn read_ready(&self) -> bool {
1472        self.uart.info().rx_fifo_count() > 0
1473    }
1474
1475    /// Read bytes.
1476    ///
1477    /// The UART hardware continuously receives bytes and stores them in the RX
1478    /// FIFO. This function reads the bytes from the RX FIFO and returns
1479    /// them in the provided buffer. If the hardware buffer is empty, this
1480    /// function will block until data is available. The [`Self::read_ready`]
1481    /// function can be used to check if data is available without blocking.
1482    ///
1483    /// The function returns the number of bytes read into the buffer. This may
1484    /// be less than the length of the buffer. This function only returns 0
1485    /// if the provided buffer is empty.
1486    ///
1487    /// ## Errors
1488    ///
1489    /// This function returns an [`RxError`] if a reported error occurred since
1490    /// the last call to [`Self::check_for_errors`], [`Self::read_buffered`], or
1491    /// this function.
1492    ///
1493    /// If the error occurred before this function was called, the contents of
1494    /// the FIFO are not modified.
1495    #[instability::unstable]
1496    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1497        self.uart.info().read(buf, self.reported_errors)
1498    }
1499
1500    /// Read already received bytes.
1501    ///
1502    /// This function reads the already received bytes from the FIFO into the
1503    /// provided buffer. The function does not wait for the FIFO to actually
1504    /// contain any bytes.
1505    ///
1506    /// The function returns the number of bytes read into the buffer. This may
1507    /// be less than the length of the buffer, and it may also be 0.
1508    ///
1509    /// ## Errors
1510    ///
1511    /// This function returns an [`RxError`] if a reported error occurred since
1512    /// the last call to [`Self::check_for_errors`], [`Self::read`], or this
1513    /// function.
1514    ///
1515    /// If the error occurred before this function was called, the contents of
1516    /// the FIFO are not modified.
1517    #[instability::unstable]
1518    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1519        self.uart.info().read_buffered(buf, self.reported_errors)
1520    }
1521
1522    /// Disables all RX-related interrupts for this UART instance.
1523    ///
1524    /// This function clears and disables the `receive FIFO full` interrupt,
1525    /// `receive FIFO overflow`, `receive FIFO timeout`, and `AT command
1526    /// byte detection` interrupts.
1527    fn disable_rx_interrupts(&self) {
1528        self.regs().int_clr().write(|w| {
1529            w.rxfifo_full().clear_bit_by_one();
1530            w.rxfifo_ovf().clear_bit_by_one();
1531            w.rxfifo_tout().clear_bit_by_one();
1532            w.at_cmd_char_det().clear_bit_by_one()
1533        });
1534
1535        self.regs().int_ena().write(|w| {
1536            w.rxfifo_full().clear_bit();
1537            w.rxfifo_ovf().clear_bit();
1538            w.rxfifo_tout().clear_bit();
1539            w.at_cmd_char_det().clear_bit()
1540        });
1541    }
1542}
1543
1544impl<'d> Uart<'d, Blocking> {
1545    #[procmacros::doc_replace(
1546        "note" => {
1547            cfg(esp32) => "**esp32-specific ⚠️**: `UART2` is not recommended for use.",
1548            _ => ""
1549        }
1550    )]
1551    /// Create a new UART instance in [`Blocking`] mode.
1552    ///
1553    /// __note__
1554    ///
1555    /// ## Errors
1556    ///
1557    /// This function returns a [`ConfigError`] if the configuration is not
1558    /// supported by the hardware.
1559    ///
1560    /// ## Example
1561    ///
1562    /// ```rust, no_run
1563    /// # {before_snippet}
1564    /// use esp_hal::uart::{Config, Uart};
1565    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1566    ///     .with_rx(peripherals.GPIO1)
1567    ///     .with_tx(peripherals.GPIO2);
1568    /// # {after_snippet}
1569    /// ```
1570    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1571        UartBuilder::new(uart).init(config)
1572    }
1573
1574    /// Reconfigures the driver to operate in [`Async`] mode.
1575    ///
1576    /// See the [`Async`] documentation for an example on how to use this
1577    /// method.
1578    pub fn into_async(self) -> Uart<'d, Async> {
1579        Uart {
1580            rx: self.rx.into_async(),
1581            tx: self.tx.into_async(),
1582        }
1583    }
1584
1585    #[cfg_attr(
1586        not(multi_core),
1587        doc = "Registers an interrupt handler for the peripheral."
1588    )]
1589    #[cfg_attr(
1590        multi_core,
1591        doc = "Registers an interrupt handler for the peripheral on the current core."
1592    )]
1593    #[doc = ""]
1594    /// Note that this will replace any previously registered interrupt
1595    /// handlers.
1596    ///
1597    /// You can restore the default/unhandled interrupt handler by using
1598    /// [crate::interrupt::DEFAULT_INTERRUPT_HANDLER]
1599    #[instability::unstable]
1600    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1601        // `self.tx.uart` and `self.rx.uart` are the same
1602        self.tx.uart.set_interrupt_handler(handler);
1603    }
1604
1605    #[procmacros::doc_replace]
1606    /// Listen for the given interrupts
1607    ///
1608    /// ## Example
1609    ///
1610    /// **Note**: In practice a proper serial terminal should be used
1611    /// to connect to the board (espflash won't work)
1612    ///
1613    /// ```rust, no_run
1614    /// # {before_snippet}
1615    /// use esp_hal::{
1616    ///     delay::Delay,
1617    ///     uart::{AtCmdConfig, Config, RxConfig, Uart, UartInterrupt},
1618    /// };
1619    /// # let delay = Delay::new();
1620    /// # let config = Config::default().with_rx(
1621    /// #    RxConfig::default().with_fifo_full_threshold(30)
1622    /// # );
1623    /// # let mut uart = Uart::new(
1624    /// #    peripherals.UART0,
1625    /// #    config)?;
1626    /// uart.set_interrupt_handler(interrupt_handler);
1627    ///
1628    /// critical_section::with(|cs| {
1629    ///     uart.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
1630    ///     uart.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1631    ///
1632    ///     SERIAL.borrow_ref_mut(cs).replace(uart);
1633    /// });
1634    ///
1635    /// loop {
1636    ///     println!("Send `#` character or >=30 characters");
1637    ///     delay.delay(Duration::from_secs(1));
1638    /// }
1639    /// # }
1640    ///
1641    /// use core::cell::RefCell;
1642    ///
1643    /// use critical_section::Mutex;
1644    /// use esp_hal::uart::Uart;
1645    /// static SERIAL: Mutex<RefCell<Option<Uart<esp_hal::Blocking>>>> = Mutex::new(RefCell::new(None));
1646    ///
1647    /// use core::fmt::Write;
1648    ///
1649    /// use esp_hal::uart::UartInterrupt;
1650    /// #[esp_hal::handler]
1651    /// fn interrupt_handler() {
1652    ///     critical_section::with(|cs| {
1653    ///         let mut serial = SERIAL.borrow_ref_mut(cs);
1654    ///         if let Some(serial) = serial.as_mut() {
1655    ///             let mut buf = [0u8; 64];
1656    ///             if let Ok(cnt) = serial.read_buffered(&mut buf) {
1657    ///                 println!("Read {} bytes", cnt);
1658    ///             }
1659    ///
1660    ///             let pending_interrupts = serial.interrupts();
1661    ///             println!(
1662    ///                 "Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
1663    ///                 pending_interrupts.contains(UartInterrupt::AtCmd),
1664    ///                 pending_interrupts.contains(UartInterrupt::RxFifoFull),
1665    ///             );
1666    ///
1667    ///             serial.clear_interrupts(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1668    ///         }
1669    ///     });
1670    /// }
1671    /// ```
1672    #[instability::unstable]
1673    pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1674        self.tx.uart.info().enable_listen(interrupts.into(), true)
1675    }
1676
1677    /// Unlisten the given interrupts
1678    #[instability::unstable]
1679    pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1680        self.tx.uart.info().enable_listen(interrupts.into(), false)
1681    }
1682
1683    /// Gets asserted interrupts
1684    #[instability::unstable]
1685    pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1686        self.tx.uart.info().interrupts()
1687    }
1688
1689    /// Resets asserted interrupts
1690    #[instability::unstable]
1691    pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1692        self.tx.uart.info().clear_interrupts(interrupts)
1693    }
1694
1695    /// Waits for a break condition to be detected.
1696    ///
1697    /// This is a blocking function that will continuously check for a break condition.
1698    /// After detection, the break interrupt flag is automatically cleared.
1699    #[instability::unstable]
1700    pub fn wait_for_break(&mut self) {
1701        self.rx.wait_for_break()
1702    }
1703
1704    /// Waits for a break condition to be detected with a timeout.
1705    ///
1706    /// This is a blocking function that will check for a break condition up to
1707    /// the specified timeout. Returns `true` if a break was detected, `false` if
1708    /// the timeout elapsed. After successful detection, the break interrupt flag
1709    /// is automatically cleared.
1710    ///
1711    /// ## Arguments
1712    /// * `timeout` - Maximum time to wait for a break condition
1713    #[instability::unstable]
1714    pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1715        self.rx.wait_for_break_with_timeout(timeout)
1716    }
1717}
1718
1719impl<'d> Uart<'d, Async> {
1720    /// Reconfigures the driver to operate in [`Blocking`] mode.
1721    ///
1722    /// See the [`Blocking`] documentation for an example on how to use this
1723    /// method.
1724    pub fn into_blocking(self) -> Uart<'d, Blocking> {
1725        Uart {
1726            rx: self.rx.into_blocking(),
1727            tx: self.tx.into_blocking(),
1728        }
1729    }
1730
1731    #[procmacros::doc_replace]
1732    /// Write data into the TX buffer.
1733    ///
1734    /// This function writes the provided buffer `bytes` into the UART transmit
1735    /// buffer. If the buffer is full, the function waits asynchronously for
1736    /// space in the buffer to become available.
1737    ///
1738    /// The function returns the number of bytes written into the buffer. This
1739    /// may be less than the length of the buffer.
1740    ///
1741    /// Upon an error, the function returns immediately and the contents of the
1742    /// internal FIFO are not modified.
1743    ///
1744    /// ## Cancellation
1745    ///
1746    /// This function is cancellation safe.
1747    ///
1748    /// ## Example
1749    ///
1750    /// ```rust, no_run
1751    /// # {before_snippet}
1752    /// use esp_hal::uart::{Config, Uart};
1753    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1754    ///     .with_rx(peripherals.GPIO1)
1755    ///     .with_tx(peripherals.GPIO2)
1756    ///     .into_async();
1757    ///
1758    /// const MESSAGE: &[u8] = b"Hello, world!";
1759    /// uart.write_async(&MESSAGE).await?;
1760    /// # {after_snippet}
1761    /// ```
1762    pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1763        self.tx.write_async(words).await
1764    }
1765
1766    #[procmacros::doc_replace]
1767    /// Asynchronously flushes the UART transmit buffer.
1768    ///
1769    /// This function ensures that all pending data in the transmit FIFO has
1770    /// been sent over the UART. If the FIFO contains data, it waits for the
1771    /// transmission to complete before returning.
1772    ///
1773    /// ## Cancellation
1774    ///
1775    /// This function is cancellation safe.
1776    ///
1777    /// ## Example
1778    ///
1779    /// ```rust, no_run
1780    /// # {before_snippet}
1781    /// use esp_hal::uart::{Config, Uart};
1782    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1783    ///     .with_rx(peripherals.GPIO1)
1784    ///     .with_tx(peripherals.GPIO2)
1785    ///     .into_async();
1786    ///
1787    /// const MESSAGE: &[u8] = b"Hello, world!";
1788    /// uart.write_async(&MESSAGE).await?;
1789    /// uart.flush_async().await?;
1790    /// # {after_snippet}
1791    /// ```
1792    pub async fn flush_async(&mut self) -> Result<(), TxError> {
1793        self.tx.flush_async().await
1794    }
1795
1796    #[procmacros::doc_replace]
1797    /// Read data asynchronously.
1798    ///
1799    /// This function reads data from the UART receive buffer into the
1800    /// provided buffer. If the buffer is empty, the function waits
1801    /// asynchronously for data to become available, or for an error to occur.
1802    ///
1803    /// The function returns the number of bytes read into the buffer. This may
1804    /// be less than the length of the buffer.
1805    ///
1806    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1807    /// to ensure that it does not wait for more data than the buffer can hold.
1808    ///
1809    /// Upon an error, the function returns immediately and the contents of the
1810    /// internal FIFO are not modified.
1811    ///
1812    /// ## Cancellation
1813    ///
1814    /// This function is cancellation safe.
1815    ///
1816    /// ## Example
1817    ///
1818    /// ```rust, no_run
1819    /// # {before_snippet}
1820    /// use esp_hal::uart::{Config, Uart};
1821    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1822    ///     .with_rx(peripherals.GPIO1)
1823    ///     .with_tx(peripherals.GPIO2)
1824    ///     .into_async();
1825    ///
1826    /// const MESSAGE: &[u8] = b"Hello, world!";
1827    /// uart.write_async(&MESSAGE).await?;
1828    /// uart.flush_async().await?;
1829    ///
1830    /// let mut buf = [0u8; MESSAGE.len()];
1831    /// uart.read_async(&mut buf[..]).await?;
1832    /// # {after_snippet}
1833    /// ```
1834    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1835        self.rx.read_async(buf).await
1836    }
1837
1838    /// Fill buffer asynchronously.
1839    ///
1840    /// This function reads data from the UART receive buffer into the
1841    /// provided buffer. If the buffer is empty, the function waits
1842    /// asynchronously for data to become available, or for an error to occur.
1843    ///
1844    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1845    /// to ensure that it does not wait for more data than the buffer can hold.
1846    ///
1847    /// ## Cancellation
1848    ///
1849    /// This function is **not** cancellation safe. If the future is dropped
1850    /// before it resolves, or if an error occurs during the read operation,
1851    /// previously read data may be lost.
1852    #[instability::unstable]
1853    pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1854        self.rx.read_exact_async(buf).await
1855    }
1856
1857    /// Waits for a break condition to be detected asynchronously.
1858    ///
1859    /// This is an async function that will await until a break condition is
1860    /// detected on the RX line. After detection, the break interrupt flag is
1861    /// automatically cleared.
1862    #[instability::unstable]
1863    pub async fn wait_for_break_async(&mut self) {
1864        self.rx.wait_for_break_async().await
1865    }
1866
1867    /// Sends a break signal for a specified duration in bit time.
1868    ///
1869    /// Duration is in bits, the time it takes to transfer one bit at the
1870    /// current baud rate.
1871    ///
1872    /// This function restores the original TX line state after the break signal is sent, even if
1873    /// the future is cancelled.
1874    #[instability::unstable]
1875    pub async fn send_break_async<D: DelayNs>(&mut self, delay: &mut D, bits: u32) {
1876        self.tx.send_break_async(delay, bits).await
1877    }
1878}
1879
1880/// List of exposed UART events.
1881#[derive(Debug, EnumSetType)]
1882#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1883#[non_exhaustive]
1884#[instability::unstable]
1885pub enum UartInterrupt {
1886    /// Indicates that the receiver has detected the configured
1887    /// [`Uart::set_at_cmd`] byte.
1888    AtCmd,
1889
1890    /// The transmitter has finished sending out all data from the FIFO.
1891    TxDone,
1892
1893    /// Break condition has been detected.
1894    /// Triggered when the receiver detects a NULL character (i.e. logic 0 for
1895    /// one NULL character transmission) after stop bits.
1896    RxBreakDetected,
1897
1898    /// The receiver has received more data than what
1899    /// [`RxConfig::fifo_full_threshold`] specifies.
1900    RxFifoFull,
1901
1902    /// The receiver has not received any data for the time
1903    /// [`RxConfig::with_timeout`] specifies.
1904    RxTimeout,
1905}
1906
1907impl<'d, Dm> Uart<'d, Dm>
1908where
1909    Dm: DriverMode,
1910{
1911    #[procmacros::doc_replace]
1912    /// Assign the RX pin for UART instance.
1913    ///
1914    /// Sets the specified pin to input and connects it to the UART RX signal.
1915    ///
1916    /// Note: when you listen for the output of the UART peripheral, you should
1917    /// configure the driver side (i.e. the TX pin), or ensure that the line is
1918    /// initially high, to avoid receiving a non-data byte caused by an
1919    /// initial low signal level.
1920    ///
1921    /// ## Example
1922    ///
1923    /// ```rust, no_run
1924    /// # {before_snippet}
1925    /// use esp_hal::uart::{Config, Uart};
1926    /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO1);
1927    ///
1928    /// # {after_snippet}
1929    /// ```
1930    pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1931        self.rx = self.rx.with_rx(rx);
1932        self
1933    }
1934
1935    #[procmacros::doc_replace]
1936    /// Assign the TX pin for UART instance.
1937    ///
1938    /// Sets the specified pin to push-pull output and connects it to the UART
1939    /// TX signal.
1940    ///
1941    /// ## Example
1942    ///
1943    /// ```rust, no_run
1944    /// # {before_snippet}
1945    /// use esp_hal::uart::{Config, Uart};
1946    /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO2);
1947    ///
1948    /// # {after_snippet}
1949    /// ```
1950    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1951        self.tx = self.tx.with_tx(tx);
1952        self
1953    }
1954
1955    #[procmacros::doc_replace]
1956    /// Configure CTS pin
1957    ///
1958    /// ## Example
1959    ///
1960    /// ```rust, no_run
1961    /// # {before_snippet}
1962    /// use esp_hal::uart::{Config, Uart};
1963    /// let uart = Uart::new(peripherals.UART0, Config::default())?
1964    ///     .with_rx(peripherals.GPIO1)
1965    ///     .with_cts(peripherals.GPIO3);
1966    ///
1967    /// # {after_snippet}
1968    /// ```
1969    pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1970        self.rx = self.rx.with_cts(cts);
1971        self
1972    }
1973
1974    #[procmacros::doc_replace]
1975    /// Configure RTS pin
1976    ///
1977    /// ## Example
1978    ///
1979    /// ```rust, no_run
1980    /// # {before_snippet}
1981    /// use esp_hal::uart::{Config, Uart};
1982    /// let uart = Uart::new(peripherals.UART0, Config::default())?
1983    ///     .with_tx(peripherals.GPIO2)
1984    ///     .with_rts(peripherals.GPIO3);
1985    ///
1986    /// # {after_snippet}
1987    /// ```
1988    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1989        self.tx = self.tx.with_rts(rts);
1990        self
1991    }
1992
1993    fn regs(&self) -> &RegisterBlock {
1994        // `self.tx.uart` and `self.rx.uart` are the same
1995        self.tx.uart.info().regs()
1996    }
1997
1998    #[procmacros::doc_replace]
1999    /// Returns whether the UART TX buffer is ready to accept more data.
2000    ///
2001    /// If this function returns `true`, [`Self::write`] and [`Self::write_async`]
2002    /// will not block. Otherwise, the functions will not return until the buffer is
2003    /// ready.
2004    ///
2005    /// ## Example
2006    ///
2007    /// ```rust, no_run
2008    /// # {before_snippet}
2009    /// use esp_hal::uart::{Config, Uart};
2010    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2011    ///
2012    /// if uart.write_ready() {
2013    ///     // Because write_ready has returned true, the following call will immediately
2014    ///     // copy some bytes into the FIFO and return a non-zero value.
2015    ///     let written = uart.write(b"Hello")?;
2016    ///     // ... handle written bytes
2017    /// } else {
2018    ///     // Calling write would have blocked, but here we can do something useful
2019    ///     // instead of waiting for the buffer to become ready.
2020    /// }
2021    /// # {after_snippet}
2022    /// ```
2023    pub fn write_ready(&self) -> bool {
2024        self.tx.write_ready()
2025    }
2026
2027    #[procmacros::doc_replace]
2028    /// Writes bytes.
2029    ///
2030    /// This function writes data to the internal TX FIFO of the UART
2031    /// peripheral. The data is then transmitted over the UART TX line.
2032    ///
2033    /// The function returns the number of bytes written to the FIFO. This may
2034    /// be less than the length of the provided data. The function may only
2035    /// return 0 if the provided data is empty.
2036    ///
2037    /// ## Errors
2038    ///
2039    /// This function returns a [`TxError`] if an error occurred during the
2040    /// write operation.
2041    ///
2042    /// ## Example
2043    ///
2044    /// ```rust, no_run
2045    /// # {before_snippet}
2046    /// use esp_hal::uart::{Config, Uart};
2047    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2048    ///
2049    /// const MESSAGE: &[u8] = b"Hello, world!";
2050    /// uart.write(&MESSAGE)?;
2051    /// # {after_snippet}
2052    /// ```
2053    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
2054        self.tx.write(data)
2055    }
2056
2057    #[procmacros::doc_replace]
2058    /// Flush the transmit buffer of the UART
2059    ///
2060    /// ## Example
2061    ///
2062    /// ```rust, no_run
2063    /// # {before_snippet}
2064    /// use esp_hal::uart::{Config, Uart};
2065    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2066    ///
2067    /// const MESSAGE: &[u8] = b"Hello, world!";
2068    /// uart.write(&MESSAGE)?;
2069    /// uart.flush()?;
2070    /// # {after_snippet}
2071    /// ```
2072    pub fn flush(&mut self) -> Result<(), TxError> {
2073        self.tx.flush()
2074    }
2075
2076    /// Sends a break signal for a specified duration
2077    #[instability::unstable]
2078    pub fn send_break(&mut self, bits: u32) {
2079        self.tx.send_break(bits)
2080    }
2081
2082    #[procmacros::doc_replace]
2083    /// Returns whether the UART receive buffer has at least one byte of data.
2084    ///
2085    /// If this function returns `true`, [`Self::read`] and [`Self::read_async`]
2086    /// will not block. Otherwise, they will not return until data is available.
2087    ///
2088    /// Data that does not get stored due to an error will be lost and does not count
2089    /// towards the number of bytes in the receive buffer.
2090    // TODO: once we add support for UART_ERR_WR_MASK it needs to be documented here.
2091    /// ## Example
2092    ///
2093    /// ```rust, no_run
2094    /// # {before_snippet}
2095    /// use esp_hal::uart::{Config, Uart};
2096    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2097    ///
2098    /// while !uart.read_ready() {
2099    ///     // Do something else while waiting for data to be available.
2100    /// }
2101    ///
2102    /// let mut buf = [0u8; 32];
2103    /// uart.read(&mut buf[..])?;
2104    ///
2105    /// # {after_snippet}
2106    /// ```
2107    pub fn read_ready(&self) -> bool {
2108        self.rx.read_ready()
2109    }
2110
2111    /// Returns whether a break condition has been detected.
2112    ///
2113    /// The returned status is sticky and remains set until
2114    /// [`Self::clear_break_detected`] is called, or until one of the
2115    /// `wait_for_break` methods observes and clears it.
2116    #[instability::unstable]
2117    pub fn is_break_detected(&self) -> bool {
2118        self.rx.is_break_detected()
2119    }
2120
2121    /// Clears the break-detection status.
2122    #[instability::unstable]
2123    pub fn clear_break_detected(&mut self) {
2124        self.rx.clear_break_detected();
2125    }
2126
2127    #[procmacros::doc_replace]
2128    /// Read received bytes.
2129    ///
2130    /// The UART hardware continuously receives bytes and stores them in the RX
2131    /// FIFO. This function reads the bytes from the RX FIFO and returns
2132    /// them in the provided buffer. If the hardware buffer is empty, this
2133    /// function will block until data is available. The [`Self::read_ready`]
2134    /// function can be used to check if data is available without blocking.
2135    ///
2136    /// The function returns the number of bytes read into the buffer. This may
2137    /// be less than the length of the buffer. This function only returns 0
2138    /// if the provided buffer is empty.
2139    ///
2140    /// ## Errors
2141    ///
2142    /// This function returns an [`RxError`] if a reported error occurred since
2143    /// the last check for errors.
2144    ///
2145    /// If the error occurred before this function was called, the contents of
2146    /// the FIFO are not modified.
2147    ///
2148    /// ## Example
2149    ///
2150    /// ```rust, no_run
2151    /// # {before_snippet}
2152    /// use esp_hal::uart::{Config, Uart};
2153    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2154    ///
2155    /// const MESSAGE: &[u8] = b"Hello, world!";
2156    /// uart.write(&MESSAGE)?;
2157    /// uart.flush()?;
2158    ///
2159    /// let mut buf = [0u8; MESSAGE.len()];
2160    /// uart.read(&mut buf[..])?;
2161    ///
2162    /// # {after_snippet}
2163    /// ```
2164    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2165        self.rx.read(buf)
2166    }
2167
2168    #[procmacros::doc_replace]
2169    /// Change the configuration.
2170    ///
2171    /// ## Errors
2172    ///
2173    /// This function returns a [`ConfigError`] if the configuration is not
2174    /// supported by the hardware.
2175    ///
2176    /// ## Example
2177    ///
2178    /// ```rust, no_run
2179    /// # {before_snippet}
2180    /// use esp_hal::uart::{Config, Uart};
2181    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2182    ///
2183    /// uart.apply_config(&Config::default().with_baudrate(19_200))?;
2184    /// # {after_snippet}
2185    /// ```
2186    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
2187        // Must apply the common settings first, as `rx.apply_config` reads back symbol
2188        // size.
2189        self.rx.uart.info().apply_config(config)?;
2190
2191        self.rx.apply_config(config)?;
2192        self.tx.apply_config(config)?;
2193        Ok(())
2194    }
2195
2196    /// Lets activity on the RX line wake the chip from light sleep.
2197    ///
2198    /// See [`UartRx::enable_wakeup`].
2199    ///
2200    /// # Errors
2201    ///
2202    /// Returns [`WakeConfigError::NotAWakeupSource`] if this UART instance cannot wake the chip,
2203    /// and [`WakeConfigError::EdgeCountUnsupported`] if the hardware cannot count the requested
2204    /// number of edges.
2205    #[cfg(sleep_driver_supported)]
2206    #[instability::unstable]
2207    pub fn enable_wakeup(&mut self, config: &WakeupConfig) -> Result<(), WakeConfigError> {
2208        self.rx.enable_wakeup(config)
2209    }
2210
2211    /// Stops the UART from waking the chip.
2212    #[cfg(sleep_driver_supported)]
2213    #[instability::unstable]
2214    pub fn disable_wakeup(&mut self) {
2215        self.rx.disable_wakeup();
2216    }
2217
2218    #[procmacros::doc_replace]
2219    /// Split the UART into a transmitter and receiver
2220    ///
2221    /// This is particularly useful when having two tasks correlating to
2222    /// transmitting and receiving.
2223    ///
2224    /// ## Example
2225    ///
2226    /// ```rust, no_run
2227    /// # {before_snippet}
2228    /// use esp_hal::uart::{Config, Uart};
2229    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
2230    ///     .with_rx(peripherals.GPIO1)
2231    ///     .with_tx(peripherals.GPIO2);
2232    ///
2233    /// // The UART can be split into separate Transmit and Receive components:
2234    /// let (mut rx, mut tx) = uart.split();
2235    ///
2236    /// // Each component can be used individually to interact with the UART:
2237    /// tx.write(&[42u8])?;
2238    /// let mut byte = [0u8; 1];
2239    /// rx.read(&mut byte);
2240    /// # {after_snippet}
2241    /// ```
2242    #[instability::unstable]
2243    pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
2244        (self.rx, self.tx)
2245    }
2246
2247    #[procmacros::doc_replace]
2248    /// Borrows the UART as separate transmitter and receiver halves.
2249    ///
2250    /// Unlike [`split`], this method does not consume the UART. The returned
2251    /// transmitter and receiver are borrowed from the original UART, which can
2252    /// be used again after those borrows end.
2253    ///
2254    /// This is particularly useful when running separate transmit and receive
2255    /// futures concurrently.
2256    ///
2257    /// ## Example
2258    ///
2259    /// ```rust, no_run
2260    /// # {before_snippet}
2261    /// use esp_hal::uart::{Config, Uart};
2262    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
2263    ///     .with_rx(peripherals.GPIO1)
2264    ///     .with_tx(peripherals.GPIO2);
2265    ///
2266    /// loop {
2267    ///     // The UART can be split into separate Transmit and Receive components:
2268    ///     let (rx, tx) = uart.split_mut();
2269    ///
2270    ///     // Each component can be used individually to interact with the UART:
2271    ///     tx.write(&[42u8])?;
2272    ///     let mut byte = [0u8; 1];
2273    ///     rx.read(&mut byte);
2274    /// }
2275    /// # {after_snippet}
2276    /// ```
2277    #[instability::unstable]
2278    pub fn split_mut(&mut self) -> (&mut UartRx<'d, Dm>, &mut UartTx<'d, Dm>) {
2279        (&mut self.rx, &mut self.tx)
2280    }
2281
2282    /// Reads and clears RX error conditions set by received data.
2283    ///
2284    /// Only errors enabled in [`RxConfig::with_reported_errors`] are returned;
2285    /// disabled errors are cleared and ignored.
2286    #[instability::unstable]
2287    pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
2288        self.rx.check_for_errors()
2289    }
2290
2291    /// Read already received bytes.
2292    ///
2293    /// This function reads the already received bytes from the FIFO into the
2294    /// provided buffer. The function does not wait for the FIFO to actually
2295    /// contain any bytes.
2296    ///
2297    /// The function returns the number of bytes read into the buffer. This may
2298    /// be less than the length of the buffer, and it may also be 0.
2299    ///
2300    /// ## Errors
2301    ///
2302    /// This function returns an [`RxError`] if a reported error occurred since
2303    /// the last check for errors.
2304    ///
2305    /// If the error occurred before this function was called, the contents of
2306    /// the FIFO are not modified.
2307    #[instability::unstable]
2308    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2309        self.rx.read_buffered(buf)
2310    }
2311
2312    /// Configures the AT-CMD detection settings
2313    #[instability::unstable]
2314    pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
2315        #[cfg(uart_has_sclk_enable)]
2316        self.rx.uart.info().set_at_cmd_clock_enabled(false);
2317
2318        self.regs().at_cmd_char().write(|w| unsafe {
2319            w.at_cmd_char().bits(config.cmd_char);
2320            w.char_num().bits(config.char_num)
2321        });
2322
2323        if let Some(pre_idle_count) = config.pre_idle_count {
2324            self.regs()
2325                .at_cmd_precnt()
2326                .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
2327        }
2328
2329        if let Some(post_idle_count) = config.post_idle_count {
2330            self.regs()
2331                .at_cmd_postcnt()
2332                .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
2333        }
2334
2335        if let Some(gap_timeout) = config.gap_timeout {
2336            self.regs()
2337                .at_cmd_gaptout()
2338                .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
2339        }
2340
2341        #[cfg(uart_has_sclk_enable)]
2342        self.rx.uart.info().set_at_cmd_clock_enabled(true);
2343
2344        sync_regs(self.regs());
2345    }
2346
2347    #[inline(always)]
2348    fn init(&mut self, config: Config) -> Result<(), ConfigError> {
2349        self.rx.disable_rx_interrupts();
2350        self.tx.disable_tx_interrupts();
2351
2352        // Applying config also resets Tx/Rx FIFOs
2353        self.apply_config(&config)?;
2354
2355        // Don't wait after transmissions by default,
2356        // so that bytes written to TX FIFO are always immediately transmitted.
2357        self.regs()
2358            .idle_conf()
2359            .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2360        // `idle_conf` is a sync register.
2361        sync_regs(self.regs());
2362
2363        crate::rom::ets_delay_us(15);
2364
2365        // Make sure we are starting in a "clean state" - previous operations might have
2366        // run into error conditions
2367        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
2368
2369        Ok(())
2370    }
2371}
2372
2373/// UART Tx or Rx Error
2374#[instability::unstable]
2375#[derive(Debug, Clone, Copy, PartialEq)]
2376#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2377#[non_exhaustive]
2378pub enum IoError {
2379    /// UART TX error
2380    Tx(TxError),
2381    /// UART RX error
2382    Rx(RxError),
2383}
2384
2385#[instability::unstable]
2386impl core::error::Error for IoError {}
2387
2388#[instability::unstable]
2389impl core::fmt::Display for IoError {
2390    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2391        match self {
2392            IoError::Tx(e) => e.fmt(f),
2393            IoError::Rx(e) => e.fmt(f),
2394        }
2395    }
2396}
2397
2398#[instability::unstable]
2399impl From<RxError> for IoError {
2400    fn from(e: RxError) -> Self {
2401        IoError::Rx(e)
2402    }
2403}
2404
2405#[instability::unstable]
2406impl From<TxError> for IoError {
2407    fn from(e: TxError) -> Self {
2408        IoError::Tx(e)
2409    }
2410}