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    /// UHCI wrapper around UART
46    #[cfg(uhci_driver_supported)]
47    pub mod uhci;
48}
49
50use core::{marker::PhantomData, sync::atomic::Ordering, task::Poll};
51
52use enumset::{EnumSet, EnumSetType};
53use portable_atomic::AtomicBool;
54
55use crate::{
56    Async,
57    Blocking,
58    DriverMode,
59    asynch::AtomicWaker,
60    gpio::{
61        InputConfig,
62        InputSignal,
63        OutputConfig,
64        OutputSignal,
65        PinGuard,
66        Pull,
67        interconnect::{PeripheralInput, PeripheralOutput},
68    },
69    handler,
70    interrupt::InterruptHandler,
71    pac::uart0::RegisterBlock,
72    private::DropGuard,
73    ram,
74    soc::clocks::{self, ClockTree},
75    system::PeripheralGuard,
76};
77
78/// UART RX Error
79#[derive(Debug, Clone, Copy, PartialEq)]
80#[cfg_attr(feature = "defmt", derive(defmt::Format))]
81#[non_exhaustive]
82pub enum RxError {
83    /// An RX FIFO overflow happened.
84    ///
85    /// This error occurs when RX FIFO is full and a new byte is received. The
86    /// RX FIFO is then automatically reset by the driver.
87    FifoOverflowed,
88
89    /// A glitch was detected on the RX line.
90    ///
91    /// This error occurs when an unexpected or erroneous signal (glitch) is
92    /// detected on the UART RX line, which could lead to incorrect data
93    /// reception.
94    GlitchOccurred,
95
96    /// A framing error was detected on the RX line.
97    ///
98    /// This error occurs when the received data does not conform to the
99    /// expected UART frame format.
100    FrameFormatViolated,
101
102    /// A parity error was detected on the RX line.
103    ///
104    /// This error occurs when the parity bit in the received data does not
105    /// match the expected parity configuration.
106    ParityMismatch,
107}
108
109impl core::error::Error for RxError {}
110
111impl core::fmt::Display for RxError {
112    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
113        match self {
114            RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
115            RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
116            RxError::FrameFormatViolated => {
117                write!(f, "A framing error was detected on the RX line")
118            }
119            RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
120        }
121    }
122}
123
124#[instability::unstable]
125impl embedded_io_06::Error for RxError {
126    fn kind(&self) -> embedded_io_06::ErrorKind {
127        embedded_io_06::ErrorKind::Other
128    }
129}
130
131#[instability::unstable]
132impl embedded_io_07::Error for RxError {
133    fn kind(&self) -> embedded_io_07::ErrorKind {
134        embedded_io_07::ErrorKind::Other
135    }
136}
137
138/// UART TX Error
139#[derive(Debug, Clone, Copy, PartialEq)]
140#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141#[non_exhaustive]
142pub enum TxError {}
143
144impl core::fmt::Display for TxError {
145    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146        write!(f, "Tx error")
147    }
148}
149
150impl core::error::Error for TxError {}
151
152#[instability::unstable]
153impl embedded_io_06::Error for TxError {
154    fn kind(&self) -> embedded_io_06::ErrorKind {
155        embedded_io_06::ErrorKind::Other
156    }
157}
158#[instability::unstable]
159impl embedded_io_07::Error for TxError {
160    fn kind(&self) -> embedded_io_07::ErrorKind {
161        embedded_io_07::ErrorKind::Other
162    }
163}
164
165#[instability::unstable]
166pub use crate::soc::clocks::UartFunctionClockSclk as ClockSource;
167use crate::soc::clocks::{
168    UartBaudRateGeneratorConfig as BaudRateConfig,
169    UartFunctionClockConfig as ClockConfig,
170};
171
172/// Number of data bits
173///
174/// This enum represents the various configurations for the number of data
175/// bits used in UART communication. The number of data bits defines the
176/// length of each transmitted or received data frame.
177#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
178#[cfg_attr(feature = "defmt", derive(defmt::Format))]
179pub enum DataBits {
180    /// 5 data bits per frame.
181    _5,
182    /// 6 data bits per frame.
183    _6,
184    /// 7 data bits per frame.
185    _7,
186    /// 8 data bits per frame.
187    #[default]
188    _8,
189}
190
191/// Parity check
192///
193/// Parity is a form of error detection in UART communication, used to
194/// ensure that the data has not been corrupted during transmission. The
195/// parity bit is added to the data bits to make the number of 1-bits
196/// either even or odd.
197#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
198#[cfg_attr(feature = "defmt", derive(defmt::Format))]
199pub enum Parity {
200    /// No parity bit is used.
201    #[default]
202    None,
203    /// Even parity: the parity bit is set to make the total number of
204    /// 1-bits even.
205    Even,
206    /// Odd parity: the parity bit is set to make the total number of 1-bits
207    /// odd.
208    Odd,
209}
210
211/// Number of stop bits
212///
213/// The stop bit(s) signal the end of a data packet in UART communication.
214/// This enum defines the possible configurations for the number of stop
215/// bits.
216#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
217#[cfg_attr(feature = "defmt", derive(defmt::Format))]
218pub enum StopBits {
219    /// 1 stop bit.
220    #[default]
221    _1,
222    /// 1.5 stop bits.
223    _1p5,
224    /// 2 stop bits.
225    _2,
226}
227
228/// Software flow control settings.
229#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
230#[cfg_attr(feature = "defmt", derive(defmt::Format))]
231#[instability::unstable]
232pub enum SwFlowControl {
233    #[default]
234    /// Disables software flow control.
235    Disabled,
236    /// Enables software flow control with configured parameters
237    Enabled {
238        /// Xon flow control byte.
239        xon_char: u8,
240        /// Xoff flow control byte.
241        xoff_char: u8,
242        /// If the software flow control is enabled and the data amount in
243        /// rxfifo is less than xon_thrd, an xon_char will be sent.
244        xon_threshold: u8,
245        /// If the software flow control is enabled and the data amount in
246        /// rxfifo is more than xoff_thrd, an xoff_char will be sent
247        xoff_threshold: u8,
248    },
249}
250
251/// Configuration for CTS (Clear To Send) flow control.
252#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
253#[cfg_attr(feature = "defmt", derive(defmt::Format))]
254#[instability::unstable]
255pub enum CtsConfig {
256    /// Enable CTS flow control (TX).
257    Enabled,
258    #[default]
259    /// Disable CTS flow control (TX).
260    Disabled,
261}
262
263/// Configuration for RTS (Request To Send) flow control.
264#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
265#[cfg_attr(feature = "defmt", derive(defmt::Format))]
266#[instability::unstable]
267pub enum RtsConfig {
268    /// Enable RTS flow control with a FIFO threshold (RX).
269    Enabled(u8),
270    #[default]
271    /// Disable RTS flow control.
272    Disabled,
273}
274
275/// Hardware flow control configuration.
276#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
277#[cfg_attr(feature = "defmt", derive(defmt::Format))]
278#[instability::unstable]
279pub struct HwFlowControl {
280    /// CTS configuration.
281    pub cts: CtsConfig,
282    /// RTS configuration.
283    pub rts: RtsConfig,
284}
285
286/// Defines how strictly the requested baud rate must be met.
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
288#[cfg_attr(feature = "defmt", derive(defmt::Format))]
289#[instability::unstable]
290pub enum BaudrateTolerance {
291    /// Accept the closest achievable baud rate without restriction.
292    #[default]
293    Closest,
294    /// In this setting, the deviation of only 1% from the desired baud value is
295    /// tolerated.
296    Exact,
297    /// Allow a certain percentage of deviation.
298    ErrorPercent(u8),
299}
300
301/// UART Configuration
302#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
303#[cfg_attr(feature = "defmt", derive(defmt::Format))]
304#[non_exhaustive]
305pub struct Config {
306    /// The baud rate (speed) of the UART communication in bits per second
307    /// (bps).
308    baudrate: u32,
309    /// Determines how close to the desired baud rate value the driver should
310    /// set the baud rate.
311    #[builder_lite(unstable)]
312    baudrate_tolerance: BaudrateTolerance,
313    /// Number of data bits in each frame (5, 6, 7, or 8 bits).
314    data_bits: DataBits,
315    /// Parity setting (None, Even, or Odd).
316    parity: Parity,
317    /// Number of stop bits in each frame (1, 1.5, or 2 bits).
318    stop_bits: StopBits,
319    /// Software flow control.
320    #[builder_lite(unstable)]
321    sw_flow_ctrl: SwFlowControl,
322    /// Hardware flow control.
323    #[builder_lite(unstable)]
324    hw_flow_ctrl: HwFlowControl,
325    /// Clock source used by the UART peripheral.
326    #[builder_lite(unstable)]
327    clock_source: ClockSource,
328    /// UART Receive part configuration.
329    rx: RxConfig,
330    /// UART Transmit part configuration.
331    tx: TxConfig,
332}
333
334impl Default for Config {
335    fn default() -> Config {
336        Config {
337            rx: RxConfig::default(),
338            tx: TxConfig::default(),
339            baudrate: 115_200,
340            baudrate_tolerance: BaudrateTolerance::default(),
341            data_bits: Default::default(),
342            parity: Default::default(),
343            stop_bits: Default::default(),
344            sw_flow_ctrl: Default::default(),
345            hw_flow_ctrl: Default::default(),
346            clock_source: Default::default(),
347        }
348    }
349}
350
351impl Config {
352    fn validate(&self) -> Result<(), ConfigError> {
353        if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
354            assert!(percentage > 0 && percentage <= 100);
355        }
356
357        // Max supported baud rate is 5Mbaud
358        if self.baudrate == 0 || self.baudrate > 5_000_000 {
359            return Err(ConfigError::BaudrateNotSupported);
360        }
361        Ok(())
362    }
363}
364
365/// UART Receive part configuration.
366#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
367#[cfg_attr(feature = "defmt", derive(defmt::Format))]
368#[non_exhaustive]
369pub struct RxConfig {
370    /// Threshold level at which the RX FIFO is considered full.
371    fifo_full_threshold: u16,
372    /// Optional timeout value for RX operations.
373    timeout: Option<u8>,
374}
375
376impl Default for RxConfig {
377    fn default() -> RxConfig {
378        RxConfig {
379            // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L61>
380            fifo_full_threshold: 120,
381            // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L63>
382            timeout: Some(10),
383        }
384    }
385}
386
387/// UART Transmit part configuration.
388#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
389#[cfg_attr(feature = "defmt", derive(defmt::Format))]
390#[non_exhaustive]
391pub struct TxConfig {
392    /// Threshold level at which the TX FIFO is considered empty.
393    fifo_empty_threshold: u16,
394}
395
396impl Default for TxConfig {
397    fn default() -> TxConfig {
398        TxConfig {
399            // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L59>
400            fifo_empty_threshold: 10,
401        }
402    }
403}
404
405/// Configuration for the AT-CMD detection functionality
406#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
407#[cfg_attr(feature = "defmt", derive(defmt::Format))]
408#[instability::unstable]
409#[non_exhaustive]
410pub struct AtCmdConfig {
411    /// Optional idle time before the AT command detection begins, in clock
412    /// cycles.
413    pre_idle_count: Option<u16>,
414    /// Optional idle time after the AT command detection ends, in clock
415    /// cycles.
416    post_idle_count: Option<u16>,
417    /// Optional timeout between bytes in the AT command, in clock
418    /// cycles.
419    gap_timeout: Option<u16>,
420    /// The byte (character) that triggers the AT command detection.
421    cmd_char: u8,
422    /// Optional number of bytes to detect as part of the AT command.
423    char_num: u8,
424}
425
426impl Default for AtCmdConfig {
427    fn default() -> Self {
428        Self {
429            pre_idle_count: None,
430            post_idle_count: None,
431            gap_timeout: None,
432            cmd_char: b'+',
433            char_num: 1,
434        }
435    }
436}
437
438struct UartBuilder<'d, Dm: DriverMode> {
439    uart: AnyUart<'d>,
440    phantom: PhantomData<Dm>,
441}
442
443impl<'d, Dm> UartBuilder<'d, Dm>
444where
445    Dm: DriverMode,
446{
447    fn new(uart: impl Instance + 'd) -> Self {
448        let uart = uart.degrade();
449
450        // Make sure inputs are well-defined.
451        // Connect RX to an idle high level.
452        uart.info().rx_signal.connect_to(&crate::gpio::Level::High);
453        uart.info().cts_signal.connect_to(&crate::gpio::Level::Low);
454
455        Self {
456            uart,
457            phantom: PhantomData,
458        }
459    }
460
461    fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
462        let rx_guard = PeripheralGuard::new(self.uart.info().peripheral);
463        let tx_guard = PeripheralGuard::new(self.uart.info().peripheral);
464
465        let peri_clock_guard = UartClockGuard::new(unsafe { self.uart.clone_unchecked() });
466
467        let rts_pin = PinGuard::new_unconnected();
468        let tx_pin = PinGuard::new_unconnected();
469
470        let mut serial = Uart {
471            rx: UartRx {
472                uart: unsafe { self.uart.clone_unchecked() },
473                phantom: PhantomData,
474                guard: rx_guard,
475                peri_clock_guard: peri_clock_guard.clone(),
476            },
477            tx: UartTx {
478                uart: self.uart,
479                phantom: PhantomData,
480                guard: tx_guard,
481                peri_clock_guard,
482                rts_pin,
483                tx_pin,
484                baudrate: config.baudrate,
485            },
486        };
487        serial.init(config)?;
488
489        Ok(serial)
490    }
491}
492
493#[procmacros::doc_replace]
494/// UART (Full-duplex)
495///
496/// ## Example
497///
498/// ```rust, no_run
499/// # {before_snippet}
500/// use esp_hal::uart::{Config, Uart};
501/// let mut uart = Uart::new(peripherals.UART0, Config::default())?
502///     .with_rx(peripherals.GPIO1)
503///     .with_tx(peripherals.GPIO2);
504///
505/// uart.write(b"Hello world!")?;
506/// # {after_snippet}
507/// ```
508pub struct Uart<'d, Dm: DriverMode> {
509    rx: UartRx<'d, Dm>,
510    tx: UartTx<'d, Dm>,
511}
512
513/// UART (Transmit)
514#[instability::unstable]
515pub struct UartTx<'d, Dm: DriverMode> {
516    uart: AnyUart<'d>,
517    phantom: PhantomData<Dm>,
518    guard: PeripheralGuard,
519    peri_clock_guard: UartClockGuard<'d>,
520    rts_pin: PinGuard,
521    tx_pin: PinGuard,
522    baudrate: u32,
523}
524
525/// UART (Receive)
526#[instability::unstable]
527pub struct UartRx<'d, Dm: DriverMode> {
528    uart: AnyUart<'d>,
529    phantom: PhantomData<Dm>,
530    guard: PeripheralGuard,
531    peri_clock_guard: UartClockGuard<'d>,
532}
533
534/// A configuration error.
535#[derive(Debug, Clone, Copy, PartialEq, Eq)]
536#[cfg_attr(feature = "defmt", derive(defmt::Format))]
537#[non_exhaustive]
538pub enum ConfigError {
539    /// The requested baud rate is not achievable.
540    #[cfg(feature = "unstable")]
541    #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
542    BaudrateNotAchievable,
543
544    /// The requested baud rate is not supported.
545    ///
546    /// This error is returned if:
547    ///  * the baud rate exceeds 5MBaud or is equal to zero.
548    ///  * the user has specified an exact baud rate or with some percentage of deviation to the
549    ///    desired value, and the driver cannot reach this speed.
550    BaudrateNotSupported,
551
552    /// The requested timeout exceeds the maximum value (
553    #[cfg_attr(esp32, doc = "127")]
554    #[cfg_attr(not(esp32), doc = "1023")]
555    /// ).
556    TimeoutTooLong,
557
558    /// The requested RX FIFO threshold exceeds the maximum value (127 bytes).
559    RxFifoThresholdNotSupported,
560
561    /// The requested TX FIFO threshold exceeds the maximum value (127 bytes).
562    TxFifoThresholdNotSupported,
563}
564
565impl core::error::Error for ConfigError {}
566
567impl core::fmt::Display for ConfigError {
568    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
569        match self {
570            #[cfg(feature = "unstable")]
571            ConfigError::BaudrateNotAchievable => {
572                write!(f, "The requested baud rate is not achievable")
573            }
574            ConfigError::BaudrateNotSupported => {
575                write!(f, "The requested baud rate is not supported")
576            }
577            ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
578            ConfigError::RxFifoThresholdNotSupported => {
579                write!(f, "The requested RX FIFO threshold is not supported")
580            }
581            ConfigError::TxFifoThresholdNotSupported => {
582                write!(f, "The requested TX FIFO threshold is not supported")
583            }
584        }
585    }
586}
587
588#[instability::unstable]
589impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
590where
591    Dm: DriverMode,
592{
593    type Config = Config;
594    type ConfigError = ConfigError;
595
596    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
597        self.apply_config(config)
598    }
599}
600
601#[instability::unstable]
602impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
603where
604    Dm: DriverMode,
605{
606    type Config = Config;
607    type ConfigError = ConfigError;
608
609    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
610        self.apply_config(config)
611    }
612}
613
614#[instability::unstable]
615impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
616where
617    Dm: DriverMode,
618{
619    type Config = Config;
620    type ConfigError = ConfigError;
621
622    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
623        self.baudrate = config.baudrate;
624        self.apply_config(config)
625    }
626}
627
628impl<'d> UartTx<'d, Blocking> {
629    #[procmacros::doc_replace]
630    /// Create a new UART TX instance in [`Blocking`] mode.
631    ///
632    /// ## Errors
633    ///
634    /// This function returns a [`ConfigError`] if the configuration is not
635    /// supported by the hardware.
636    ///
637    /// ## Example
638    ///
639    /// ```rust, no_run
640    /// # {before_snippet}
641    /// use esp_hal::uart::{Config, UartTx};
642    /// let tx = UartTx::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO1);
643    /// # {after_snippet}
644    /// ```
645    #[instability::unstable]
646    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
647        let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
648
649        Ok(uart_tx)
650    }
651
652    /// Reconfigures the driver to operate in [`Async`] mode.
653    #[instability::unstable]
654    pub fn into_async(self) -> UartTx<'d, Async> {
655        if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
656            self.uart
657                .set_interrupt_handler(self.uart.info().async_handler);
658        }
659        self.uart.state().is_tx_async.store(true, Ordering::Release);
660
661        UartTx {
662            uart: self.uart,
663            phantom: PhantomData,
664            guard: self.guard,
665            peri_clock_guard: self.peri_clock_guard,
666            rts_pin: self.rts_pin,
667            tx_pin: self.tx_pin,
668            baudrate: self.baudrate,
669        }
670    }
671}
672
673impl<'d> UartTx<'d, Async> {
674    /// Reconfigures the driver to operate in [`Blocking`] mode.
675    #[instability::unstable]
676    pub fn into_blocking(self) -> UartTx<'d, Blocking> {
677        self.uart
678            .state()
679            .is_tx_async
680            .store(false, Ordering::Release);
681        if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
682            self.uart.disable_peri_interrupt_on_all_cores();
683        }
684
685        UartTx {
686            uart: self.uart,
687            phantom: PhantomData,
688            guard: self.guard,
689            peri_clock_guard: self.peri_clock_guard,
690            rts_pin: self.rts_pin,
691            tx_pin: self.tx_pin,
692            baudrate: self.baudrate,
693        }
694    }
695
696    /// Write data into the TX buffer.
697    ///
698    /// This function writes the provided buffer `bytes` into the UART transmit
699    /// buffer. If the buffer is full, the function waits asynchronously for
700    /// space in the buffer to become available.
701    ///
702    /// The function returns the number of bytes written into the buffer. This
703    /// may be less than the length of the buffer.
704    ///
705    /// Upon an error, the function returns immediately and the contents of the
706    /// internal FIFO are not modified.
707    ///
708    /// ## Cancellation
709    ///
710    /// This function is cancellation safe.
711    pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
712        // We need to loop in case the TX empty interrupt was fired but not cleared
713        // before, but the FIFO itself was filled up by a previous write.
714        let space = loop {
715            let tx_fifo_count = self.uart.info().tx_fifo_count();
716            let space = Info::UART_FIFO_SIZE - tx_fifo_count;
717            if space != 0 {
718                break space;
719            }
720            UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
721        };
722
723        let free = (space as usize).min(bytes.len());
724
725        for &byte in &bytes[..free] {
726            self.uart
727                .info()
728                .regs()
729                .fifo()
730                .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
731        }
732
733        Ok(free)
734    }
735
736    /// Asynchronously flushes the UART transmit buffer.
737    ///
738    /// This function ensures that all pending data in the transmit FIFO has
739    /// been sent over the UART. If the FIFO contains data, it waits for the
740    /// transmission to complete before returning.
741    ///
742    /// ## Cancellation
743    ///
744    /// This function is cancellation safe.
745    pub async fn flush_async(&mut self) -> Result<(), TxError> {
746        // Nothing is guaranteed to clear the Done status, so let's loop here in case Tx
747        // was Done before the last write operation that pushed data into the
748        // FIFO.
749        while self.uart.info().tx_fifo_count() > 0 {
750            UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
751        }
752
753        self.flush_last_byte();
754
755        Ok(())
756    }
757}
758
759impl<'d, Dm> UartTx<'d, Dm>
760where
761    Dm: DriverMode,
762{
763    /// Configure RTS pin
764    #[instability::unstable]
765    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
766        let rts = rts.into();
767
768        rts.apply_output_config(&OutputConfig::default());
769        rts.set_output_enable(true);
770
771        self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
772
773        self
774    }
775
776    /// Assign the TX pin for UART instance.
777    ///
778    /// Sets the specified pin to push-pull output and connects it to the UART
779    /// TX signal.
780    ///
781    /// Disconnects the previous pin that was assigned with `with_tx`.
782    #[instability::unstable]
783    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
784        let tx = tx.into();
785
786        // Make sure we don't cause an unexpected low pulse on the pin.
787        tx.set_output_high(true);
788        tx.apply_output_config(&OutputConfig::default());
789        tx.set_output_enable(true);
790
791        self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
792
793        self
794    }
795
796    /// Change the configuration.
797    ///
798    /// ## Errors
799    ///
800    /// This function returns a [`ConfigError`] if the configuration is not
801    /// supported by the hardware.
802    #[instability::unstable]
803    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
804        self.uart
805            .info()
806            .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
807        self.uart.info().txfifo_reset();
808        Ok(())
809    }
810
811    /// Returns whether the UART buffer is ready to accept more data.
812    ///
813    /// If this function returns `true`, [`Self::write`] will not block.
814    #[instability::unstable]
815    pub fn write_ready(&self) -> bool {
816        self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
817    }
818
819    /// Write bytes.
820    ///
821    /// This function writes data to the internal TX FIFO of the UART
822    /// peripheral. The data is then transmitted over the UART TX line.
823    ///
824    /// The function returns the number of bytes written to the FIFO. This may
825    /// be less than the length of the provided data. The function may only
826    /// return 0 if the provided data is empty.
827    ///
828    /// ## Errors
829    ///
830    /// This function returns a [`TxError`] if an error occurred during the
831    /// write operation.
832    #[instability::unstable]
833    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
834        self.uart.info().write(data)
835    }
836
837    fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
838        while !data.is_empty() {
839            let bytes_written = self.write(data)?;
840            data = &data[bytes_written..];
841        }
842        Ok(())
843    }
844
845    /// Flush the transmit buffer.
846    ///
847    /// This function blocks until all data in the TX FIFO has been
848    /// transmitted.
849    #[instability::unstable]
850    pub fn flush(&mut self) -> Result<(), TxError> {
851        while self.uart.info().tx_fifo_count() > 0 {}
852        self.flush_last_byte();
853        Ok(())
854    }
855
856    fn flush_last_byte(&mut self) {
857        // This function handles an edge case that happens when the TX FIFO count
858        // changes to 0. The FSM is in the Idle state for a short while after
859        // the last byte is moved out of the FIFO. It is unclear how long this
860        // takes, but 10us seems to be a good enough duration to wait, for both
861        // fast and slow baud rates.
862        crate::rom::ets_delay_us(10);
863        while !self.is_tx_idle() {}
864    }
865
866    /// Sends a break signal for a specified duration in bit time.
867    ///
868    /// Duration is in bits, the time it takes to transfer one bit at the
869    /// current baud rate. The delay during the break is just busy-waiting.
870    #[instability::unstable]
871    pub fn send_break(&mut self, bits: u32) {
872        // Read the current TX inversion state
873        let original_conf0 = self.uart.info().regs().conf0().read();
874        let original_txd_inv = original_conf0.txd_inv().bit();
875
876        // Invert the TX line (toggle the current state)
877        self.uart
878            .info()
879            .regs()
880            .conf0()
881            .modify(|_, w| w.txd_inv().bit(!original_txd_inv));
882
883        sync_regs(self.uart.info().regs());
884
885        // Calculate total delay in microseconds: (bits * 1_000_000) / baudrate_bps
886        // Use u64 to avoid overflow, then convert back to u32
887        let total_delay_us = (bits as u64 * 1_000_000) / self.baudrate as u64;
888        let delay_us = (total_delay_us as u32).max(1);
889
890        crate::rom::ets_delay_us(delay_us);
891
892        // Restore the original register state
893        self.uart
894            .info()
895            .regs()
896            .conf0()
897            .write(|w| unsafe { w.bits(original_conf0.bits()) });
898
899        sync_regs(self.uart.info().regs());
900    }
901
902    /// Checks if the TX line is idle for this UART instance.
903    ///
904    /// Returns `true` if the transmit line is idle, meaning no data is
905    /// currently being transmitted.
906    fn is_tx_idle(&self) -> bool {
907        #[cfg(esp32)]
908        let status = self.regs().status();
909        #[cfg(not(esp32))]
910        let status = self.regs().fsm_status();
911
912        status.read().st_utx_out().bits() == 0x0
913    }
914
915    /// Disables all TX-related interrupts for this UART instance.
916    ///
917    /// This function clears and disables the `transmit FIFO empty` interrupt,
918    /// `transmit break done`, `transmit break idle done`, and `transmit done`
919    /// interrupts.
920    fn disable_tx_interrupts(&self) {
921        self.regs().int_clr().write(|w| {
922            w.txfifo_empty().clear_bit_by_one();
923            w.tx_brk_done().clear_bit_by_one();
924            w.tx_brk_idle_done().clear_bit_by_one();
925            w.tx_done().clear_bit_by_one()
926        });
927
928        self.regs().int_ena().write(|w| {
929            w.txfifo_empty().clear_bit();
930            w.tx_brk_done().clear_bit();
931            w.tx_brk_idle_done().clear_bit();
932            w.tx_done().clear_bit()
933        });
934    }
935
936    fn regs(&self) -> &RegisterBlock {
937        self.uart.info().regs()
938    }
939}
940
941#[inline(always)]
942fn sync_regs(_register_block: &RegisterBlock) {
943    #[cfg(not(any(esp32, esp32s2)))]
944    {
945        cfg_if::cfg_if! {
946            if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
947                let update_reg = _register_block.id();
948            } else {
949                let update_reg = _register_block.reg_update();
950            }
951        }
952
953        update_reg.modify(|_, w| w.reg_update().set_bit());
954
955        while update_reg.read().reg_update().bit_is_set() {
956            core::hint::spin_loop();
957        }
958    }
959}
960
961impl<'d> UartRx<'d, Blocking> {
962    #[procmacros::doc_replace]
963    /// Create a new UART RX instance in [`Blocking`] mode.
964    ///
965    /// ## Errors
966    ///
967    /// This function returns a [`ConfigError`] if the configuration is not
968    /// supported by the hardware.
969    ///
970    /// ```rust, no_run
971    /// # {before_snippet}
972    /// use esp_hal::uart::{Config, UartRx};
973    /// let rx = UartRx::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO2);
974    /// # {after_snippet}
975    /// ```
976    #[instability::unstable]
977    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
978        let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
979
980        Ok(uart_rx)
981    }
982
983    /// Waits for a break condition to be detected.
984    ///
985    /// This is a blocking function that will continuously check for a break condition.
986    /// After detection, the break interrupt flag is automatically cleared.
987    #[instability::unstable]
988    pub fn wait_for_break(&mut self) {
989        self.enable_break_detection();
990
991        while !self.regs().int_raw().read().brk_det().bit_is_set() {
992            // wait
993        }
994
995        self.regs()
996            .int_clr()
997            .write(|w| w.brk_det().clear_bit_by_one());
998    }
999
1000    /// Waits for a break condition to be detected with a timeout.
1001    ///
1002    /// This is a blocking function that will check for a break condition up to
1003    /// the specified timeout. Returns `true` if a break was detected, `false` if
1004    /// the timeout elapsed. After successful detection, the break interrupt flag
1005    /// is automatically cleared.
1006    ///
1007    /// ## Arguments
1008    /// * `timeout` - Maximum time to wait for a break condition
1009    #[instability::unstable]
1010    pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1011        self.enable_break_detection();
1012
1013        let start = crate::time::Instant::now();
1014
1015        while !self.regs().int_raw().read().brk_det().bit_is_set() {
1016            if crate::time::Instant::now() - start >= timeout {
1017                return false;
1018            }
1019        }
1020
1021        self.regs()
1022            .int_clr()
1023            .write(|w| w.brk_det().clear_bit_by_one());
1024        true
1025    }
1026
1027    /// Reconfigures the driver to operate in [`Async`] mode.
1028    #[instability::unstable]
1029    pub fn into_async(self) -> UartRx<'d, Async> {
1030        if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1031            self.uart
1032                .set_interrupt_handler(self.uart.info().async_handler);
1033        }
1034        self.uart.state().is_rx_async.store(true, Ordering::Release);
1035
1036        UartRx {
1037            uart: self.uart,
1038            phantom: PhantomData,
1039            guard: self.guard,
1040            peri_clock_guard: self.peri_clock_guard,
1041        }
1042    }
1043}
1044
1045impl<'d> UartRx<'d, Async> {
1046    /// Reconfigures the driver to operate in [`Blocking`] mode.
1047    #[instability::unstable]
1048    pub fn into_blocking(self) -> UartRx<'d, Blocking> {
1049        self.uart
1050            .state()
1051            .is_rx_async
1052            .store(false, Ordering::Release);
1053        if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1054            self.uart.disable_peri_interrupt_on_all_cores();
1055        }
1056
1057        UartRx {
1058            uart: self.uart,
1059            phantom: PhantomData,
1060            guard: self.guard,
1061            peri_clock_guard: self.peri_clock_guard,
1062        }
1063    }
1064
1065    async fn wait_for_buffered_data(
1066        &mut self,
1067        minimum: usize,
1068        max_threshold: usize,
1069        listen_for_timeout: bool,
1070    ) -> Result<(), RxError> {
1071        let current_threshold = self.uart.info().rx_fifo_full_threshold();
1072
1073        // User preference takes priority.
1074        let max_threshold = max_threshold.min(current_threshold as usize) as u16;
1075        let minimum = minimum.min(Info::RX_FIFO_MAX_THRHD as usize) as u16;
1076
1077        // The effective threshold must be >= minimum. We ensure this by lowering the minimum number
1078        // of returnable bytes.
1079        let minimum = minimum.min(max_threshold);
1080
1081        if self.uart.info().rx_fifo_count() < minimum {
1082            // We're ignoring the user configuration here to ensure that this is not waiting
1083            // for more data than the buffer. We'll restore the original value after the
1084            // future resolved.
1085            let info = self.uart.info();
1086            unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
1087            let _guard = DropGuard::new((), |_| {
1088                unwrap!(info.set_rx_fifo_full_threshold(current_threshold));
1089            });
1090
1091            // Wait for space or event
1092            let mut events = RxEvent::FifoFull
1093                | RxEvent::FifoOvf
1094                | RxEvent::FrameError
1095                | RxEvent::GlitchDetected
1096                | RxEvent::ParityError;
1097
1098            if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1099                events |= RxEvent::CmdCharDetected;
1100            }
1101
1102            cfg_if::cfg_if! {
1103                if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
1104                    let reg_en = self.regs().tout_conf();
1105                } else {
1106                    let reg_en = self.regs().conf1();
1107                }
1108            };
1109            if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1110                events |= RxEvent::FifoTout;
1111            }
1112
1113            let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1114
1115            let result = rx_event_check_for_error(events);
1116            if let Err(error) = result {
1117                if error == RxError::FifoOverflowed {
1118                    self.uart.info().rxfifo_reset();
1119                }
1120                return Err(error);
1121            }
1122        }
1123
1124        Ok(())
1125    }
1126
1127    /// Read data asynchronously.
1128    ///
1129    /// This function reads data from the UART receive buffer into the
1130    /// provided buffer. If the buffer is empty, the function waits
1131    /// asynchronously for data to become available, or for an error to occur.
1132    ///
1133    /// The function returns the number of bytes read into the buffer. This may
1134    /// be less than the length of the buffer.
1135    ///
1136    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1137    /// to ensure that it does not wait for more data than the buffer can hold.
1138    ///
1139    /// Upon an error, the function returns immediately and the contents of the
1140    /// internal FIFO are not modified.
1141    ///
1142    /// ## Cancellation
1143    ///
1144    /// This function is cancellation safe.
1145    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1146        if buf.is_empty() {
1147            return Ok(0);
1148        }
1149
1150        self.wait_for_buffered_data(1, buf.len(), true).await?;
1151
1152        self.read_buffered(buf)
1153    }
1154
1155    /// Fill buffer asynchronously.
1156    ///
1157    /// This function reads data into the provided buffer. If the internal FIFO
1158    /// does not contain enough data, the function waits asynchronously for data
1159    /// to become available, or for an error to occur.
1160    ///
1161    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1162    /// to ensure that it does not wait for more data than the buffer can hold.
1163    ///
1164    /// ## Cancellation
1165    ///
1166    /// This function is **not** cancellation safe. If the future is dropped
1167    /// before it resolves, or if an error occurs during the read operation,
1168    /// previously read data may be lost.
1169    pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1170        if buf.is_empty() {
1171            return Ok(());
1172        }
1173
1174        // Drain the buffer first, there's no point in waiting for data we've already received.
1175        let read = self.uart.info().read_buffered(buf)?;
1176        buf = &mut buf[read..];
1177
1178        while !buf.is_empty() {
1179            // No point in listening for timeouts, as we're waiting for an exact amount of
1180            // data. On ESP32 and S2, the timeout interrupt can't be cleared unless the FIFO
1181            // is empty, so listening could cause an infinite loop here.
1182            self.wait_for_buffered_data(buf.len(), buf.len(), false)
1183                .await?;
1184
1185            let read = self.uart.info().read_buffered(buf)?;
1186            buf = &mut buf[read..];
1187        }
1188
1189        Ok(())
1190    }
1191
1192    /// Waits for a break condition to be detected asynchronously.
1193    ///
1194    /// This is an async function that will await until a break condition is
1195    /// detected on the RX line. After detection, the break interrupt flag is
1196    /// automatically cleared.
1197    #[instability::unstable]
1198    pub async fn wait_for_break_async(&mut self) {
1199        UartRxFuture::new(self.uart.reborrow(), RxEvent::BreakDetected).await;
1200        self.regs()
1201            .int_clr()
1202            .write(|w| w.brk_det().clear_bit_by_one());
1203    }
1204}
1205
1206impl<'d, Dm> UartRx<'d, Dm>
1207where
1208    Dm: DriverMode,
1209{
1210    fn regs(&self) -> &RegisterBlock {
1211        self.uart.info().regs()
1212    }
1213
1214    /// Assign the CTS pin for UART instance.
1215    ///
1216    /// Sets the specified pin to input and connects it to the UART CTS signal.
1217    #[instability::unstable]
1218    pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1219        let cts = cts.into();
1220
1221        cts.apply_input_config(&InputConfig::default());
1222        cts.set_input_enable(true);
1223
1224        self.uart.info().cts_signal.connect_to(&cts);
1225
1226        self
1227    }
1228
1229    /// Assign the RX pin for UART instance.
1230    ///
1231    /// Sets the specified pin to input and connects it to the UART RX signal.
1232    ///
1233    /// Note: when you listen for the output of the UART peripheral, you should
1234    /// configure the driver side (i.e. the TX pin), or ensure that the line is
1235    /// initially high, to avoid receiving a non-data byte caused by an
1236    /// initial low signal level.
1237    #[instability::unstable]
1238    pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1239        let rx = rx.into();
1240
1241        rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1242        rx.set_input_enable(true);
1243
1244        self.uart.info().rx_signal.connect_to(&rx);
1245
1246        self
1247    }
1248
1249    /// Enable break detection.
1250    ///
1251    /// This must be called before any breaks are expected to be received.
1252    /// Break detection is enabled automatically by [`Self::wait_for_break`]
1253    /// and [`Self::wait_for_break_with_timeout`], but calling this method
1254    /// explicitly ensures that breaks occurring before the first wait call
1255    /// will be reliably detected.
1256    #[instability::unstable]
1257    pub fn enable_break_detection(&mut self) {
1258        self.uart
1259            .info()
1260            .enable_listen_rx(RxEvent::BreakDetected.into(), true);
1261
1262        sync_regs(self.regs());
1263    }
1264
1265    /// Change the configuration.
1266    ///
1267    /// ## Errors
1268    ///
1269    /// This function returns a [`ConfigError`] if the configuration is not
1270    /// supported by the hardware.
1271    #[instability::unstable]
1272    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1273        self.uart
1274            .info()
1275            .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1276        self.uart
1277            .info()
1278            .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1279
1280        self.uart.info().rxfifo_reset();
1281        Ok(())
1282    }
1283
1284    /// Reads and clears errors set by received data.
1285    ///
1286    /// If a FIFO overflow is detected, the RX FIFO is reset.
1287    #[instability::unstable]
1288    pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1289        self.uart.info().check_for_errors()
1290    }
1291
1292    /// Returns whether the UART buffer has data.
1293    ///
1294    /// If this function returns `true`, [`Self::read`] will not block.
1295    #[instability::unstable]
1296    pub fn read_ready(&self) -> bool {
1297        self.uart.info().rx_fifo_count() > 0
1298    }
1299
1300    /// Read bytes.
1301    ///
1302    /// The UART hardware continuously receives bytes and stores them in the RX
1303    /// FIFO. This function reads the bytes from the RX FIFO and returns
1304    /// them in the provided buffer. If the hardware buffer is empty, this
1305    /// function will block until data is available. The [`Self::read_ready`]
1306    /// function can be used to check if data is available without blocking.
1307    ///
1308    /// The function returns the number of bytes read into the buffer. This may
1309    /// be less than the length of the buffer. This function only returns 0
1310    /// if the provided buffer is empty.
1311    ///
1312    /// ## Errors
1313    ///
1314    /// This function returns an [`RxError`] if an error occurred since the last
1315    /// call to [`Self::check_for_errors`], [`Self::read_buffered`], or this
1316    /// function.
1317    ///
1318    /// If the error occurred before this function was called, the contents of
1319    /// the FIFO are not modified.
1320    #[instability::unstable]
1321    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1322        self.uart.info().read(buf)
1323    }
1324
1325    /// Read already received bytes.
1326    ///
1327    /// This function reads the already received bytes from the FIFO into the
1328    /// provided buffer. The function does not wait for the FIFO to actually
1329    /// contain any bytes.
1330    ///
1331    /// The function returns the number of bytes read into the buffer. This may
1332    /// be less than the length of the buffer, and it may also be 0.
1333    ///
1334    /// ## Errors
1335    ///
1336    /// This function returns an [`RxError`] if an error occurred since the last
1337    /// call to [`Self::check_for_errors`], [`Self::read`], or this
1338    /// function.
1339    ///
1340    /// If the error occurred before this function was called, the contents of
1341    /// the FIFO are not modified.
1342    #[instability::unstable]
1343    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1344        self.uart.info().read_buffered(buf)
1345    }
1346
1347    /// Disables all RX-related interrupts for this UART instance.
1348    ///
1349    /// This function clears and disables the `receive FIFO full` interrupt,
1350    /// `receive FIFO overflow`, `receive FIFO timeout`, and `AT command
1351    /// byte detection` interrupts.
1352    fn disable_rx_interrupts(&self) {
1353        self.regs().int_clr().write(|w| {
1354            w.rxfifo_full().clear_bit_by_one();
1355            w.rxfifo_ovf().clear_bit_by_one();
1356            w.rxfifo_tout().clear_bit_by_one();
1357            w.at_cmd_char_det().clear_bit_by_one()
1358        });
1359
1360        self.regs().int_ena().write(|w| {
1361            w.rxfifo_full().clear_bit();
1362            w.rxfifo_ovf().clear_bit();
1363            w.rxfifo_tout().clear_bit();
1364            w.at_cmd_char_det().clear_bit()
1365        });
1366    }
1367}
1368
1369impl<'d> Uart<'d, Blocking> {
1370    #[procmacros::doc_replace]
1371    /// Create a new UART instance in [`Blocking`] mode.
1372    ///
1373    /// ## Errors
1374    ///
1375    /// This function returns a [`ConfigError`] if the configuration is not
1376    /// supported by the hardware.
1377    ///
1378    /// ## Example
1379    ///
1380    /// ```rust, no_run
1381    /// # {before_snippet}
1382    /// use esp_hal::uart::{Config, Uart};
1383    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1384    ///     .with_rx(peripherals.GPIO1)
1385    ///     .with_tx(peripherals.GPIO2);
1386    /// # {after_snippet}
1387    /// ```
1388    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1389        UartBuilder::new(uart).init(config)
1390    }
1391
1392    /// Reconfigures the driver to operate in [`Async`] mode.
1393    ///
1394    /// See the [`Async`] documentation for an example on how to use this
1395    /// method.
1396    pub fn into_async(self) -> Uart<'d, Async> {
1397        Uart {
1398            rx: self.rx.into_async(),
1399            tx: self.tx.into_async(),
1400        }
1401    }
1402
1403    #[cfg_attr(
1404        not(multi_core),
1405        doc = "Registers an interrupt handler for the peripheral."
1406    )]
1407    #[cfg_attr(
1408        multi_core,
1409        doc = "Registers an interrupt handler for the peripheral on the current core."
1410    )]
1411    #[doc = ""]
1412    /// Note that this will replace any previously registered interrupt
1413    /// handlers.
1414    ///
1415    /// You can restore the default/unhandled interrupt handler by using
1416    /// [crate::interrupt::DEFAULT_INTERRUPT_HANDLER]
1417    #[instability::unstable]
1418    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1419        // `self.tx.uart` and `self.rx.uart` are the same
1420        self.tx.uart.set_interrupt_handler(handler);
1421    }
1422
1423    #[procmacros::doc_replace]
1424    /// Listen for the given interrupts
1425    ///
1426    /// ## Example
1427    ///
1428    /// **Note**: In practice a proper serial terminal should be used
1429    /// to connect to the board (espflash won't work)
1430    ///
1431    /// ```rust, no_run
1432    /// # {before_snippet}
1433    /// use esp_hal::{
1434    ///     delay::Delay,
1435    ///     uart::{AtCmdConfig, Config, RxConfig, Uart, UartInterrupt},
1436    /// };
1437    /// # let delay = Delay::new();
1438    /// # let config = Config::default().with_rx(
1439    /// #    RxConfig::default().with_fifo_full_threshold(30)
1440    /// # );
1441    /// # let mut uart = Uart::new(
1442    /// #    peripherals.UART0,
1443    /// #    config)?;
1444    /// uart.set_interrupt_handler(interrupt_handler);
1445    ///
1446    /// critical_section::with(|cs| {
1447    ///     uart.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
1448    ///     uart.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1449    ///
1450    ///     SERIAL.borrow_ref_mut(cs).replace(uart);
1451    /// });
1452    ///
1453    /// loop {
1454    ///     println!("Send `#` character or >=30 characters");
1455    ///     delay.delay(Duration::from_secs(1));
1456    /// }
1457    /// # }
1458    ///
1459    /// use core::cell::RefCell;
1460    ///
1461    /// use critical_section::Mutex;
1462    /// use esp_hal::uart::Uart;
1463    /// static SERIAL: Mutex<RefCell<Option<Uart<esp_hal::Blocking>>>> = Mutex::new(RefCell::new(None));
1464    ///
1465    /// use core::fmt::Write;
1466    ///
1467    /// use esp_hal::uart::UartInterrupt;
1468    /// #[esp_hal::handler]
1469    /// fn interrupt_handler() {
1470    ///     critical_section::with(|cs| {
1471    ///         let mut serial = SERIAL.borrow_ref_mut(cs);
1472    ///         if let Some(serial) = serial.as_mut() {
1473    ///             let mut buf = [0u8; 64];
1474    ///             if let Ok(cnt) = serial.read_buffered(&mut buf) {
1475    ///                 println!("Read {} bytes", cnt);
1476    ///             }
1477    ///
1478    ///             let pending_interrupts = serial.interrupts();
1479    ///             println!(
1480    ///                 "Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
1481    ///                 pending_interrupts.contains(UartInterrupt::AtCmd),
1482    ///                 pending_interrupts.contains(UartInterrupt::RxFifoFull),
1483    ///             );
1484    ///
1485    ///             serial.clear_interrupts(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1486    ///         }
1487    ///     });
1488    /// }
1489    /// ```
1490    #[instability::unstable]
1491    pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1492        self.tx.uart.info().enable_listen(interrupts.into(), true)
1493    }
1494
1495    /// Unlisten the given interrupts
1496    #[instability::unstable]
1497    pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1498        self.tx.uart.info().enable_listen(interrupts.into(), false)
1499    }
1500
1501    /// Gets asserted interrupts
1502    #[instability::unstable]
1503    pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1504        self.tx.uart.info().interrupts()
1505    }
1506
1507    /// Resets asserted interrupts
1508    #[instability::unstable]
1509    pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1510        self.tx.uart.info().clear_interrupts(interrupts)
1511    }
1512
1513    /// Waits for a break condition to be detected.
1514    ///
1515    /// This is a blocking function that will continuously check for a break condition.
1516    /// After detection, the break interrupt flag is automatically cleared.
1517    #[instability::unstable]
1518    pub fn wait_for_break(&mut self) {
1519        self.rx.wait_for_break()
1520    }
1521
1522    /// Waits for a break condition to be detected with a timeout.
1523    ///
1524    /// This is a blocking function that will check for a break condition up to
1525    /// the specified timeout. Returns `true` if a break was detected, `false` if
1526    /// the timeout elapsed. After successful detection, the break interrupt flag
1527    /// is automatically cleared.
1528    ///
1529    /// ## Arguments
1530    /// * `timeout` - Maximum time to wait for a break condition
1531    #[instability::unstable]
1532    pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1533        self.rx.wait_for_break_with_timeout(timeout)
1534    }
1535}
1536
1537impl<'d> Uart<'d, Async> {
1538    /// Reconfigures the driver to operate in [`Blocking`] mode.
1539    ///
1540    /// See the [`Blocking`] documentation for an example on how to use this
1541    /// method.
1542    pub fn into_blocking(self) -> Uart<'d, Blocking> {
1543        Uart {
1544            rx: self.rx.into_blocking(),
1545            tx: self.tx.into_blocking(),
1546        }
1547    }
1548
1549    #[procmacros::doc_replace]
1550    /// Write data into the TX buffer.
1551    ///
1552    /// This function writes the provided buffer `bytes` into the UART transmit
1553    /// buffer. If the buffer is full, the function waits asynchronously for
1554    /// space in the buffer to become available.
1555    ///
1556    /// The function returns the number of bytes written into the buffer. This
1557    /// may be less than the length of the buffer.
1558    ///
1559    /// Upon an error, the function returns immediately and the contents of the
1560    /// internal FIFO are not modified.
1561    ///
1562    /// ## Cancellation
1563    ///
1564    /// This function is cancellation safe.
1565    ///
1566    /// ## Example
1567    ///
1568    /// ```rust, no_run
1569    /// # {before_snippet}
1570    /// use esp_hal::uart::{Config, Uart};
1571    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1572    ///     .with_rx(peripherals.GPIO1)
1573    ///     .with_tx(peripherals.GPIO2)
1574    ///     .into_async();
1575    ///
1576    /// const MESSAGE: &[u8] = b"Hello, world!";
1577    /// uart.write_async(&MESSAGE).await?;
1578    /// # {after_snippet}
1579    /// ```
1580    pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1581        self.tx.write_async(words).await
1582    }
1583
1584    #[procmacros::doc_replace]
1585    /// Asynchronously flushes the UART transmit buffer.
1586    ///
1587    /// This function ensures that all pending data in the transmit FIFO has
1588    /// been sent over the UART. If the FIFO contains data, it waits for the
1589    /// transmission to complete before returning.
1590    ///
1591    /// ## Cancellation
1592    ///
1593    /// This function is cancellation safe.
1594    ///
1595    /// ## Example
1596    ///
1597    /// ```rust, no_run
1598    /// # {before_snippet}
1599    /// use esp_hal::uart::{Config, Uart};
1600    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1601    ///     .with_rx(peripherals.GPIO1)
1602    ///     .with_tx(peripherals.GPIO2)
1603    ///     .into_async();
1604    ///
1605    /// const MESSAGE: &[u8] = b"Hello, world!";
1606    /// uart.write_async(&MESSAGE).await?;
1607    /// uart.flush_async().await?;
1608    /// # {after_snippet}
1609    /// ```
1610    pub async fn flush_async(&mut self) -> Result<(), TxError> {
1611        self.tx.flush_async().await
1612    }
1613
1614    #[procmacros::doc_replace]
1615    /// Read data asynchronously.
1616    ///
1617    /// This function reads data from the UART receive buffer into the
1618    /// provided buffer. If the buffer is empty, the function waits
1619    /// asynchronously for data to become available, or for an error to occur.
1620    ///
1621    /// The function returns the number of bytes read into the buffer. This may
1622    /// be less than the length of the buffer.
1623    ///
1624    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1625    /// to ensure that it does not wait for more data than the buffer can hold.
1626    ///
1627    /// Upon an error, the function returns immediately and the contents of the
1628    /// internal FIFO are not modified.
1629    ///
1630    /// ## Cancellation
1631    ///
1632    /// This function is cancellation safe.
1633    ///
1634    /// ## Example
1635    ///
1636    /// ```rust, no_run
1637    /// # {before_snippet}
1638    /// use esp_hal::uart::{Config, Uart};
1639    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1640    ///     .with_rx(peripherals.GPIO1)
1641    ///     .with_tx(peripherals.GPIO2)
1642    ///     .into_async();
1643    ///
1644    /// const MESSAGE: &[u8] = b"Hello, world!";
1645    /// uart.write_async(&MESSAGE).await?;
1646    /// uart.flush_async().await?;
1647    ///
1648    /// let mut buf = [0u8; MESSAGE.len()];
1649    /// uart.read_async(&mut buf[..]).await.unwrap();
1650    /// # {after_snippet}
1651    /// ```
1652    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1653        self.rx.read_async(buf).await
1654    }
1655
1656    /// Fill buffer asynchronously.
1657    ///
1658    /// This function reads data from the UART receive buffer into the
1659    /// provided buffer. If the buffer is empty, the function waits
1660    /// asynchronously for data to become available, or for an error to occur.
1661    ///
1662    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1663    /// to ensure that it does not wait for more data than the buffer can hold.
1664    ///
1665    /// ## Cancellation
1666    ///
1667    /// This function is **not** cancellation safe. If the future is dropped
1668    /// before it resolves, or if an error occurs during the read operation,
1669    /// previously read data may be lost.
1670    #[instability::unstable]
1671    pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1672        self.rx.read_exact_async(buf).await
1673    }
1674
1675    /// Waits for a break condition to be detected asynchronously.
1676    ///
1677    /// This is an async function that will await until a break condition is
1678    /// detected on the RX line. After detection, the break interrupt flag is
1679    /// automatically cleared.
1680    #[instability::unstable]
1681    pub async fn wait_for_break_async(&mut self) {
1682        self.rx.wait_for_break_async().await
1683    }
1684}
1685
1686/// List of exposed UART events.
1687#[derive(Debug, EnumSetType)]
1688#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1689#[non_exhaustive]
1690#[instability::unstable]
1691pub enum UartInterrupt {
1692    /// Indicates that the received has detected the configured
1693    /// [`Uart::set_at_cmd`] byte.
1694    AtCmd,
1695
1696    /// The transmitter has finished sending out all data from the FIFO.
1697    TxDone,
1698
1699    /// Break condition has been detected.
1700    /// Triggered when the receiver detects a NULL character (i.e. logic 0 for
1701    /// one NULL character transmission) after stop bits.
1702    RxBreakDetected,
1703
1704    /// The receiver has received more data than what
1705    /// [`RxConfig::fifo_full_threshold`] specifies.
1706    RxFifoFull,
1707
1708    /// The receiver has not received any data for the time
1709    /// [`RxConfig::with_timeout`] specifies.
1710    RxTimeout,
1711}
1712
1713impl<'d, Dm> Uart<'d, Dm>
1714where
1715    Dm: DriverMode,
1716{
1717    #[procmacros::doc_replace]
1718    /// Assign the RX pin for UART instance.
1719    ///
1720    /// Sets the specified pin to input and connects it to the UART RX signal.
1721    ///
1722    /// Note: when you listen for the output of the UART peripheral, you should
1723    /// configure the driver side (i.e. the TX pin), or ensure that the line is
1724    /// initially high, to avoid receiving a non-data byte caused by an
1725    /// initial low signal level.
1726    ///
1727    /// ## Example
1728    ///
1729    /// ```rust, no_run
1730    /// # {before_snippet}
1731    /// use esp_hal::uart::{Config, Uart};
1732    /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO1);
1733    ///
1734    /// # {after_snippet}
1735    /// ```
1736    pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1737        self.rx = self.rx.with_rx(rx);
1738        self
1739    }
1740
1741    #[procmacros::doc_replace]
1742    /// Assign the TX pin for UART instance.
1743    ///
1744    /// Sets the specified pin to push-pull output and connects it to the UART
1745    /// TX signal.
1746    ///
1747    /// ## Example
1748    ///
1749    /// ```rust, no_run
1750    /// # {before_snippet}
1751    /// use esp_hal::uart::{Config, Uart};
1752    /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO2);
1753    ///
1754    /// # {after_snippet}
1755    /// ```
1756    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1757        self.tx = self.tx.with_tx(tx);
1758        self
1759    }
1760
1761    #[procmacros::doc_replace]
1762    /// Configure CTS pin
1763    ///
1764    /// ## Example
1765    ///
1766    /// ```rust, no_run
1767    /// # {before_snippet}
1768    /// use esp_hal::uart::{Config, Uart};
1769    /// let uart = Uart::new(peripherals.UART0, Config::default())?
1770    ///     .with_rx(peripherals.GPIO1)
1771    ///     .with_cts(peripherals.GPIO3);
1772    ///
1773    /// # {after_snippet}
1774    /// ```
1775    pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1776        self.rx = self.rx.with_cts(cts);
1777        self
1778    }
1779
1780    #[procmacros::doc_replace]
1781    /// Configure RTS pin
1782    ///
1783    /// ## Example
1784    ///
1785    /// ```rust, no_run
1786    /// # {before_snippet}
1787    /// use esp_hal::uart::{Config, Uart};
1788    /// let uart = Uart::new(peripherals.UART0, Config::default())?
1789    ///     .with_tx(peripherals.GPIO2)
1790    ///     .with_rts(peripherals.GPIO3);
1791    ///
1792    /// # {after_snippet}
1793    /// ```
1794    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1795        self.tx = self.tx.with_rts(rts);
1796        self
1797    }
1798
1799    fn regs(&self) -> &RegisterBlock {
1800        // `self.tx.uart` and `self.rx.uart` are the same
1801        self.tx.uart.info().regs()
1802    }
1803
1804    #[procmacros::doc_replace]
1805    /// Returns whether the UART TX buffer is ready to accept more data.
1806    ///
1807    /// If this function returns `true`, [`Self::write`] and [`Self::write_async`]
1808    /// will not block. Otherwise, the functions will not return until the buffer is
1809    /// ready.
1810    ///
1811    /// ## Example
1812    ///
1813    /// ```rust, no_run
1814    /// # {before_snippet}
1815    /// use esp_hal::uart::{Config, Uart};
1816    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1817    ///
1818    /// if uart.write_ready() {
1819    ///     // Because write_ready has returned true, the following call will immediately
1820    ///     // copy some bytes into the FIFO and return a non-zero value.
1821    ///     let written = uart.write(b"Hello")?;
1822    ///     // ... handle written bytes
1823    /// } else {
1824    ///     // Calling write would have blocked, but here we can do something useful
1825    ///     // instead of waiting for the buffer to become ready.
1826    /// }
1827    /// # {after_snippet}
1828    /// ```
1829    pub fn write_ready(&self) -> bool {
1830        self.tx.write_ready()
1831    }
1832
1833    #[procmacros::doc_replace]
1834    /// Writes bytes.
1835    ///
1836    /// This function writes data to the internal TX FIFO of the UART
1837    /// peripheral. The data is then transmitted over the UART TX line.
1838    ///
1839    /// The function returns the number of bytes written to the FIFO. This may
1840    /// be less than the length of the provided data. The function may only
1841    /// return 0 if the provided data is empty.
1842    ///
1843    /// ## Errors
1844    ///
1845    /// This function returns a [`TxError`] if an error occurred during the
1846    /// write operation.
1847    ///
1848    /// ## Example
1849    ///
1850    /// ```rust, no_run
1851    /// # {before_snippet}
1852    /// use esp_hal::uart::{Config, Uart};
1853    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1854    ///
1855    /// const MESSAGE: &[u8] = b"Hello, world!";
1856    /// uart.write(&MESSAGE)?;
1857    /// # {after_snippet}
1858    /// ```
1859    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1860        self.tx.write(data)
1861    }
1862
1863    #[procmacros::doc_replace]
1864    /// Flush the transmit buffer of the UART
1865    ///
1866    /// ## Example
1867    ///
1868    /// ```rust, no_run
1869    /// # {before_snippet}
1870    /// use esp_hal::uart::{Config, Uart};
1871    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1872    ///
1873    /// const MESSAGE: &[u8] = b"Hello, world!";
1874    /// uart.write(&MESSAGE)?;
1875    /// uart.flush()?;
1876    /// # {after_snippet}
1877    /// ```
1878    pub fn flush(&mut self) -> Result<(), TxError> {
1879        self.tx.flush()
1880    }
1881
1882    /// Sends a break signal for a specified duration
1883    #[instability::unstable]
1884    pub fn send_break(&mut self, bits: u32) {
1885        self.tx.send_break(bits)
1886    }
1887
1888    #[procmacros::doc_replace]
1889    /// Returns whether the UART receive buffer has at least one byte of data.
1890    ///
1891    /// If this function returns `true`, [`Self::read`] and [`Self::read_async`]
1892    /// will not block. Otherwise, they will not return until data is available.
1893    ///
1894    /// Data that does not get stored due to an error will be lost and does not count
1895    /// towards the number of bytes in the receive buffer.
1896    // TODO: once we add support for UART_ERR_WR_MASK it needs to be documented here.
1897    /// ## Example
1898    ///
1899    /// ```rust, no_run
1900    /// # {before_snippet}
1901    /// use esp_hal::uart::{Config, Uart};
1902    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1903    ///
1904    /// while !uart.read_ready() {
1905    ///     // Do something else while waiting for data to be available.
1906    /// }
1907    ///
1908    /// let mut buf = [0u8; 32];
1909    /// uart.read(&mut buf[..])?;
1910    ///
1911    /// # {after_snippet}
1912    /// ```
1913    pub fn read_ready(&self) -> bool {
1914        self.rx.read_ready()
1915    }
1916
1917    #[procmacros::doc_replace]
1918    /// Read received bytes.
1919    ///
1920    /// The UART hardware continuously receives bytes and stores them in the RX
1921    /// FIFO. This function reads the bytes from the RX FIFO and returns
1922    /// them in the provided buffer. If the hardware buffer is empty, this
1923    /// function will block until data is available. The [`Self::read_ready`]
1924    /// function can be used to check if data is available without blocking.
1925    ///
1926    /// The function returns the number of bytes read into the buffer. This may
1927    /// be less than the length of the buffer. This function only returns 0
1928    /// if the provided buffer is empty.
1929    ///
1930    /// ## Errors
1931    ///
1932    /// This function returns an [`RxError`] if an error occurred since the last
1933    /// check for errors.
1934    ///
1935    /// If the error occurred before this function was called, the contents of
1936    /// the FIFO are not modified.
1937    ///
1938    /// ## Example
1939    ///
1940    /// ```rust, no_run
1941    /// # {before_snippet}
1942    /// use esp_hal::uart::{Config, Uart};
1943    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1944    ///
1945    /// const MESSAGE: &[u8] = b"Hello, world!";
1946    /// uart.write(&MESSAGE)?;
1947    /// uart.flush()?;
1948    ///
1949    /// let mut buf = [0u8; MESSAGE.len()];
1950    /// uart.read(&mut buf[..])?;
1951    ///
1952    /// # {after_snippet}
1953    /// ```
1954    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1955        self.rx.read(buf)
1956    }
1957
1958    #[procmacros::doc_replace]
1959    /// Change the configuration.
1960    ///
1961    /// ## Errors
1962    ///
1963    /// This function returns a [`ConfigError`] if the configuration is not
1964    /// supported by the hardware.
1965    ///
1966    /// ## Example
1967    ///
1968    /// ```rust, no_run
1969    /// # {before_snippet}
1970    /// use esp_hal::uart::{Config, Uart};
1971    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1972    ///
1973    /// uart.apply_config(&Config::default().with_baudrate(19_200))?;
1974    /// # {after_snippet}
1975    /// ```
1976    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1977        // Must apply the common settings first, as `rx.apply_config` reads back symbol
1978        // size.
1979        self.rx.uart.info().apply_config(config)?;
1980
1981        self.rx.apply_config(config)?;
1982        self.tx.apply_config(config)?;
1983        Ok(())
1984    }
1985
1986    #[procmacros::doc_replace]
1987    /// Split the UART into a transmitter and receiver
1988    ///
1989    /// This is particularly useful when having two tasks correlating to
1990    /// transmitting and receiving.
1991    ///
1992    /// ## Example
1993    ///
1994    /// ```rust, no_run
1995    /// # {before_snippet}
1996    /// use esp_hal::uart::{Config, Uart};
1997    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1998    ///     .with_rx(peripherals.GPIO1)
1999    ///     .with_tx(peripherals.GPIO2);
2000    ///
2001    /// // The UART can be split into separate Transmit and Receive components:
2002    /// let (mut rx, mut tx) = uart.split();
2003    ///
2004    /// // Each component can be used individually to interact with the UART:
2005    /// tx.write(&[42u8])?;
2006    /// let mut byte = [0u8; 1];
2007    /// rx.read(&mut byte);
2008    /// # {after_snippet}
2009    /// ```
2010    #[instability::unstable]
2011    pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
2012        (self.rx, self.tx)
2013    }
2014
2015    /// Reads and clears errors set by received data.
2016    #[instability::unstable]
2017    pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
2018        self.rx.check_for_errors()
2019    }
2020
2021    /// Read already received bytes.
2022    ///
2023    /// This function reads the already received bytes from the FIFO into the
2024    /// provided buffer. The function does not wait for the FIFO to actually
2025    /// contain any bytes.
2026    ///
2027    /// The function returns the number of bytes read into the buffer. This may
2028    /// be less than the length of the buffer, and it may also be 0.
2029    ///
2030    /// ## Errors
2031    ///
2032    /// This function returns an [`RxError`] if an error occurred since the last
2033    /// check for errors.
2034    ///
2035    /// If the error occurred before this function was called, the contents of
2036    /// the FIFO are not modified.
2037    #[instability::unstable]
2038    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2039        self.rx.read_buffered(buf)
2040    }
2041
2042    /// Configures the AT-CMD detection settings
2043    #[instability::unstable]
2044    pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
2045        #[cfg(not(any(esp32, esp32s2)))]
2046        self.regs()
2047            .clk_conf()
2048            .modify(|_, w| w.sclk_en().clear_bit());
2049
2050        self.regs().at_cmd_char().write(|w| unsafe {
2051            w.at_cmd_char().bits(config.cmd_char);
2052            w.char_num().bits(config.char_num)
2053        });
2054
2055        if let Some(pre_idle_count) = config.pre_idle_count {
2056            self.regs()
2057                .at_cmd_precnt()
2058                .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
2059        }
2060
2061        if let Some(post_idle_count) = config.post_idle_count {
2062            self.regs()
2063                .at_cmd_postcnt()
2064                .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
2065        }
2066
2067        if let Some(gap_timeout) = config.gap_timeout {
2068            self.regs()
2069                .at_cmd_gaptout()
2070                .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
2071        }
2072
2073        #[cfg(not(any(esp32, esp32s2)))]
2074        self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
2075
2076        sync_regs(self.regs());
2077    }
2078
2079    #[inline(always)]
2080    fn init(&mut self, config: Config) -> Result<(), ConfigError> {
2081        self.rx.disable_rx_interrupts();
2082        self.tx.disable_tx_interrupts();
2083
2084        // Reset Tx/Rx FIFOs
2085        self.rx.uart.info().rxfifo_reset();
2086        self.rx.uart.info().txfifo_reset();
2087
2088        self.apply_config(&config)?;
2089
2090        // Don't wait after transmissions by default,
2091        // so that bytes written to TX FIFO are always immediately transmitted.
2092        self.regs()
2093            .idle_conf()
2094            .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2095
2096        // Setting err_wr_mask stops uart from storing data when data is wrong according
2097        // to reference manual
2098        self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
2099
2100        crate::rom::ets_delay_us(15);
2101
2102        // Make sure we are starting in a "clean state" - previous operations might have
2103        // run into error conditions
2104        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
2105
2106        Ok(())
2107    }
2108}
2109
2110impl crate::private::Sealed for Uart<'_, Blocking> {}
2111
2112#[instability::unstable]
2113impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
2114    fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
2115        // `self.tx.uart` and `self.rx.uart` are the same
2116        self.tx.uart.set_interrupt_handler(handler);
2117    }
2118}
2119
2120#[instability::unstable]
2121impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
2122where
2123    Dm: DriverMode,
2124{
2125    type Error = TxError;
2126
2127    #[inline]
2128    fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2129        self.tx.write_str(s)
2130    }
2131
2132    #[inline]
2133    fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
2134        self.tx.write_char(ch)
2135    }
2136}
2137
2138#[instability::unstable]
2139impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
2140where
2141    Dm: DriverMode,
2142{
2143    type Error = TxError;
2144
2145    #[inline]
2146    fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2147        self.write_all(s.as_bytes())
2148    }
2149}
2150
2151impl<Dm> core::fmt::Write for Uart<'_, Dm>
2152where
2153    Dm: DriverMode,
2154{
2155    #[inline]
2156    fn write_str(&mut self, s: &str) -> core::fmt::Result {
2157        self.tx.write_str(s)
2158    }
2159}
2160
2161impl<Dm> core::fmt::Write for UartTx<'_, Dm>
2162where
2163    Dm: DriverMode,
2164{
2165    #[inline]
2166    fn write_str(&mut self, s: &str) -> core::fmt::Result {
2167        self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
2168    }
2169}
2170
2171/// UART Tx or Rx Error
2172#[instability::unstable]
2173#[derive(Debug, Clone, Copy, PartialEq)]
2174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2175#[non_exhaustive]
2176pub enum IoError {
2177    /// UART TX error
2178    Tx(TxError),
2179    /// UART RX error
2180    Rx(RxError),
2181}
2182
2183#[instability::unstable]
2184impl core::error::Error for IoError {}
2185
2186#[instability::unstable]
2187impl core::fmt::Display for IoError {
2188    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2189        match self {
2190            IoError::Tx(e) => e.fmt(f),
2191            IoError::Rx(e) => e.fmt(f),
2192        }
2193    }
2194}
2195
2196#[instability::unstable]
2197impl embedded_io_06::Error for IoError {
2198    fn kind(&self) -> embedded_io_06::ErrorKind {
2199        embedded_io_06::ErrorKind::Other
2200    }
2201}
2202
2203#[instability::unstable]
2204impl embedded_io_07::Error for IoError {
2205    fn kind(&self) -> embedded_io_07::ErrorKind {
2206        embedded_io_07::ErrorKind::Other
2207    }
2208}
2209
2210#[instability::unstable]
2211impl From<RxError> for IoError {
2212    fn from(e: RxError) -> Self {
2213        IoError::Rx(e)
2214    }
2215}
2216
2217#[instability::unstable]
2218impl From<TxError> for IoError {
2219    fn from(e: TxError) -> Self {
2220        IoError::Tx(e)
2221    }
2222}
2223
2224#[instability::unstable]
2225impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2226    type Error = IoError;
2227}
2228
2229#[instability::unstable]
2230impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2231    type Error = TxError;
2232}
2233
2234#[instability::unstable]
2235impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2236    type Error = RxError;
2237}
2238
2239#[instability::unstable]
2240impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2241where
2242    Dm: DriverMode,
2243{
2244    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2245        self.rx.read(buf).map_err(IoError::Rx)
2246    }
2247}
2248
2249#[instability::unstable]
2250impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2251where
2252    Dm: DriverMode,
2253{
2254    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2255        self.read(buf)
2256    }
2257}
2258
2259#[instability::unstable]
2260impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2261where
2262    Dm: DriverMode,
2263{
2264    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2265        Ok(self.rx.read_ready())
2266    }
2267}
2268
2269#[instability::unstable]
2270impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2271where
2272    Dm: DriverMode,
2273{
2274    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2275        Ok(UartRx::read_ready(self))
2276    }
2277}
2278
2279#[instability::unstable]
2280impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2281where
2282    Dm: DriverMode,
2283{
2284    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2285        self.tx.write(buf).map_err(IoError::Tx)
2286    }
2287
2288    fn flush(&mut self) -> Result<(), Self::Error> {
2289        self.tx.flush().map_err(IoError::Tx)
2290    }
2291}
2292
2293#[instability::unstable]
2294impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2295where
2296    Dm: DriverMode,
2297{
2298    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2299        self.write(buf)
2300    }
2301
2302    fn flush(&mut self) -> Result<(), Self::Error> {
2303        self.flush()
2304    }
2305}
2306
2307#[instability::unstable]
2308impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2309where
2310    Dm: DriverMode,
2311{
2312    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2313        Ok(UartTx::write_ready(self))
2314    }
2315}
2316
2317#[instability::unstable]
2318impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2319where
2320    Dm: DriverMode,
2321{
2322    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2323        Ok(self.tx.write_ready())
2324    }
2325}
2326
2327#[instability::unstable]
2328impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2329    type Error = IoError;
2330}
2331
2332#[instability::unstable]
2333impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2334    type Error = TxError;
2335}
2336
2337#[instability::unstable]
2338impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2339    type Error = RxError;
2340}
2341
2342#[instability::unstable]
2343impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2344where
2345    Dm: DriverMode,
2346{
2347    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2348        self.rx.read(buf).map_err(IoError::Rx)
2349    }
2350}
2351
2352#[instability::unstable]
2353impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2354where
2355    Dm: DriverMode,
2356{
2357    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2358        self.read(buf)
2359    }
2360}
2361
2362#[instability::unstable]
2363impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2364where
2365    Dm: DriverMode,
2366{
2367    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2368        Ok(self.rx.read_ready())
2369    }
2370}
2371
2372#[instability::unstable]
2373impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2374where
2375    Dm: DriverMode,
2376{
2377    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2378        Ok(UartRx::read_ready(self))
2379    }
2380}
2381
2382#[instability::unstable]
2383impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2384where
2385    Dm: DriverMode,
2386{
2387    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2388        self.tx.write(buf).map_err(IoError::Tx)
2389    }
2390
2391    fn flush(&mut self) -> Result<(), Self::Error> {
2392        self.tx.flush().map_err(IoError::Tx)
2393    }
2394}
2395
2396#[instability::unstable]
2397impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2398where
2399    Dm: DriverMode,
2400{
2401    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2402        self.write(buf)
2403    }
2404
2405    fn flush(&mut self) -> Result<(), Self::Error> {
2406        self.flush()
2407    }
2408}
2409
2410#[instability::unstable]
2411impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2412where
2413    Dm: DriverMode,
2414{
2415    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2416        Ok(UartTx::write_ready(self))
2417    }
2418}
2419
2420#[instability::unstable]
2421impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2422where
2423    Dm: DriverMode,
2424{
2425    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2426        Ok(self.tx.write_ready())
2427    }
2428}
2429
2430#[derive(Debug, EnumSetType)]
2431pub(crate) enum TxEvent {
2432    Done,
2433    FiFoEmpty,
2434}
2435
2436#[derive(Debug, EnumSetType)]
2437pub(crate) enum RxEvent {
2438    FifoFull,
2439    CmdCharDetected,
2440    FifoOvf,
2441    FifoTout,
2442    GlitchDetected,
2443    FrameError,
2444    ParityError,
2445    BreakDetected,
2446}
2447
2448fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2449    for event in events {
2450        match event {
2451            RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2452            RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2453            RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2454            RxEvent::ParityError => return Err(RxError::ParityMismatch),
2455            RxEvent::FifoFull
2456            | RxEvent::CmdCharDetected
2457            | RxEvent::FifoTout
2458            | RxEvent::BreakDetected => continue,
2459        }
2460    }
2461
2462    Ok(())
2463}
2464
2465/// A future that resolves when the passed interrupt is triggered,
2466/// or has been triggered in the meantime (flag set in INT_RAW).
2467/// Upon construction the future enables the passed interrupt and when it
2468/// is dropped it disables the interrupt again. The future returns the event
2469/// that was initially passed, when it resolves.
2470#[must_use = "futures do nothing unless you `.await` or poll them"]
2471struct UartRxFuture {
2472    events: EnumSet<RxEvent>,
2473    uart: &'static Info,
2474    state: &'static State,
2475    registered: bool,
2476}
2477
2478impl UartRxFuture {
2479    fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2480        Self {
2481            events: events.into(),
2482            uart: uart.info(),
2483            state: uart.state(),
2484            registered: false,
2485        }
2486    }
2487}
2488
2489impl core::future::Future for UartRxFuture {
2490    type Output = EnumSet<RxEvent>;
2491
2492    fn poll(
2493        mut self: core::pin::Pin<&mut Self>,
2494        cx: &mut core::task::Context<'_>,
2495    ) -> core::task::Poll<Self::Output> {
2496        let events = self.uart.rx_events().intersection(self.events);
2497        if !events.is_empty() {
2498            self.uart.clear_rx_events(events);
2499            Poll::Ready(events)
2500        } else {
2501            self.state.rx_waker.register(cx.waker());
2502            if !self.registered {
2503                self.uart.enable_listen_rx(self.events, true);
2504                self.registered = true;
2505            }
2506            Poll::Pending
2507        }
2508    }
2509}
2510
2511impl Drop for UartRxFuture {
2512    fn drop(&mut self) {
2513        // Although the isr disables the interrupt that occurred directly, we need to
2514        // disable the other interrupts (= the ones that did not occur), as
2515        // soon as this future goes out of scope.
2516        self.uart.enable_listen_rx(self.events, false);
2517    }
2518}
2519
2520#[must_use = "futures do nothing unless you `.await` or poll them"]
2521struct UartTxFuture {
2522    events: EnumSet<TxEvent>,
2523    uart: &'static Info,
2524    state: &'static State,
2525    registered: bool,
2526}
2527
2528impl UartTxFuture {
2529    fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2530        Self {
2531            events: events.into(),
2532            uart: uart.info(),
2533            state: uart.state(),
2534            registered: false,
2535        }
2536    }
2537}
2538
2539impl core::future::Future for UartTxFuture {
2540    type Output = ();
2541
2542    fn poll(
2543        mut self: core::pin::Pin<&mut Self>,
2544        cx: &mut core::task::Context<'_>,
2545    ) -> core::task::Poll<Self::Output> {
2546        let events = self.uart.tx_events().intersection(self.events);
2547        if !events.is_empty() {
2548            self.uart.clear_tx_events(events);
2549            Poll::Ready(())
2550        } else {
2551            self.state.tx_waker.register(cx.waker());
2552            if !self.registered {
2553                self.uart.enable_listen_tx(self.events, true);
2554                self.registered = true;
2555            }
2556            Poll::Pending
2557        }
2558    }
2559}
2560
2561impl Drop for UartTxFuture {
2562    fn drop(&mut self) {
2563        // Although the isr disables the interrupt that occurred directly, we need to
2564        // disable the other interrupts (= the ones that did not occur), as
2565        // soon as this future goes out of scope.
2566        self.uart.enable_listen_tx(self.events, false);
2567    }
2568}
2569
2570#[instability::unstable]
2571impl embedded_io_async_06::Read for Uart<'_, Async> {
2572    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2573        self.read_async(buf).await.map_err(IoError::Rx)
2574    }
2575
2576    async fn read_exact(
2577        &mut self,
2578        buf: &mut [u8],
2579    ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2580        self.read_exact_async(buf)
2581            .await
2582            .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2583    }
2584}
2585
2586#[instability::unstable]
2587impl embedded_io_async_06::Read for UartRx<'_, Async> {
2588    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2589        self.read_async(buf).await
2590    }
2591
2592    async fn read_exact(
2593        &mut self,
2594        buf: &mut [u8],
2595    ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2596        self.read_exact_async(buf)
2597            .await
2598            .map_err(embedded_io_06::ReadExactError::Other)
2599    }
2600}
2601
2602#[instability::unstable]
2603impl embedded_io_async_06::Write for Uart<'_, Async> {
2604    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2605        self.write_async(buf).await.map_err(IoError::Tx)
2606    }
2607
2608    async fn flush(&mut self) -> Result<(), Self::Error> {
2609        self.flush_async().await.map_err(IoError::Tx)
2610    }
2611}
2612
2613#[instability::unstable]
2614impl embedded_io_async_06::Write for UartTx<'_, Async> {
2615    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2616        self.write_async(buf).await
2617    }
2618
2619    async fn flush(&mut self) -> Result<(), Self::Error> {
2620        self.flush_async().await
2621    }
2622}
2623
2624#[instability::unstable]
2625impl embedded_io_async_07::Read for Uart<'_, Async> {
2626    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2627        self.read_async(buf).await.map_err(IoError::Rx)
2628    }
2629
2630    async fn read_exact(
2631        &mut self,
2632        buf: &mut [u8],
2633    ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2634        self.read_exact_async(buf)
2635            .await
2636            .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2637    }
2638}
2639
2640#[instability::unstable]
2641impl embedded_io_async_07::Read for UartRx<'_, Async> {
2642    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2643        self.read_async(buf).await
2644    }
2645
2646    async fn read_exact(
2647        &mut self,
2648        buf: &mut [u8],
2649    ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2650        self.read_exact_async(buf)
2651            .await
2652            .map_err(embedded_io_07::ReadExactError::Other)
2653    }
2654}
2655
2656#[instability::unstable]
2657impl embedded_io_async_07::Write for Uart<'_, Async> {
2658    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2659        self.write_async(buf).await.map_err(IoError::Tx)
2660    }
2661
2662    async fn flush(&mut self) -> Result<(), Self::Error> {
2663        self.flush_async().await.map_err(IoError::Tx)
2664    }
2665}
2666
2667#[instability::unstable]
2668impl embedded_io_async_07::Write for UartTx<'_, Async> {
2669    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2670        self.write_async(buf).await
2671    }
2672
2673    async fn flush(&mut self) -> Result<(), Self::Error> {
2674        self.flush_async().await
2675    }
2676}
2677
2678/// Interrupt handler for all UART instances
2679/// Clears and disables interrupts that have occurred and have their enable
2680/// bit set. The fact that an interrupt has been disabled is used by the
2681/// futures to detect that they should indeed resolve after being woken up
2682#[ram]
2683pub(super) fn intr_handler(uart: &Info, state: &State) {
2684    let interrupts = uart.regs().int_st().read();
2685    let interrupt_bits = interrupts.bits(); // = int_raw & int_ena
2686    let rx_wake = interrupts.rxfifo_full().bit_is_set()
2687        | interrupts.rxfifo_ovf().bit_is_set()
2688        | interrupts.rxfifo_tout().bit_is_set()
2689        | interrupts.at_cmd_char_det().bit_is_set()
2690        | interrupts.glitch_det().bit_is_set()
2691        | interrupts.frm_err().bit_is_set()
2692        | interrupts.parity_err().bit_is_set();
2693    let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2694
2695    uart.regs()
2696        .int_ena()
2697        .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2698
2699    if tx_wake {
2700        state.tx_waker.wake();
2701    }
2702    if rx_wake {
2703        state.rx_waker.wake();
2704    }
2705}
2706
2707/// Low-power UART
2708#[cfg(lp_uart_driver_supported)]
2709#[instability::unstable]
2710pub mod lp_uart {
2711    use crate::{
2712        gpio::lp_io::{LowPowerInput, LowPowerOutput},
2713        peripherals::{LP_AON, LP_CLKRST, LP_IO, LP_UART, LPWR},
2714        soc::clocks::ClockTree,
2715        uart::{DataBits, Parity, StopBits},
2716    };
2717
2718    /// LP-UART Configuration
2719    #[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
2720    #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2721    #[non_exhaustive]
2722    pub struct Config {
2723        /// The baud rate (speed) of the UART communication in bits per second
2724        /// (bps).
2725        baudrate: u32,
2726        /// Number of data bits in each frame (5, 6, 7, or 8 bits).
2727        data_bits: DataBits,
2728        /// Parity setting (None, Even, or Odd).
2729        parity: Parity,
2730        /// Number of stop bits in each frame (1, 1.5, or 2 bits).
2731        stop_bits: StopBits,
2732        /// Clock source used by the UART peripheral.
2733        #[builder_lite(unstable)]
2734        clock_source: ClockSource,
2735    }
2736
2737    impl Default for Config {
2738        fn default() -> Config {
2739            Config {
2740                baudrate: 115_200,
2741                data_bits: Default::default(),
2742                parity: Default::default(),
2743                stop_bits: Default::default(),
2744                clock_source: Default::default(),
2745            }
2746        }
2747    }
2748
2749    /// LP-UART clock source
2750    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
2751    #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2752    #[non_exhaustive]
2753    #[instability::unstable]
2754    pub enum ClockSource {
2755        /// RC_FAST_CLK clock source
2756        RcFast,
2757
2758        /// XTAL_D2 clock source
2759        #[default]
2760        Xtal,
2761    }
2762
2763    /// LP-UART driver
2764    pub struct LpUart {
2765        uart: LP_UART<'static>,
2766    }
2767
2768    impl LpUart {
2769        /// Initialize the UART driver using the provided configuration
2770        // TODO: CTS and RTS pins
2771        pub fn new(
2772            uart: LP_UART<'static>,
2773            config: Config,
2774            _tx: LowPowerOutput<'_, 5>,
2775            _rx: LowPowerInput<'_, 4>,
2776        ) -> Self {
2777            // FIXME: use GPIO APIs to configure pins
2778            LP_AON::regs()
2779                .gpio_mux()
2780                .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2781
2782            LP_IO::regs()
2783                .gpio(4)
2784                .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2785            LP_IO::regs()
2786                .gpio(5)
2787                .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2788
2789            let mut me = Self { uart };
2790            let uart = me.uart.register_block();
2791
2792            // Set UART mode - do nothing for LP
2793
2794            // Disable UART parity
2795            // 8-bit world
2796            // 1-bit stop bit
2797            uart.conf0().modify(|_, w| unsafe {
2798                w.parity().clear_bit();
2799                w.parity_en().clear_bit();
2800                w.bit_num().bits(0x3);
2801                w.stop_bit_num().bits(0x1)
2802            });
2803            // Set tx idle
2804            uart.idle_conf()
2805                .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2806            // Disable hw-flow control
2807            uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2808
2809            // Get source clock frequency
2810            // default == SOC_MOD_CLK_RTC_FAST == 2
2811
2812            // LPWR.lpperi.lp_uart_clk_sel = 0;
2813            LPWR::regs()
2814                .lpperi()
2815                .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2816
2817            // Override protocol parameters from the configuration
2818            // uart_hal_set_baudrate(&hal, cfg->uart_proto_cfg.baud_rate, sclk_freq);
2819            me.change_baud_internal(&config);
2820            // uart_hal_set_parity(&hal, cfg->uart_proto_cfg.parity);
2821            me.change_parity(config.parity);
2822            // uart_hal_set_data_bit_num(&hal, cfg->uart_proto_cfg.data_bits);
2823            me.change_data_bits(config.data_bits);
2824            // uart_hal_set_stop_bits(&hal, cfg->uart_proto_cfg.stop_bits);
2825            me.change_stop_bits(config.stop_bits);
2826            // uart_hal_set_tx_idle_num(&hal, LP_UART_TX_IDLE_NUM_DEFAULT);
2827            me.change_tx_idle(0); // LP_UART_TX_IDLE_NUM_DEFAULT == 0
2828
2829            // Reset Tx/Rx FIFOs
2830            me.rxfifo_reset();
2831            me.txfifo_reset();
2832
2833            me
2834        }
2835
2836        fn rxfifo_reset(&mut self) {
2837            self.uart
2838                .register_block()
2839                .conf0()
2840                .modify(|_, w| w.rxfifo_rst().set_bit());
2841            self.update();
2842
2843            self.uart
2844                .register_block()
2845                .conf0()
2846                .modify(|_, w| w.rxfifo_rst().clear_bit());
2847            self.update();
2848        }
2849
2850        fn txfifo_reset(&mut self) {
2851            self.uart
2852                .register_block()
2853                .conf0()
2854                .modify(|_, w| w.txfifo_rst().set_bit());
2855            self.update();
2856
2857            self.uart
2858                .register_block()
2859                .conf0()
2860                .modify(|_, w| w.txfifo_rst().clear_bit());
2861            self.update();
2862        }
2863
2864        fn update(&mut self) {
2865            let register_block = self.uart.register_block();
2866            register_block
2867                .reg_update()
2868                .modify(|_, w| w.reg_update().set_bit());
2869            while register_block.reg_update().read().reg_update().bit_is_set() {
2870                // wait
2871            }
2872        }
2873
2874        fn change_baud_internal(&mut self, config: &Config) {
2875            let clk = ClockTree::with(|clocks| match config.clock_source {
2876                ClockSource::RcFast => crate::soc::clocks::rc_fast_clk_frequency(clocks),
2877                ClockSource::Xtal => crate::soc::clocks::xtal_d2_clk_frequency(clocks),
2878            });
2879
2880            LP_CLKRST::regs().lpperi().modify(|_, w| {
2881                w.lp_uart_clk_sel().bit(match config.clock_source {
2882                    ClockSource::RcFast => false,
2883                    ClockSource::Xtal => true,
2884                })
2885            });
2886            self.uart.register_block().clk_conf().modify(|_, w| {
2887                w.rx_sclk_en().set_bit();
2888                w.tx_sclk_en().set_bit()
2889            });
2890
2891            let divider = clk / config.baudrate;
2892            let divider = divider as u16;
2893
2894            self.uart
2895                .register_block()
2896                .clkdiv()
2897                .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2898
2899            self.update();
2900        }
2901
2902        /// Modify UART baud rate and reset TX/RX fifo.
2903        pub fn change_baud(&mut self, config: &Config) {
2904            self.change_baud_internal(config);
2905            self.txfifo_reset();
2906            self.rxfifo_reset();
2907        }
2908
2909        fn change_parity(&mut self, parity: Parity) -> &mut Self {
2910            if parity != Parity::None {
2911                self.uart
2912                    .register_block()
2913                    .conf0()
2914                    .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2915            }
2916
2917            self.uart
2918                .register_block()
2919                .conf0()
2920                .modify(|_, w| match parity {
2921                    Parity::None => w.parity_en().clear_bit(),
2922                    Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2923                    Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2924                });
2925
2926            self
2927        }
2928
2929        fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2930            self.uart
2931                .register_block()
2932                .conf0()
2933                .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2934
2935            self.update();
2936            self
2937        }
2938
2939        fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2940            self.uart
2941                .register_block()
2942                .conf0()
2943                .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2944
2945            self.update();
2946            self
2947        }
2948
2949        fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2950            self.uart
2951                .register_block()
2952                .idle_conf()
2953                .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2954
2955            self.update();
2956            self
2957        }
2958    }
2959}
2960
2961/// A peripheral singleton compatible with the UART driver.
2962pub trait Instance: crate::private::Sealed + any::Degrade {
2963    #[doc(hidden)]
2964    /// Returns the peripheral data and state describing this UART instance.
2965    fn parts(&self) -> (&'static Info, &'static State);
2966
2967    /// Returns the peripheral data describing this UART instance.
2968    #[inline(always)]
2969    #[doc(hidden)]
2970    fn info(&self) -> &'static Info {
2971        self.parts().0
2972    }
2973
2974    /// Returns the peripheral state for this UART instance.
2975    #[inline(always)]
2976    #[doc(hidden)]
2977    fn state(&self) -> &'static State {
2978        self.parts().1
2979    }
2980}
2981
2982/// Peripheral data describing a particular UART instance.
2983#[doc(hidden)]
2984#[non_exhaustive]
2985#[allow(private_interfaces, reason = "Unstable details")]
2986pub struct Info {
2987    /// Pointer to the register block for this UART instance.
2988    ///
2989    /// Use [Self::register_block] to access the register block.
2990    pub register_block: *const RegisterBlock,
2991
2992    /// The system peripheral marker.
2993    pub peripheral: crate::system::Peripheral,
2994
2995    /// UART clock group instance.
2996    pub clock_instance: clocks::UartInstance,
2997
2998    /// Interrupt handler for the asynchronous operations of this UART instance.
2999    pub async_handler: InterruptHandler,
3000
3001    /// TX pin
3002    pub tx_signal: OutputSignal,
3003
3004    /// RX pin
3005    pub rx_signal: InputSignal,
3006
3007    /// CTS (Clear to Send) pin
3008    pub cts_signal: InputSignal,
3009
3010    /// RTS (Request to Send) pin
3011    pub rts_signal: OutputSignal,
3012}
3013
3014/// Peripheral state for a UART instance.
3015#[doc(hidden)]
3016#[non_exhaustive]
3017pub struct State {
3018    /// Waker for the asynchronous RX operations.
3019    pub rx_waker: AtomicWaker,
3020
3021    /// Waker for the asynchronous TX operations.
3022    pub tx_waker: AtomicWaker,
3023
3024    /// Stores whether the TX half is configured for async operation.
3025    pub is_rx_async: AtomicBool,
3026
3027    /// Stores whether the RX half is configured for async operation.
3028    pub is_tx_async: AtomicBool,
3029}
3030
3031impl Info {
3032    // Currently we don't support merging adjacent FIFO memory, so the max size is
3033    // 128 bytes, the max threshold is 127 bytes.
3034    const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
3035    const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
3036    const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
3037
3038    /// Returns the register block for this UART instance.
3039    pub fn regs(&self) -> &RegisterBlock {
3040        unsafe { &*self.register_block }
3041    }
3042
3043    /// Listen for the given interrupts
3044    fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
3045        let reg_block = self.regs();
3046
3047        reg_block.int_ena().modify(|_, w| {
3048            for interrupt in interrupts {
3049                match interrupt {
3050                    UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
3051                    UartInterrupt::TxDone => w.tx_done().bit(enable),
3052                    UartInterrupt::RxBreakDetected => w.brk_det().bit(enable),
3053                    UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
3054                    UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
3055                };
3056            }
3057            w
3058        });
3059    }
3060
3061    fn interrupts(&self) -> EnumSet<UartInterrupt> {
3062        let mut res = EnumSet::new();
3063        let reg_block = self.regs();
3064
3065        let ints = reg_block.int_raw().read();
3066
3067        if ints.at_cmd_char_det().bit_is_set() {
3068            res.insert(UartInterrupt::AtCmd);
3069        }
3070        if ints.tx_done().bit_is_set() {
3071            res.insert(UartInterrupt::TxDone);
3072        }
3073        if ints.brk_det().bit_is_set() {
3074            res.insert(UartInterrupt::RxBreakDetected);
3075        }
3076        if ints.rxfifo_full().bit_is_set() {
3077            res.insert(UartInterrupt::RxFifoFull);
3078        }
3079        if ints.rxfifo_tout().bit_is_set() {
3080            res.insert(UartInterrupt::RxTimeout);
3081        }
3082
3083        res
3084    }
3085
3086    fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
3087        let reg_block = self.regs();
3088
3089        reg_block.int_clr().write(|w| {
3090            for interrupt in interrupts {
3091                match interrupt {
3092                    UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
3093                    UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
3094                    UartInterrupt::RxBreakDetected => w.brk_det().clear_bit_by_one(),
3095                    UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
3096                    UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
3097                };
3098            }
3099            w
3100        });
3101    }
3102
3103    fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
3104        config.validate()?;
3105        self.change_baud(config)?;
3106        self.change_data_bits(config.data_bits);
3107        self.change_parity(config.parity);
3108        self.change_stop_bits(config.stop_bits);
3109        self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
3110
3111        // Avoid glitch interrupts.
3112        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
3113
3114        Ok(())
3115    }
3116
3117    fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
3118        self.regs().int_ena().modify(|_, w| {
3119            for event in events {
3120                match event {
3121                    TxEvent::Done => w.tx_done().bit(enable),
3122                    TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
3123                };
3124            }
3125            w
3126        });
3127    }
3128
3129    fn tx_events(&self) -> EnumSet<TxEvent> {
3130        let pending_interrupts = self.regs().int_raw().read();
3131        let mut active_events = EnumSet::new();
3132
3133        if pending_interrupts.tx_done().bit_is_set() {
3134            active_events |= TxEvent::Done;
3135        }
3136        if pending_interrupts.txfifo_empty().bit_is_set() {
3137            active_events |= TxEvent::FiFoEmpty;
3138        }
3139
3140        active_events
3141    }
3142
3143    fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
3144        let events = events.into();
3145        self.regs().int_clr().write(|w| {
3146            for event in events {
3147                match event {
3148                    TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
3149                    TxEvent::Done => w.tx_done().clear_bit_by_one(),
3150                };
3151            }
3152            w
3153        });
3154    }
3155
3156    fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
3157        self.regs().int_ena().modify(|_, w| {
3158            for event in events {
3159                match event {
3160                    RxEvent::FifoFull => w.rxfifo_full().bit(enable),
3161                    RxEvent::BreakDetected => w.brk_det().bit(enable),
3162                    RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
3163
3164                    RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
3165                    RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
3166                    RxEvent::GlitchDetected => w.glitch_det().bit(enable),
3167                    RxEvent::FrameError => w.frm_err().bit(enable),
3168                    RxEvent::ParityError => w.parity_err().bit(enable),
3169                };
3170            }
3171            w
3172        });
3173    }
3174
3175    fn rx_events(&self) -> EnumSet<RxEvent> {
3176        let pending_interrupts = self.regs().int_raw().read();
3177        let mut active_events = EnumSet::new();
3178
3179        if pending_interrupts.rxfifo_full().bit_is_set() {
3180            active_events |= RxEvent::FifoFull;
3181        }
3182        if pending_interrupts.brk_det().bit_is_set() {
3183            active_events |= RxEvent::BreakDetected;
3184        }
3185        if pending_interrupts.at_cmd_char_det().bit_is_set() {
3186            active_events |= RxEvent::CmdCharDetected;
3187        }
3188        if pending_interrupts.rxfifo_ovf().bit_is_set() {
3189            active_events |= RxEvent::FifoOvf;
3190        }
3191        if pending_interrupts.rxfifo_tout().bit_is_set() {
3192            active_events |= RxEvent::FifoTout;
3193        }
3194        if pending_interrupts.glitch_det().bit_is_set() {
3195            active_events |= RxEvent::GlitchDetected;
3196        }
3197        if pending_interrupts.frm_err().bit_is_set() {
3198            active_events |= RxEvent::FrameError;
3199        }
3200        if pending_interrupts.parity_err().bit_is_set() {
3201            active_events |= RxEvent::ParityError;
3202        }
3203
3204        active_events
3205    }
3206
3207    fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
3208        let events = events.into();
3209        self.regs().int_clr().write(|w| {
3210            for event in events {
3211                match event {
3212                    RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
3213                    RxEvent::BreakDetected => w.brk_det().clear_bit_by_one(),
3214                    RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
3215
3216                    RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
3217                    RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
3218                    RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
3219                    RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
3220                    RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
3221                };
3222            }
3223            w
3224        });
3225    }
3226
3227    /// Configures the RX-FIFO threshold
3228    ///
3229    /// ## Errors
3230    ///
3231    /// [ConfigError::UnsupportedRxFifoThreshold] if the provided value exceeds
3232    /// [`Info::RX_FIFO_MAX_THRHD`].
3233    fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3234        if threshold > Self::RX_FIFO_MAX_THRHD {
3235            return Err(ConfigError::RxFifoThresholdNotSupported);
3236        }
3237
3238        self.regs()
3239            .conf1()
3240            .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
3241
3242        Ok(())
3243    }
3244
3245    /// Reads the RX-FIFO threshold
3246    #[allow(clippy::useless_conversion)]
3247    fn rx_fifo_full_threshold(&self) -> u16 {
3248        self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
3249    }
3250
3251    /// Configures the TX-FIFO threshold
3252    ///
3253    /// ## Errors
3254    ///
3255    /// [ConfigError::UnsupportedTxFifoThreshold] if the provided value exceeds
3256    /// [`Info::TX_FIFO_MAX_THRHD`].
3257    fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3258        if threshold > Self::TX_FIFO_MAX_THRHD {
3259            return Err(ConfigError::TxFifoThresholdNotSupported);
3260        }
3261
3262        self.regs()
3263            .conf1()
3264            .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3265
3266        Ok(())
3267    }
3268
3269    /// Configures the Receive Timeout detection setting
3270    ///
3271    /// ## Arguments
3272    ///
3273    /// `timeout` - the number of symbols ("bytes") to wait for before
3274    /// triggering a timeout. Pass None to disable the timeout.
3275    ///
3276    /// ## Errors
3277    ///
3278    /// [ConfigError::UnsupportedTimeout] if the provided value exceeds
3279    /// the maximum value for SOC:
3280    /// - `esp32`: Symbol size is fixed to 8, do not pass a value > **0x7F**.
3281    /// - `esp32c2`, `esp32c3`, `esp32c6`, `esp32h2`, esp32s2`, esp32s3`: The value you pass times
3282    ///   the symbol size must be <= **0x3FF**
3283    fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3284        cfg_if::cfg_if! {
3285            if #[cfg(esp32)] {
3286                const MAX_THRHD: u8 = 0x7F; // 7 bits
3287            } else {
3288                const MAX_THRHD: u16 = 0x3FF; // 10 bits
3289            }
3290        }
3291
3292        let register_block = self.regs();
3293
3294        if let Some(timeout) = timeout {
3295            // the esp32 counts directly in number of symbols (symbol len fixed to 8)
3296            #[cfg(esp32)]
3297            let timeout_reg = timeout;
3298            // all other count in bits, so we need to multiply by the symbol len.
3299            #[cfg(not(esp32))]
3300            let timeout_reg = timeout as u16 * _symbol_len as u16;
3301
3302            if timeout_reg > MAX_THRHD {
3303                return Err(ConfigError::TimeoutTooLong);
3304            }
3305
3306            cfg_if::cfg_if! {
3307                if #[cfg(esp32)] {
3308                    let reg_thrhd = register_block.conf1();
3309                } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3310                    let reg_thrhd = register_block.tout_conf();
3311                } else {
3312                    let reg_thrhd = register_block.mem_conf();
3313                }
3314            }
3315            reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3316        }
3317
3318        cfg_if::cfg_if! {
3319            if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3320                let reg_en = register_block.tout_conf();
3321            } else {
3322                let reg_en = register_block.conf1();
3323            }
3324        }
3325        reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3326
3327        self.sync_regs();
3328
3329        Ok(())
3330    }
3331
3332    fn sync_regs(&self) {
3333        sync_regs(self.regs());
3334    }
3335
3336    fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3337        ClockTree::with(|clocks| {
3338            let clock = self.clock_instance;
3339
3340            let source_config = ClockConfig::new(
3341                config.clock_source,
3342                #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3343                0,
3344            );
3345            let clk = clock.function_clock_config_frequency(clocks, source_config);
3346
3347            // The UART baud rate clock divider is, depending on the device, either a
3348            // 20.4 bit, or a 12.4 bit divider.
3349            const FRAC_BITS: u32 = const {
3350                let largest_divider: u32 =
3351                    property!("clock_tree.uart.baud_rate_generator.fractional").1;
3352                ::core::assert!((largest_divider + 1).is_power_of_two());
3353                largest_divider.count_ones()
3354            };
3355            const FRAC_MASK: u32 = (1 << FRAC_BITS) - 1;
3356
3357            // TODO: this block should only prepare the new clock config, and it should
3358            // be applied only after validating the resulting baud rate.
3359            cfg_if::cfg_if! {
3360                if #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] {
3361                    const MAX_DIV: u32 = property!("clock_tree.uart.baud_rate_generator.integral").1;
3362                    let clk_div = clk.div_ceil(MAX_DIV).div_ceil(config.baudrate);
3363                    debug!("SCLK: {} divider: {}", clk, clk_div);
3364
3365                    let conf = ClockConfig::new(config.clock_source, clk_div - 1);
3366                    let divider = (clk << FRAC_BITS) / (config.baudrate * clk_div);
3367                } else {
3368                    debug!("SCLK: {}", clk);
3369                    let conf = ClockConfig::new(config.clock_source);
3370                    let divider = (clk << FRAC_BITS) / config.baudrate;
3371                }
3372            }
3373
3374            let divider_integer = divider >> FRAC_BITS;
3375            let divider_frag = divider & FRAC_MASK;
3376            debug!(
3377                "UART CLK divider: {} + {}/16",
3378                divider_integer, divider_frag
3379            );
3380
3381            clock.configure_function_clock(clocks, conf);
3382            clock.configure_baud_rate_generator(
3383                clocks,
3384                BaudRateConfig::new(divider_frag, divider_integer),
3385            );
3386
3387            self.sync_regs();
3388
3389            #[cfg(feature = "unstable")]
3390            {
3391                let deviation_limit = match config.baudrate_tolerance {
3392                    BaudrateTolerance::Exact => 1, // Still allow a tiny deviation
3393                    BaudrateTolerance::ErrorPercent(percent) => percent as u32,
3394                    _ => return Ok(()),
3395                };
3396
3397                let actual_baud = clock.baud_rate_generator_frequency(clocks);
3398                if actual_baud == 0 {
3399                    return Err(ConfigError::BaudrateNotAchievable);
3400                }
3401
3402                let deviation = (config.baudrate.abs_diff(actual_baud) * 100) / actual_baud;
3403                debug!(
3404                    "Nominal baud: {}, actual: {}, deviation: {}%",
3405                    config.baudrate, actual_baud, deviation
3406                );
3407
3408                if deviation > deviation_limit {
3409                    return Err(ConfigError::BaudrateNotAchievable);
3410                }
3411            }
3412
3413            Ok(())
3414        })
3415    }
3416
3417    fn change_data_bits(&self, data_bits: DataBits) {
3418        self.regs()
3419            .conf0()
3420            .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3421    }
3422
3423    fn change_parity(&self, parity: Parity) {
3424        self.regs().conf0().modify(|_, w| match parity {
3425            Parity::None => w.parity_en().clear_bit(),
3426            Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3427            Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3428        });
3429    }
3430
3431    fn change_stop_bits(&self, stop_bits: StopBits) {
3432        #[cfg(esp32)]
3433        {
3434            // workaround for hardware issue, when UART stop bit set as 2-bit mode.
3435            if stop_bits == StopBits::_2 {
3436                self.regs()
3437                    .rs485_conf()
3438                    .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3439
3440                self.regs()
3441                    .conf0()
3442                    .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3443            }
3444        }
3445
3446        #[cfg(not(esp32))]
3447        self.regs()
3448            .conf0()
3449            .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3450    }
3451
3452    fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3453        // set SW flow control
3454        match sw_flow_ctrl {
3455            SwFlowControl::Enabled {
3456                xon_char,
3457                xoff_char,
3458                xon_threshold,
3459                xoff_threshold,
3460            } => {
3461                cfg_if::cfg_if! {
3462                    if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3463                        self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3464                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3465                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3466                    } else if #[cfg(esp32)]{
3467                        self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3468                        self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3469                        self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3470                    } else {
3471                        self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3472                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3473                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3474                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3475                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3476                    }
3477                }
3478            }
3479            SwFlowControl::Disabled => {
3480                cfg_if::cfg_if! {
3481                    if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3482                        let reg = self.regs().swfc_conf0();
3483                    } else {
3484                        let reg = self.regs().flow_conf();
3485                    }
3486                }
3487
3488                reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3489                reg.modify(|_, w| w.xonoff_del().clear_bit());
3490            }
3491        }
3492
3493        self.regs().conf0().modify(|_, w| {
3494            w.tx_flow_en()
3495                .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3496        });
3497
3498        match hw_flow_ctrl.rts {
3499            RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3500            RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3501        }
3502
3503        sync_regs(self.regs());
3504    }
3505
3506    fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3507        if let Some(threshold) = threshold {
3508            cfg_if::cfg_if! {
3509                if #[cfg(esp32)] {
3510                    self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3511                } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3512                    self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3513                } else {
3514                    self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3515                }
3516            }
3517        }
3518
3519        cfg_if::cfg_if! {
3520            if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3521                self.regs().hwfc_conf().modify(|_, w| {
3522                    w.rx_flow_en().bit(enable)
3523                });
3524            } else {
3525                self.regs().conf1().modify(|_, w| {
3526                    w.rx_flow_en().bit(enable)
3527                });
3528            }
3529        }
3530    }
3531
3532    fn rxfifo_reset(&self) {
3533        fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3534            reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3535            sync_regs(reg_block);
3536        }
3537
3538        rxfifo_rst(self.regs(), true);
3539        rxfifo_rst(self.regs(), false);
3540    }
3541
3542    fn txfifo_reset(&self) {
3543        fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3544            reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3545            sync_regs(reg_block);
3546        }
3547
3548        txfifo_rst(self.regs(), true);
3549        txfifo_rst(self.regs(), false);
3550    }
3551
3552    fn current_symbol_length(&self) -> u8 {
3553        let conf0 = self.regs().conf0().read();
3554        let data_bits = conf0.bit_num().bits() + 5; // 5 data bits are encoded as variant 0
3555        let parity = conf0.parity_en().bit() as u8;
3556        let mut stop_bits = conf0.stop_bit_num().bits();
3557
3558        match stop_bits {
3559            1 => {
3560                // workaround for hardware issue, when UART stop bit set as 2-bit mode.
3561                #[cfg(esp32)]
3562                if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3563                    stop_bits = 2;
3564                }
3565            }
3566            // esp-idf also counts 2 bits for settings 1.5 and 2 stop bits
3567            _ => stop_bits = 2,
3568        }
3569
3570        1 + data_bits + parity + stop_bits
3571    }
3572
3573    /// Reads one byte from the RX FIFO.
3574    ///
3575    /// If the FIFO is empty, the value of the returned byte is not specified.
3576    fn read_next_from_fifo(&self) -> u8 {
3577        fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3578            // https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/cpu-subsequent-access-halted-when-get-interrupted.html
3579            cfg_if::cfg_if! {
3580                if #[cfg(esp32)] {
3581                    crate::interrupt::free(f)
3582                } else {
3583                    f()
3584                }
3585            }
3586        }
3587
3588        let fifo_reg = self.regs().fifo();
3589        cfg_if::cfg_if! {
3590            if #[cfg(esp32s2)] {
3591                // On the ESP32-S2 we need to use PeriBus2 to read the FIFO:
3592                let fifo_reg = unsafe {
3593                    &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3594                };
3595            }
3596        }
3597
3598        access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3599    }
3600
3601    #[allow(clippy::useless_conversion)]
3602    fn tx_fifo_count(&self) -> u16 {
3603        u16::from(self.regs().status().read().txfifo_cnt().bits())
3604    }
3605
3606    fn write_byte(&self, byte: u8) {
3607        self.regs()
3608            .fifo()
3609            .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3610    }
3611
3612    fn check_for_errors(&self) -> Result<(), RxError> {
3613        let errors = RxEvent::FifoOvf
3614            | RxEvent::FifoTout
3615            | RxEvent::GlitchDetected
3616            | RxEvent::FrameError
3617            | RxEvent::ParityError;
3618        let events = self.rx_events().intersection(errors);
3619        let result = rx_event_check_for_error(events);
3620        if result.is_err() {
3621            self.clear_rx_events(errors);
3622            if events.contains(RxEvent::FifoOvf) {
3623                self.rxfifo_reset();
3624            }
3625        }
3626        result
3627    }
3628
3629    #[cfg(not(esp32))]
3630    #[allow(clippy::unnecessary_cast)]
3631    fn rx_fifo_count(&self) -> u16 {
3632        self.regs().status().read().rxfifo_cnt().bits() as u16
3633    }
3634
3635    #[cfg(esp32)]
3636    fn rx_fifo_count(&self) -> u16 {
3637        let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3638
3639        // Calculate the real count based on the FIFO read and write offset address:
3640        // https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/uart-fifo-cnt-indicates-data-length-incorrectly.html
3641        let status = self.regs().mem_rx_status().read();
3642        let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3643        let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3644
3645        if wr_addr > rd_addr {
3646            wr_addr - rd_addr
3647        } else if wr_addr < rd_addr {
3648            (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3649        } else if fifo_cnt > 0 {
3650            Info::UART_FIFO_SIZE
3651        } else {
3652            0
3653        }
3654    }
3655
3656    fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3657        if data.is_empty() {
3658            return Ok(0);
3659        }
3660
3661        while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3662
3663        let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3664        let to_write = space.min(data.len());
3665        for &byte in &data[..to_write] {
3666            self.write_byte(byte);
3667        }
3668
3669        Ok(to_write)
3670    }
3671
3672    fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3673        if buf.is_empty() {
3674            return Ok(0);
3675        }
3676
3677        while self.rx_fifo_count() == 0 {
3678            // Block until we received at least one byte
3679            self.check_for_errors()?;
3680        }
3681
3682        self.read_buffered(buf)
3683    }
3684
3685    fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3686        // Get the count first, to avoid accidentally reading a corrupted byte received
3687        // after the error check.
3688        let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3689        self.check_for_errors()?;
3690
3691        for byte_into in buf[..to_read].iter_mut() {
3692            *byte_into = self.read_next_from_fifo();
3693        }
3694
3695        // This bit is not cleared until the FIFO actually drops below the threshold.
3696        self.clear_rx_events(RxEvent::FifoFull);
3697
3698        Ok(to_read)
3699    }
3700}
3701
3702impl PartialEq for Info {
3703    fn eq(&self, other: &Self) -> bool {
3704        core::ptr::eq(self.register_block, other.register_block)
3705    }
3706}
3707
3708unsafe impl Sync for Info {}
3709
3710for_each_uart! {
3711    ($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3712        impl Instance for crate::peripherals::$inst<'_> {
3713            fn parts(&self) -> (&'static Info, &'static State) {
3714                #[handler]
3715                #[ram]
3716                pub(super) fn irq_handler() {
3717                    intr_handler(&PERIPHERAL, &STATE);
3718                }
3719
3720                static STATE: State = State {
3721                    tx_waker: AtomicWaker::new(),
3722                    rx_waker: AtomicWaker::new(),
3723                    is_rx_async: AtomicBool::new(false),
3724                    is_tx_async: AtomicBool::new(false),
3725                };
3726
3727                static PERIPHERAL: Info = Info {
3728                    register_block: crate::peripherals::$inst::ptr(),
3729                    peripheral: crate::system::Peripheral::$peri,
3730                    clock_instance: clocks::UartInstance::$peri,
3731                    async_handler: irq_handler,
3732                    tx_signal: OutputSignal::$txd,
3733                    rx_signal: InputSignal::$rxd,
3734                    cts_signal: InputSignal::$cts,
3735                    rts_signal: OutputSignal::$rts,
3736                };
3737                (&PERIPHERAL, &STATE)
3738            }
3739        }
3740    };
3741}
3742
3743crate::any_peripheral! {
3744    /// Any UART peripheral.
3745    pub peripheral AnyUart<'d> {
3746        #[cfg(soc_has_uart0)]
3747        Uart0(crate::peripherals::UART0<'d>),
3748        #[cfg(soc_has_uart1)]
3749        Uart1(crate::peripherals::UART1<'d>),
3750        #[cfg(soc_has_uart2)]
3751        Uart2(crate::peripherals::UART2<'d>),
3752    }
3753}
3754
3755impl Instance for AnyUart<'_> {
3756    #[inline]
3757    fn parts(&self) -> (&'static Info, &'static State) {
3758        any::delegate!(self, uart => { uart.parts() })
3759    }
3760}
3761
3762impl AnyUart<'_> {
3763    fn bind_peri_interrupt(&self, handler: InterruptHandler) {
3764        any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3765    }
3766
3767    fn disable_peri_interrupt_on_all_cores(&self) {
3768        any::delegate!(self, uart => { uart.disable_peri_interrupt_on_all_cores() })
3769    }
3770
3771    fn set_interrupt_handler(&self, handler: InterruptHandler) {
3772        self.disable_peri_interrupt_on_all_cores();
3773
3774        self.info().enable_listen(EnumSet::all(), false);
3775        self.info().clear_interrupts(EnumSet::all());
3776
3777        self.bind_peri_interrupt(handler);
3778    }
3779}
3780
3781struct UartClockGuard<'t> {
3782    uart: AnyUart<'t>,
3783}
3784
3785impl<'t> UartClockGuard<'t> {
3786    fn new(uart: AnyUart<'t>) -> Self {
3787        ClockTree::with(|clocks| {
3788            let clock = uart.info().clock_instance;
3789
3790            // Apply default SCLK configuration
3791            let sclk_config = ClockConfig::new(
3792                Default::default(),
3793                #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3794                0,
3795            );
3796            clock.configure_function_clock(clocks, sclk_config);
3797            clock.request_function_clock(clocks);
3798            clock.request_baud_rate_generator(clocks);
3799            #[cfg(soc_has_clock_node_uart_mem_clock)]
3800            clock.request_mem_clock(clocks);
3801        });
3802
3803        Self { uart }
3804    }
3805}
3806
3807impl Clone for UartClockGuard<'_> {
3808    fn clone(&self) -> Self {
3809        Self::new(unsafe { self.uart.clone_unchecked() })
3810    }
3811}
3812
3813impl Drop for UartClockGuard<'_> {
3814    fn drop(&mut self) {
3815        ClockTree::with(|clocks| {
3816            let clock = self.uart.info().clock_instance;
3817
3818            #[cfg(soc_has_clock_node_uart_mem_clock)]
3819            clock.release_mem_clock(clocks);
3820            clock.release_baud_rate_generator(clocks);
3821            clock.release_function_clock(clocks);
3822        });
3823    }
3824}