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        // loop to prevent returning 0 bytes
1082        while self.uart.info().rx_fifo_count() < minimum {
1083            // We're ignoring the user configuration here to ensure that this is not waiting
1084            // for more data than the buffer. We'll restore the original value after the
1085            // future resolved.
1086            let info = self.uart.info();
1087            unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
1088            let _guard = DropGuard::new((), |_| {
1089                unwrap!(info.set_rx_fifo_full_threshold(current_threshold));
1090            });
1091
1092            // Wait for space or event
1093            let mut events = RxEvent::FifoFull
1094                | RxEvent::FifoOvf
1095                | RxEvent::FrameError
1096                | RxEvent::GlitchDetected
1097                | RxEvent::ParityError;
1098
1099            if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1100                events |= RxEvent::CmdCharDetected;
1101            }
1102
1103            cfg_if::cfg_if! {
1104                if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
1105                    let reg_en = self.regs().tout_conf();
1106                } else {
1107                    let reg_en = self.regs().conf1();
1108                }
1109            };
1110            if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1111                events |= RxEvent::FifoTout;
1112            }
1113
1114            let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1115
1116            let result = rx_event_check_for_error(events);
1117            if let Err(error) = result {
1118                if error == RxError::FifoOverflowed {
1119                    self.uart.info().rxfifo_reset();
1120                }
1121                return Err(error);
1122            }
1123        }
1124
1125        Ok(())
1126    }
1127
1128    /// Read data asynchronously.
1129    ///
1130    /// This function reads data from the UART receive buffer into the
1131    /// provided buffer. If the buffer is empty, the function waits
1132    /// asynchronously for data to become available, or for an error to occur.
1133    ///
1134    /// The function returns the number of bytes read into the buffer. This may
1135    /// be less than the length of the buffer.
1136    ///
1137    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1138    /// to ensure that it does not wait for more data than the buffer can hold.
1139    ///
1140    /// Upon an error, the function returns immediately and the contents of the
1141    /// internal FIFO are not modified.
1142    ///
1143    /// ## Cancellation
1144    ///
1145    /// This function is cancellation safe.
1146    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1147        if buf.is_empty() {
1148            return Ok(0);
1149        }
1150
1151        self.wait_for_buffered_data(1, buf.len(), true).await?;
1152
1153        self.read_buffered(buf)
1154    }
1155
1156    /// Fill buffer asynchronously.
1157    ///
1158    /// This function reads data into the provided buffer. If the internal FIFO
1159    /// does not contain enough data, the function waits asynchronously for data
1160    /// to become available, or for an error to occur.
1161    ///
1162    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1163    /// to ensure that it does not wait for more data than the buffer can hold.
1164    ///
1165    /// ## Cancellation
1166    ///
1167    /// This function is **not** cancellation safe. If the future is dropped
1168    /// before it resolves, or if an error occurs during the read operation,
1169    /// previously read data may be lost.
1170    pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1171        if buf.is_empty() {
1172            return Ok(());
1173        }
1174
1175        // Drain the buffer first, there's no point in waiting for data we've already received.
1176        let read = self.uart.info().read_buffered(buf)?;
1177        buf = &mut buf[read..];
1178
1179        while !buf.is_empty() {
1180            // No point in listening for timeouts, as we're waiting for an exact amount of
1181            // data. On ESP32 and S2, the timeout interrupt can't be cleared unless the FIFO
1182            // is empty, so listening could cause an infinite loop here.
1183            self.wait_for_buffered_data(buf.len(), buf.len(), false)
1184                .await?;
1185
1186            let read = self.uart.info().read_buffered(buf)?;
1187            buf = &mut buf[read..];
1188        }
1189
1190        Ok(())
1191    }
1192
1193    /// Waits for a break condition to be detected asynchronously.
1194    ///
1195    /// This is an async function that will await until a break condition is
1196    /// detected on the RX line. After detection, the break interrupt flag is
1197    /// automatically cleared.
1198    #[instability::unstable]
1199    pub async fn wait_for_break_async(&mut self) {
1200        UartRxFuture::new(self.uart.reborrow(), RxEvent::BreakDetected).await;
1201        self.regs()
1202            .int_clr()
1203            .write(|w| w.brk_det().clear_bit_by_one());
1204    }
1205}
1206
1207impl<'d, Dm> UartRx<'d, Dm>
1208where
1209    Dm: DriverMode,
1210{
1211    fn regs(&self) -> &RegisterBlock {
1212        self.uart.info().regs()
1213    }
1214
1215    /// Assign the CTS pin for UART instance.
1216    ///
1217    /// Sets the specified pin to input and connects it to the UART CTS signal.
1218    #[instability::unstable]
1219    pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1220        let cts = cts.into();
1221
1222        cts.apply_input_config(&InputConfig::default());
1223        cts.set_input_enable(true);
1224
1225        self.uart.info().cts_signal.connect_to(&cts);
1226
1227        self
1228    }
1229
1230    /// Assign the RX pin for UART instance.
1231    ///
1232    /// Sets the specified pin to input and connects it to the UART RX signal.
1233    ///
1234    /// Note: when you listen for the output of the UART peripheral, you should
1235    /// configure the driver side (i.e. the TX pin), or ensure that the line is
1236    /// initially high, to avoid receiving a non-data byte caused by an
1237    /// initial low signal level.
1238    #[instability::unstable]
1239    pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1240        let rx = rx.into();
1241
1242        rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1243        rx.set_input_enable(true);
1244
1245        self.uart.info().rx_signal.connect_to(&rx);
1246
1247        self
1248    }
1249
1250    /// Enable break detection.
1251    ///
1252    /// This must be called before any breaks are expected to be received.
1253    /// Break detection is enabled automatically by [`Self::wait_for_break`]
1254    /// and [`Self::wait_for_break_with_timeout`], but calling this method
1255    /// explicitly ensures that breaks occurring before the first wait call
1256    /// will be reliably detected.
1257    #[instability::unstable]
1258    pub fn enable_break_detection(&mut self) {
1259        self.uart
1260            .info()
1261            .enable_listen_rx(RxEvent::BreakDetected.into(), true);
1262
1263        sync_regs(self.regs());
1264    }
1265
1266    /// Change the configuration.
1267    ///
1268    /// ## Errors
1269    ///
1270    /// This function returns a [`ConfigError`] if the configuration is not
1271    /// supported by the hardware.
1272    #[instability::unstable]
1273    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1274        self.uart
1275            .info()
1276            .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1277        self.uart
1278            .info()
1279            .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1280
1281        self.uart.info().rxfifo_reset();
1282        Ok(())
1283    }
1284
1285    /// Reads and clears errors set by received data.
1286    ///
1287    /// If a FIFO overflow is detected, the RX FIFO is reset.
1288    #[instability::unstable]
1289    pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1290        self.uart.info().check_for_errors()
1291    }
1292
1293    /// Returns whether the UART buffer has data.
1294    ///
1295    /// If this function returns `true`, [`Self::read`] will not block.
1296    #[instability::unstable]
1297    pub fn read_ready(&self) -> bool {
1298        self.uart.info().rx_fifo_count() > 0
1299    }
1300
1301    /// Read bytes.
1302    ///
1303    /// The UART hardware continuously receives bytes and stores them in the RX
1304    /// FIFO. This function reads the bytes from the RX FIFO and returns
1305    /// them in the provided buffer. If the hardware buffer is empty, this
1306    /// function will block until data is available. The [`Self::read_ready`]
1307    /// function can be used to check if data is available without blocking.
1308    ///
1309    /// The function returns the number of bytes read into the buffer. This may
1310    /// be less than the length of the buffer. This function only returns 0
1311    /// if the provided buffer is empty.
1312    ///
1313    /// ## Errors
1314    ///
1315    /// This function returns an [`RxError`] if an error occurred since the last
1316    /// call to [`Self::check_for_errors`], [`Self::read_buffered`], or this
1317    /// function.
1318    ///
1319    /// If the error occurred before this function was called, the contents of
1320    /// the FIFO are not modified.
1321    #[instability::unstable]
1322    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1323        self.uart.info().read(buf)
1324    }
1325
1326    /// Read already received bytes.
1327    ///
1328    /// This function reads the already received bytes from the FIFO into the
1329    /// provided buffer. The function does not wait for the FIFO to actually
1330    /// contain any bytes.
1331    ///
1332    /// The function returns the number of bytes read into the buffer. This may
1333    /// be less than the length of the buffer, and it may also be 0.
1334    ///
1335    /// ## Errors
1336    ///
1337    /// This function returns an [`RxError`] if an error occurred since the last
1338    /// call to [`Self::check_for_errors`], [`Self::read`], or this
1339    /// function.
1340    ///
1341    /// If the error occurred before this function was called, the contents of
1342    /// the FIFO are not modified.
1343    #[instability::unstable]
1344    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1345        self.uart.info().read_buffered(buf)
1346    }
1347
1348    /// Disables all RX-related interrupts for this UART instance.
1349    ///
1350    /// This function clears and disables the `receive FIFO full` interrupt,
1351    /// `receive FIFO overflow`, `receive FIFO timeout`, and `AT command
1352    /// byte detection` interrupts.
1353    fn disable_rx_interrupts(&self) {
1354        self.regs().int_clr().write(|w| {
1355            w.rxfifo_full().clear_bit_by_one();
1356            w.rxfifo_ovf().clear_bit_by_one();
1357            w.rxfifo_tout().clear_bit_by_one();
1358            w.at_cmd_char_det().clear_bit_by_one()
1359        });
1360
1361        self.regs().int_ena().write(|w| {
1362            w.rxfifo_full().clear_bit();
1363            w.rxfifo_ovf().clear_bit();
1364            w.rxfifo_tout().clear_bit();
1365            w.at_cmd_char_det().clear_bit()
1366        });
1367    }
1368}
1369
1370impl<'d> Uart<'d, Blocking> {
1371    #[procmacros::doc_replace]
1372    /// Create a new UART instance in [`Blocking`] mode.
1373    ///
1374    /// ## Errors
1375    ///
1376    /// This function returns a [`ConfigError`] if the configuration is not
1377    /// supported by the hardware.
1378    ///
1379    /// ## Example
1380    ///
1381    /// ```rust, no_run
1382    /// # {before_snippet}
1383    /// use esp_hal::uart::{Config, Uart};
1384    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1385    ///     .with_rx(peripherals.GPIO1)
1386    ///     .with_tx(peripherals.GPIO2);
1387    /// # {after_snippet}
1388    /// ```
1389    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1390        UartBuilder::new(uart).init(config)
1391    }
1392
1393    /// Reconfigures the driver to operate in [`Async`] mode.
1394    ///
1395    /// See the [`Async`] documentation for an example on how to use this
1396    /// method.
1397    pub fn into_async(self) -> Uart<'d, Async> {
1398        Uart {
1399            rx: self.rx.into_async(),
1400            tx: self.tx.into_async(),
1401        }
1402    }
1403
1404    #[cfg_attr(
1405        not(multi_core),
1406        doc = "Registers an interrupt handler for the peripheral."
1407    )]
1408    #[cfg_attr(
1409        multi_core,
1410        doc = "Registers an interrupt handler for the peripheral on the current core."
1411    )]
1412    #[doc = ""]
1413    /// Note that this will replace any previously registered interrupt
1414    /// handlers.
1415    ///
1416    /// You can restore the default/unhandled interrupt handler by using
1417    /// [crate::interrupt::DEFAULT_INTERRUPT_HANDLER]
1418    #[instability::unstable]
1419    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1420        // `self.tx.uart` and `self.rx.uart` are the same
1421        self.tx.uart.set_interrupt_handler(handler);
1422    }
1423
1424    #[procmacros::doc_replace]
1425    /// Listen for the given interrupts
1426    ///
1427    /// ## Example
1428    ///
1429    /// **Note**: In practice a proper serial terminal should be used
1430    /// to connect to the board (espflash won't work)
1431    ///
1432    /// ```rust, no_run
1433    /// # {before_snippet}
1434    /// use esp_hal::{
1435    ///     delay::Delay,
1436    ///     uart::{AtCmdConfig, Config, RxConfig, Uart, UartInterrupt},
1437    /// };
1438    /// # let delay = Delay::new();
1439    /// # let config = Config::default().with_rx(
1440    /// #    RxConfig::default().with_fifo_full_threshold(30)
1441    /// # );
1442    /// # let mut uart = Uart::new(
1443    /// #    peripherals.UART0,
1444    /// #    config)?;
1445    /// uart.set_interrupt_handler(interrupt_handler);
1446    ///
1447    /// critical_section::with(|cs| {
1448    ///     uart.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
1449    ///     uart.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1450    ///
1451    ///     SERIAL.borrow_ref_mut(cs).replace(uart);
1452    /// });
1453    ///
1454    /// loop {
1455    ///     println!("Send `#` character or >=30 characters");
1456    ///     delay.delay(Duration::from_secs(1));
1457    /// }
1458    /// # }
1459    ///
1460    /// use core::cell::RefCell;
1461    ///
1462    /// use critical_section::Mutex;
1463    /// use esp_hal::uart::Uart;
1464    /// static SERIAL: Mutex<RefCell<Option<Uart<esp_hal::Blocking>>>> = Mutex::new(RefCell::new(None));
1465    ///
1466    /// use core::fmt::Write;
1467    ///
1468    /// use esp_hal::uart::UartInterrupt;
1469    /// #[esp_hal::handler]
1470    /// fn interrupt_handler() {
1471    ///     critical_section::with(|cs| {
1472    ///         let mut serial = SERIAL.borrow_ref_mut(cs);
1473    ///         if let Some(serial) = serial.as_mut() {
1474    ///             let mut buf = [0u8; 64];
1475    ///             if let Ok(cnt) = serial.read_buffered(&mut buf) {
1476    ///                 println!("Read {} bytes", cnt);
1477    ///             }
1478    ///
1479    ///             let pending_interrupts = serial.interrupts();
1480    ///             println!(
1481    ///                 "Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
1482    ///                 pending_interrupts.contains(UartInterrupt::AtCmd),
1483    ///                 pending_interrupts.contains(UartInterrupt::RxFifoFull),
1484    ///             );
1485    ///
1486    ///             serial.clear_interrupts(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1487    ///         }
1488    ///     });
1489    /// }
1490    /// ```
1491    #[instability::unstable]
1492    pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1493        self.tx.uart.info().enable_listen(interrupts.into(), true)
1494    }
1495
1496    /// Unlisten the given interrupts
1497    #[instability::unstable]
1498    pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1499        self.tx.uart.info().enable_listen(interrupts.into(), false)
1500    }
1501
1502    /// Gets asserted interrupts
1503    #[instability::unstable]
1504    pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1505        self.tx.uart.info().interrupts()
1506    }
1507
1508    /// Resets asserted interrupts
1509    #[instability::unstable]
1510    pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1511        self.tx.uart.info().clear_interrupts(interrupts)
1512    }
1513
1514    /// Waits for a break condition to be detected.
1515    ///
1516    /// This is a blocking function that will continuously check for a break condition.
1517    /// After detection, the break interrupt flag is automatically cleared.
1518    #[instability::unstable]
1519    pub fn wait_for_break(&mut self) {
1520        self.rx.wait_for_break()
1521    }
1522
1523    /// Waits for a break condition to be detected with a timeout.
1524    ///
1525    /// This is a blocking function that will check for a break condition up to
1526    /// the specified timeout. Returns `true` if a break was detected, `false` if
1527    /// the timeout elapsed. After successful detection, the break interrupt flag
1528    /// is automatically cleared.
1529    ///
1530    /// ## Arguments
1531    /// * `timeout` - Maximum time to wait for a break condition
1532    #[instability::unstable]
1533    pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1534        self.rx.wait_for_break_with_timeout(timeout)
1535    }
1536}
1537
1538impl<'d> Uart<'d, Async> {
1539    /// Reconfigures the driver to operate in [`Blocking`] mode.
1540    ///
1541    /// See the [`Blocking`] documentation for an example on how to use this
1542    /// method.
1543    pub fn into_blocking(self) -> Uart<'d, Blocking> {
1544        Uart {
1545            rx: self.rx.into_blocking(),
1546            tx: self.tx.into_blocking(),
1547        }
1548    }
1549
1550    #[procmacros::doc_replace]
1551    /// Write data into the TX buffer.
1552    ///
1553    /// This function writes the provided buffer `bytes` into the UART transmit
1554    /// buffer. If the buffer is full, the function waits asynchronously for
1555    /// space in the buffer to become available.
1556    ///
1557    /// The function returns the number of bytes written into the buffer. This
1558    /// may be less than the length of the buffer.
1559    ///
1560    /// Upon an error, the function returns immediately and the contents of the
1561    /// internal FIFO are not modified.
1562    ///
1563    /// ## Cancellation
1564    ///
1565    /// This function is cancellation safe.
1566    ///
1567    /// ## Example
1568    ///
1569    /// ```rust, no_run
1570    /// # {before_snippet}
1571    /// use esp_hal::uart::{Config, Uart};
1572    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1573    ///     .with_rx(peripherals.GPIO1)
1574    ///     .with_tx(peripherals.GPIO2)
1575    ///     .into_async();
1576    ///
1577    /// const MESSAGE: &[u8] = b"Hello, world!";
1578    /// uart.write_async(&MESSAGE).await?;
1579    /// # {after_snippet}
1580    /// ```
1581    pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1582        self.tx.write_async(words).await
1583    }
1584
1585    #[procmacros::doc_replace]
1586    /// Asynchronously flushes the UART transmit buffer.
1587    ///
1588    /// This function ensures that all pending data in the transmit FIFO has
1589    /// been sent over the UART. If the FIFO contains data, it waits for the
1590    /// transmission to complete before returning.
1591    ///
1592    /// ## Cancellation
1593    ///
1594    /// This function is cancellation safe.
1595    ///
1596    /// ## Example
1597    ///
1598    /// ```rust, no_run
1599    /// # {before_snippet}
1600    /// use esp_hal::uart::{Config, Uart};
1601    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1602    ///     .with_rx(peripherals.GPIO1)
1603    ///     .with_tx(peripherals.GPIO2)
1604    ///     .into_async();
1605    ///
1606    /// const MESSAGE: &[u8] = b"Hello, world!";
1607    /// uart.write_async(&MESSAGE).await?;
1608    /// uart.flush_async().await?;
1609    /// # {after_snippet}
1610    /// ```
1611    pub async fn flush_async(&mut self) -> Result<(), TxError> {
1612        self.tx.flush_async().await
1613    }
1614
1615    #[procmacros::doc_replace]
1616    /// Read data asynchronously.
1617    ///
1618    /// This function reads data from the UART receive buffer into the
1619    /// provided buffer. If the buffer is empty, the function waits
1620    /// asynchronously for data to become available, or for an error to occur.
1621    ///
1622    /// The function returns the number of bytes read into the buffer. This may
1623    /// be less than the length of the buffer.
1624    ///
1625    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1626    /// to ensure that it does not wait for more data than the buffer can hold.
1627    ///
1628    /// Upon an error, the function returns immediately and the contents of the
1629    /// internal FIFO are not modified.
1630    ///
1631    /// ## Cancellation
1632    ///
1633    /// This function is cancellation safe.
1634    ///
1635    /// ## Example
1636    ///
1637    /// ```rust, no_run
1638    /// # {before_snippet}
1639    /// use esp_hal::uart::{Config, Uart};
1640    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1641    ///     .with_rx(peripherals.GPIO1)
1642    ///     .with_tx(peripherals.GPIO2)
1643    ///     .into_async();
1644    ///
1645    /// const MESSAGE: &[u8] = b"Hello, world!";
1646    /// uart.write_async(&MESSAGE).await?;
1647    /// uart.flush_async().await?;
1648    ///
1649    /// let mut buf = [0u8; MESSAGE.len()];
1650    /// uart.read_async(&mut buf[..]).await.unwrap();
1651    /// # {after_snippet}
1652    /// ```
1653    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1654        self.rx.read_async(buf).await
1655    }
1656
1657    /// Fill buffer asynchronously.
1658    ///
1659    /// This function reads data from the UART receive buffer into the
1660    /// provided buffer. If the buffer is empty, the function waits
1661    /// asynchronously for data to become available, or for an error to occur.
1662    ///
1663    /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1664    /// to ensure that it does not wait for more data than the buffer can hold.
1665    ///
1666    /// ## Cancellation
1667    ///
1668    /// This function is **not** cancellation safe. If the future is dropped
1669    /// before it resolves, or if an error occurs during the read operation,
1670    /// previously read data may be lost.
1671    #[instability::unstable]
1672    pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1673        self.rx.read_exact_async(buf).await
1674    }
1675
1676    /// Waits for a break condition to be detected asynchronously.
1677    ///
1678    /// This is an async function that will await until a break condition is
1679    /// detected on the RX line. After detection, the break interrupt flag is
1680    /// automatically cleared.
1681    #[instability::unstable]
1682    pub async fn wait_for_break_async(&mut self) {
1683        self.rx.wait_for_break_async().await
1684    }
1685}
1686
1687/// List of exposed UART events.
1688#[derive(Debug, EnumSetType)]
1689#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1690#[non_exhaustive]
1691#[instability::unstable]
1692pub enum UartInterrupt {
1693    /// Indicates that the received has detected the configured
1694    /// [`Uart::set_at_cmd`] byte.
1695    AtCmd,
1696
1697    /// The transmitter has finished sending out all data from the FIFO.
1698    TxDone,
1699
1700    /// Break condition has been detected.
1701    /// Triggered when the receiver detects a NULL character (i.e. logic 0 for
1702    /// one NULL character transmission) after stop bits.
1703    RxBreakDetected,
1704
1705    /// The receiver has received more data than what
1706    /// [`RxConfig::fifo_full_threshold`] specifies.
1707    RxFifoFull,
1708
1709    /// The receiver has not received any data for the time
1710    /// [`RxConfig::with_timeout`] specifies.
1711    RxTimeout,
1712}
1713
1714impl<'d, Dm> Uart<'d, Dm>
1715where
1716    Dm: DriverMode,
1717{
1718    #[procmacros::doc_replace]
1719    /// Assign the RX pin for UART instance.
1720    ///
1721    /// Sets the specified pin to input and connects it to the UART RX signal.
1722    ///
1723    /// Note: when you listen for the output of the UART peripheral, you should
1724    /// configure the driver side (i.e. the TX pin), or ensure that the line is
1725    /// initially high, to avoid receiving a non-data byte caused by an
1726    /// initial low signal level.
1727    ///
1728    /// ## Example
1729    ///
1730    /// ```rust, no_run
1731    /// # {before_snippet}
1732    /// use esp_hal::uart::{Config, Uart};
1733    /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO1);
1734    ///
1735    /// # {after_snippet}
1736    /// ```
1737    pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1738        self.rx = self.rx.with_rx(rx);
1739        self
1740    }
1741
1742    #[procmacros::doc_replace]
1743    /// Assign the TX pin for UART instance.
1744    ///
1745    /// Sets the specified pin to push-pull output and connects it to the UART
1746    /// TX signal.
1747    ///
1748    /// ## Example
1749    ///
1750    /// ```rust, no_run
1751    /// # {before_snippet}
1752    /// use esp_hal::uart::{Config, Uart};
1753    /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO2);
1754    ///
1755    /// # {after_snippet}
1756    /// ```
1757    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1758        self.tx = self.tx.with_tx(tx);
1759        self
1760    }
1761
1762    #[procmacros::doc_replace]
1763    /// Configure CTS pin
1764    ///
1765    /// ## Example
1766    ///
1767    /// ```rust, no_run
1768    /// # {before_snippet}
1769    /// use esp_hal::uart::{Config, Uart};
1770    /// let uart = Uart::new(peripherals.UART0, Config::default())?
1771    ///     .with_rx(peripherals.GPIO1)
1772    ///     .with_cts(peripherals.GPIO3);
1773    ///
1774    /// # {after_snippet}
1775    /// ```
1776    pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1777        self.rx = self.rx.with_cts(cts);
1778        self
1779    }
1780
1781    #[procmacros::doc_replace]
1782    /// Configure RTS pin
1783    ///
1784    /// ## Example
1785    ///
1786    /// ```rust, no_run
1787    /// # {before_snippet}
1788    /// use esp_hal::uart::{Config, Uart};
1789    /// let uart = Uart::new(peripherals.UART0, Config::default())?
1790    ///     .with_tx(peripherals.GPIO2)
1791    ///     .with_rts(peripherals.GPIO3);
1792    ///
1793    /// # {after_snippet}
1794    /// ```
1795    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1796        self.tx = self.tx.with_rts(rts);
1797        self
1798    }
1799
1800    fn regs(&self) -> &RegisterBlock {
1801        // `self.tx.uart` and `self.rx.uart` are the same
1802        self.tx.uart.info().regs()
1803    }
1804
1805    #[procmacros::doc_replace]
1806    /// Returns whether the UART TX buffer is ready to accept more data.
1807    ///
1808    /// If this function returns `true`, [`Self::write`] and [`Self::write_async`]
1809    /// will not block. Otherwise, the functions will not return until the buffer is
1810    /// ready.
1811    ///
1812    /// ## Example
1813    ///
1814    /// ```rust, no_run
1815    /// # {before_snippet}
1816    /// use esp_hal::uart::{Config, Uart};
1817    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1818    ///
1819    /// if uart.write_ready() {
1820    ///     // Because write_ready has returned true, the following call will immediately
1821    ///     // copy some bytes into the FIFO and return a non-zero value.
1822    ///     let written = uart.write(b"Hello")?;
1823    ///     // ... handle written bytes
1824    /// } else {
1825    ///     // Calling write would have blocked, but here we can do something useful
1826    ///     // instead of waiting for the buffer to become ready.
1827    /// }
1828    /// # {after_snippet}
1829    /// ```
1830    pub fn write_ready(&self) -> bool {
1831        self.tx.write_ready()
1832    }
1833
1834    #[procmacros::doc_replace]
1835    /// Writes bytes.
1836    ///
1837    /// This function writes data to the internal TX FIFO of the UART
1838    /// peripheral. The data is then transmitted over the UART TX line.
1839    ///
1840    /// The function returns the number of bytes written to the FIFO. This may
1841    /// be less than the length of the provided data. The function may only
1842    /// return 0 if the provided data is empty.
1843    ///
1844    /// ## Errors
1845    ///
1846    /// This function returns a [`TxError`] if an error occurred during the
1847    /// write operation.
1848    ///
1849    /// ## Example
1850    ///
1851    /// ```rust, no_run
1852    /// # {before_snippet}
1853    /// use esp_hal::uart::{Config, Uart};
1854    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1855    ///
1856    /// const MESSAGE: &[u8] = b"Hello, world!";
1857    /// uart.write(&MESSAGE)?;
1858    /// # {after_snippet}
1859    /// ```
1860    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1861        self.tx.write(data)
1862    }
1863
1864    #[procmacros::doc_replace]
1865    /// Flush the transmit buffer of the UART
1866    ///
1867    /// ## Example
1868    ///
1869    /// ```rust, no_run
1870    /// # {before_snippet}
1871    /// use esp_hal::uart::{Config, Uart};
1872    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1873    ///
1874    /// const MESSAGE: &[u8] = b"Hello, world!";
1875    /// uart.write(&MESSAGE)?;
1876    /// uart.flush()?;
1877    /// # {after_snippet}
1878    /// ```
1879    pub fn flush(&mut self) -> Result<(), TxError> {
1880        self.tx.flush()
1881    }
1882
1883    /// Sends a break signal for a specified duration
1884    #[instability::unstable]
1885    pub fn send_break(&mut self, bits: u32) {
1886        self.tx.send_break(bits)
1887    }
1888
1889    #[procmacros::doc_replace]
1890    /// Returns whether the UART receive buffer has at least one byte of data.
1891    ///
1892    /// If this function returns `true`, [`Self::read`] and [`Self::read_async`]
1893    /// will not block. Otherwise, they will not return until data is available.
1894    ///
1895    /// Data that does not get stored due to an error will be lost and does not count
1896    /// towards the number of bytes in the receive buffer.
1897    // TODO: once we add support for UART_ERR_WR_MASK it needs to be documented here.
1898    /// ## Example
1899    ///
1900    /// ```rust, no_run
1901    /// # {before_snippet}
1902    /// use esp_hal::uart::{Config, Uart};
1903    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1904    ///
1905    /// while !uart.read_ready() {
1906    ///     // Do something else while waiting for data to be available.
1907    /// }
1908    ///
1909    /// let mut buf = [0u8; 32];
1910    /// uart.read(&mut buf[..])?;
1911    ///
1912    /// # {after_snippet}
1913    /// ```
1914    pub fn read_ready(&self) -> bool {
1915        self.rx.read_ready()
1916    }
1917
1918    #[procmacros::doc_replace]
1919    /// Read received bytes.
1920    ///
1921    /// The UART hardware continuously receives bytes and stores them in the RX
1922    /// FIFO. This function reads the bytes from the RX FIFO and returns
1923    /// them in the provided buffer. If the hardware buffer is empty, this
1924    /// function will block until data is available. The [`Self::read_ready`]
1925    /// function can be used to check if data is available without blocking.
1926    ///
1927    /// The function returns the number of bytes read into the buffer. This may
1928    /// be less than the length of the buffer. This function only returns 0
1929    /// if the provided buffer is empty.
1930    ///
1931    /// ## Errors
1932    ///
1933    /// This function returns an [`RxError`] if an error occurred since the last
1934    /// check for errors.
1935    ///
1936    /// If the error occurred before this function was called, the contents of
1937    /// the FIFO are not modified.
1938    ///
1939    /// ## Example
1940    ///
1941    /// ```rust, no_run
1942    /// # {before_snippet}
1943    /// use esp_hal::uart::{Config, Uart};
1944    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1945    ///
1946    /// const MESSAGE: &[u8] = b"Hello, world!";
1947    /// uart.write(&MESSAGE)?;
1948    /// uart.flush()?;
1949    ///
1950    /// let mut buf = [0u8; MESSAGE.len()];
1951    /// uart.read(&mut buf[..])?;
1952    ///
1953    /// # {after_snippet}
1954    /// ```
1955    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1956        self.rx.read(buf)
1957    }
1958
1959    #[procmacros::doc_replace]
1960    /// Change the configuration.
1961    ///
1962    /// ## Errors
1963    ///
1964    /// This function returns a [`ConfigError`] if the configuration is not
1965    /// supported by the hardware.
1966    ///
1967    /// ## Example
1968    ///
1969    /// ```rust, no_run
1970    /// # {before_snippet}
1971    /// use esp_hal::uart::{Config, Uart};
1972    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
1973    ///
1974    /// uart.apply_config(&Config::default().with_baudrate(19_200))?;
1975    /// # {after_snippet}
1976    /// ```
1977    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1978        // Must apply the common settings first, as `rx.apply_config` reads back symbol
1979        // size.
1980        self.rx.uart.info().apply_config(config)?;
1981
1982        self.rx.apply_config(config)?;
1983        self.tx.apply_config(config)?;
1984        Ok(())
1985    }
1986
1987    #[procmacros::doc_replace]
1988    /// Split the UART into a transmitter and receiver
1989    ///
1990    /// This is particularly useful when having two tasks correlating to
1991    /// transmitting and receiving.
1992    ///
1993    /// ## Example
1994    ///
1995    /// ```rust, no_run
1996    /// # {before_snippet}
1997    /// use esp_hal::uart::{Config, Uart};
1998    /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1999    ///     .with_rx(peripherals.GPIO1)
2000    ///     .with_tx(peripherals.GPIO2);
2001    ///
2002    /// // The UART can be split into separate Transmit and Receive components:
2003    /// let (mut rx, mut tx) = uart.split();
2004    ///
2005    /// // Each component can be used individually to interact with the UART:
2006    /// tx.write(&[42u8])?;
2007    /// let mut byte = [0u8; 1];
2008    /// rx.read(&mut byte);
2009    /// # {after_snippet}
2010    /// ```
2011    #[instability::unstable]
2012    pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
2013        (self.rx, self.tx)
2014    }
2015
2016    /// Reads and clears errors set by received data.
2017    #[instability::unstable]
2018    pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
2019        self.rx.check_for_errors()
2020    }
2021
2022    /// Read already received bytes.
2023    ///
2024    /// This function reads the already received bytes from the FIFO into the
2025    /// provided buffer. The function does not wait for the FIFO to actually
2026    /// contain any bytes.
2027    ///
2028    /// The function returns the number of bytes read into the buffer. This may
2029    /// be less than the length of the buffer, and it may also be 0.
2030    ///
2031    /// ## Errors
2032    ///
2033    /// This function returns an [`RxError`] if an error occurred since the last
2034    /// check for errors.
2035    ///
2036    /// If the error occurred before this function was called, the contents of
2037    /// the FIFO are not modified.
2038    #[instability::unstable]
2039    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2040        self.rx.read_buffered(buf)
2041    }
2042
2043    /// Configures the AT-CMD detection settings
2044    #[instability::unstable]
2045    pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
2046        #[cfg(not(any(esp32, esp32s2)))]
2047        self.regs()
2048            .clk_conf()
2049            .modify(|_, w| w.sclk_en().clear_bit());
2050
2051        self.regs().at_cmd_char().write(|w| unsafe {
2052            w.at_cmd_char().bits(config.cmd_char);
2053            w.char_num().bits(config.char_num)
2054        });
2055
2056        if let Some(pre_idle_count) = config.pre_idle_count {
2057            self.regs()
2058                .at_cmd_precnt()
2059                .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
2060        }
2061
2062        if let Some(post_idle_count) = config.post_idle_count {
2063            self.regs()
2064                .at_cmd_postcnt()
2065                .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
2066        }
2067
2068        if let Some(gap_timeout) = config.gap_timeout {
2069            self.regs()
2070                .at_cmd_gaptout()
2071                .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
2072        }
2073
2074        #[cfg(not(any(esp32, esp32s2)))]
2075        self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
2076
2077        sync_regs(self.regs());
2078    }
2079
2080    #[inline(always)]
2081    fn init(&mut self, config: Config) -> Result<(), ConfigError> {
2082        self.rx.disable_rx_interrupts();
2083        self.tx.disable_tx_interrupts();
2084
2085        // Reset Tx/Rx FIFOs
2086        self.rx.uart.info().rxfifo_reset();
2087        self.rx.uart.info().txfifo_reset();
2088
2089        self.apply_config(&config)?;
2090
2091        // Don't wait after transmissions by default,
2092        // so that bytes written to TX FIFO are always immediately transmitted.
2093        self.regs()
2094            .idle_conf()
2095            .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2096
2097        // Setting err_wr_mask stops uart from storing data when data is wrong according
2098        // to reference manual
2099        self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
2100
2101        crate::rom::ets_delay_us(15);
2102
2103        // Make sure we are starting in a "clean state" - previous operations might have
2104        // run into error conditions
2105        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
2106
2107        Ok(())
2108    }
2109}
2110
2111impl crate::private::Sealed for Uart<'_, Blocking> {}
2112
2113#[instability::unstable]
2114impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
2115    fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
2116        // `self.tx.uart` and `self.rx.uart` are the same
2117        self.tx.uart.set_interrupt_handler(handler);
2118    }
2119}
2120
2121#[instability::unstable]
2122impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
2123where
2124    Dm: DriverMode,
2125{
2126    type Error = TxError;
2127
2128    #[inline]
2129    fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2130        self.tx.write_str(s)
2131    }
2132
2133    #[inline]
2134    fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
2135        self.tx.write_char(ch)
2136    }
2137}
2138
2139#[instability::unstable]
2140impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
2141where
2142    Dm: DriverMode,
2143{
2144    type Error = TxError;
2145
2146    #[inline]
2147    fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
2148        self.write_all(s.as_bytes())
2149    }
2150}
2151
2152impl<Dm> core::fmt::Write for Uart<'_, Dm>
2153where
2154    Dm: DriverMode,
2155{
2156    #[inline]
2157    fn write_str(&mut self, s: &str) -> core::fmt::Result {
2158        self.tx.write_str(s)
2159    }
2160}
2161
2162impl<Dm> core::fmt::Write for UartTx<'_, Dm>
2163where
2164    Dm: DriverMode,
2165{
2166    #[inline]
2167    fn write_str(&mut self, s: &str) -> core::fmt::Result {
2168        self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
2169    }
2170}
2171
2172/// UART Tx or Rx Error
2173#[instability::unstable]
2174#[derive(Debug, Clone, Copy, PartialEq)]
2175#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2176#[non_exhaustive]
2177pub enum IoError {
2178    /// UART TX error
2179    Tx(TxError),
2180    /// UART RX error
2181    Rx(RxError),
2182}
2183
2184#[instability::unstable]
2185impl core::error::Error for IoError {}
2186
2187#[instability::unstable]
2188impl core::fmt::Display for IoError {
2189    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2190        match self {
2191            IoError::Tx(e) => e.fmt(f),
2192            IoError::Rx(e) => e.fmt(f),
2193        }
2194    }
2195}
2196
2197#[instability::unstable]
2198impl embedded_io_06::Error for IoError {
2199    fn kind(&self) -> embedded_io_06::ErrorKind {
2200        embedded_io_06::ErrorKind::Other
2201    }
2202}
2203
2204#[instability::unstable]
2205impl embedded_io_07::Error for IoError {
2206    fn kind(&self) -> embedded_io_07::ErrorKind {
2207        embedded_io_07::ErrorKind::Other
2208    }
2209}
2210
2211#[instability::unstable]
2212impl From<RxError> for IoError {
2213    fn from(e: RxError) -> Self {
2214        IoError::Rx(e)
2215    }
2216}
2217
2218#[instability::unstable]
2219impl From<TxError> for IoError {
2220    fn from(e: TxError) -> Self {
2221        IoError::Tx(e)
2222    }
2223}
2224
2225#[instability::unstable]
2226impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2227    type Error = IoError;
2228}
2229
2230#[instability::unstable]
2231impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2232    type Error = TxError;
2233}
2234
2235#[instability::unstable]
2236impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2237    type Error = RxError;
2238}
2239
2240#[instability::unstable]
2241impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2242where
2243    Dm: DriverMode,
2244{
2245    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2246        self.rx.read(buf).map_err(IoError::Rx)
2247    }
2248}
2249
2250#[instability::unstable]
2251impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2252where
2253    Dm: DriverMode,
2254{
2255    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2256        self.read(buf)
2257    }
2258}
2259
2260#[instability::unstable]
2261impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2262where
2263    Dm: DriverMode,
2264{
2265    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2266        Ok(self.rx.read_ready())
2267    }
2268}
2269
2270#[instability::unstable]
2271impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2272where
2273    Dm: DriverMode,
2274{
2275    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2276        Ok(UartRx::read_ready(self))
2277    }
2278}
2279
2280#[instability::unstable]
2281impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2282where
2283    Dm: DriverMode,
2284{
2285    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2286        self.tx.write(buf).map_err(IoError::Tx)
2287    }
2288
2289    fn flush(&mut self) -> Result<(), Self::Error> {
2290        self.tx.flush().map_err(IoError::Tx)
2291    }
2292}
2293
2294#[instability::unstable]
2295impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2296where
2297    Dm: DriverMode,
2298{
2299    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2300        self.write(buf)
2301    }
2302
2303    fn flush(&mut self) -> Result<(), Self::Error> {
2304        self.flush()
2305    }
2306}
2307
2308#[instability::unstable]
2309impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2310where
2311    Dm: DriverMode,
2312{
2313    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2314        Ok(UartTx::write_ready(self))
2315    }
2316}
2317
2318#[instability::unstable]
2319impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2320where
2321    Dm: DriverMode,
2322{
2323    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2324        Ok(self.tx.write_ready())
2325    }
2326}
2327
2328#[instability::unstable]
2329impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2330    type Error = IoError;
2331}
2332
2333#[instability::unstable]
2334impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2335    type Error = TxError;
2336}
2337
2338#[instability::unstable]
2339impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2340    type Error = RxError;
2341}
2342
2343#[instability::unstable]
2344impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2345where
2346    Dm: DriverMode,
2347{
2348    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2349        self.rx.read(buf).map_err(IoError::Rx)
2350    }
2351}
2352
2353#[instability::unstable]
2354impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2355where
2356    Dm: DriverMode,
2357{
2358    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2359        self.read(buf)
2360    }
2361}
2362
2363#[instability::unstable]
2364impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2365where
2366    Dm: DriverMode,
2367{
2368    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2369        Ok(self.rx.read_ready())
2370    }
2371}
2372
2373#[instability::unstable]
2374impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2375where
2376    Dm: DriverMode,
2377{
2378    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2379        Ok(UartRx::read_ready(self))
2380    }
2381}
2382
2383#[instability::unstable]
2384impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2385where
2386    Dm: DriverMode,
2387{
2388    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2389        self.tx.write(buf).map_err(IoError::Tx)
2390    }
2391
2392    fn flush(&mut self) -> Result<(), Self::Error> {
2393        self.tx.flush().map_err(IoError::Tx)
2394    }
2395}
2396
2397#[instability::unstable]
2398impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2399where
2400    Dm: DriverMode,
2401{
2402    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2403        self.write(buf)
2404    }
2405
2406    fn flush(&mut self) -> Result<(), Self::Error> {
2407        self.flush()
2408    }
2409}
2410
2411#[instability::unstable]
2412impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2413where
2414    Dm: DriverMode,
2415{
2416    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2417        Ok(UartTx::write_ready(self))
2418    }
2419}
2420
2421#[instability::unstable]
2422impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2423where
2424    Dm: DriverMode,
2425{
2426    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2427        Ok(self.tx.write_ready())
2428    }
2429}
2430
2431#[derive(Debug, EnumSetType)]
2432pub(crate) enum TxEvent {
2433    Done,
2434    FiFoEmpty,
2435}
2436
2437#[derive(Debug, EnumSetType)]
2438pub(crate) enum RxEvent {
2439    FifoFull,
2440    CmdCharDetected,
2441    FifoOvf,
2442    FifoTout,
2443    GlitchDetected,
2444    FrameError,
2445    ParityError,
2446    BreakDetected,
2447}
2448
2449fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2450    for event in events {
2451        match event {
2452            RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2453            RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2454            RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2455            RxEvent::ParityError => return Err(RxError::ParityMismatch),
2456            RxEvent::FifoFull
2457            | RxEvent::CmdCharDetected
2458            | RxEvent::FifoTout
2459            | RxEvent::BreakDetected => continue,
2460        }
2461    }
2462
2463    Ok(())
2464}
2465
2466/// A future that resolves when the passed interrupt is triggered,
2467/// or has been triggered in the meantime (flag set in INT_RAW).
2468/// Upon construction the future enables the passed interrupt and when it
2469/// is dropped it disables the interrupt again. The future returns the event
2470/// that was initially passed, when it resolves.
2471#[must_use = "futures do nothing unless you `.await` or poll them"]
2472struct UartRxFuture {
2473    events: EnumSet<RxEvent>,
2474    uart: &'static Info,
2475    state: &'static State,
2476    registered: bool,
2477}
2478
2479impl UartRxFuture {
2480    fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2481        Self {
2482            events: events.into(),
2483            uart: uart.info(),
2484            state: uart.state(),
2485            registered: false,
2486        }
2487    }
2488}
2489
2490impl core::future::Future for UartRxFuture {
2491    type Output = EnumSet<RxEvent>;
2492
2493    fn poll(
2494        mut self: core::pin::Pin<&mut Self>,
2495        cx: &mut core::task::Context<'_>,
2496    ) -> core::task::Poll<Self::Output> {
2497        let events = self.uart.rx_events().intersection(self.events);
2498        if !events.is_empty() {
2499            self.uart.clear_rx_events(events);
2500            Poll::Ready(events)
2501        } else {
2502            self.state.rx_waker.register(cx.waker());
2503            if !self.registered {
2504                self.uart.enable_listen_rx(self.events, true);
2505                self.registered = true;
2506            }
2507            Poll::Pending
2508        }
2509    }
2510}
2511
2512impl Drop for UartRxFuture {
2513    fn drop(&mut self) {
2514        // Although the isr disables the interrupt that occurred directly, we need to
2515        // disable the other interrupts (= the ones that did not occur), as
2516        // soon as this future goes out of scope.
2517        self.uart.enable_listen_rx(self.events, false);
2518    }
2519}
2520
2521#[must_use = "futures do nothing unless you `.await` or poll them"]
2522struct UartTxFuture {
2523    events: EnumSet<TxEvent>,
2524    uart: &'static Info,
2525    state: &'static State,
2526    registered: bool,
2527}
2528
2529impl UartTxFuture {
2530    fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2531        Self {
2532            events: events.into(),
2533            uart: uart.info(),
2534            state: uart.state(),
2535            registered: false,
2536        }
2537    }
2538}
2539
2540impl core::future::Future for UartTxFuture {
2541    type Output = ();
2542
2543    fn poll(
2544        mut self: core::pin::Pin<&mut Self>,
2545        cx: &mut core::task::Context<'_>,
2546    ) -> core::task::Poll<Self::Output> {
2547        let events = self.uart.tx_events().intersection(self.events);
2548        if !events.is_empty() {
2549            self.uart.clear_tx_events(events);
2550            Poll::Ready(())
2551        } else {
2552            self.state.tx_waker.register(cx.waker());
2553            if !self.registered {
2554                self.uart.enable_listen_tx(self.events, true);
2555                self.registered = true;
2556            }
2557            Poll::Pending
2558        }
2559    }
2560}
2561
2562impl Drop for UartTxFuture {
2563    fn drop(&mut self) {
2564        // Although the isr disables the interrupt that occurred directly, we need to
2565        // disable the other interrupts (= the ones that did not occur), as
2566        // soon as this future goes out of scope.
2567        self.uart.enable_listen_tx(self.events, false);
2568    }
2569}
2570
2571#[instability::unstable]
2572impl embedded_io_async_06::Read for Uart<'_, Async> {
2573    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2574        self.read_async(buf).await.map_err(IoError::Rx)
2575    }
2576
2577    async fn read_exact(
2578        &mut self,
2579        buf: &mut [u8],
2580    ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2581        self.read_exact_async(buf)
2582            .await
2583            .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2584    }
2585}
2586
2587#[instability::unstable]
2588impl embedded_io_async_06::Read for UartRx<'_, Async> {
2589    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2590        self.read_async(buf).await
2591    }
2592
2593    async fn read_exact(
2594        &mut self,
2595        buf: &mut [u8],
2596    ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2597        self.read_exact_async(buf)
2598            .await
2599            .map_err(embedded_io_06::ReadExactError::Other)
2600    }
2601}
2602
2603#[instability::unstable]
2604impl embedded_io_async_06::Write for Uart<'_, Async> {
2605    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2606        self.write_async(buf).await.map_err(IoError::Tx)
2607    }
2608
2609    async fn flush(&mut self) -> Result<(), Self::Error> {
2610        self.flush_async().await.map_err(IoError::Tx)
2611    }
2612}
2613
2614#[instability::unstable]
2615impl embedded_io_async_06::Write for UartTx<'_, Async> {
2616    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2617        self.write_async(buf).await
2618    }
2619
2620    async fn flush(&mut self) -> Result<(), Self::Error> {
2621        self.flush_async().await
2622    }
2623}
2624
2625#[instability::unstable]
2626impl embedded_io_async_07::Read for Uart<'_, Async> {
2627    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2628        self.read_async(buf).await.map_err(IoError::Rx)
2629    }
2630
2631    async fn read_exact(
2632        &mut self,
2633        buf: &mut [u8],
2634    ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2635        self.read_exact_async(buf)
2636            .await
2637            .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2638    }
2639}
2640
2641#[instability::unstable]
2642impl embedded_io_async_07::Read for UartRx<'_, Async> {
2643    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2644        self.read_async(buf).await
2645    }
2646
2647    async fn read_exact(
2648        &mut self,
2649        buf: &mut [u8],
2650    ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2651        self.read_exact_async(buf)
2652            .await
2653            .map_err(embedded_io_07::ReadExactError::Other)
2654    }
2655}
2656
2657#[instability::unstable]
2658impl embedded_io_async_07::Write for Uart<'_, Async> {
2659    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2660        self.write_async(buf).await.map_err(IoError::Tx)
2661    }
2662
2663    async fn flush(&mut self) -> Result<(), Self::Error> {
2664        self.flush_async().await.map_err(IoError::Tx)
2665    }
2666}
2667
2668#[instability::unstable]
2669impl embedded_io_async_07::Write for UartTx<'_, Async> {
2670    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2671        self.write_async(buf).await
2672    }
2673
2674    async fn flush(&mut self) -> Result<(), Self::Error> {
2675        self.flush_async().await
2676    }
2677}
2678
2679/// Interrupt handler for all UART instances
2680/// Clears and disables interrupts that have occurred and have their enable
2681/// bit set. The fact that an interrupt has been disabled is used by the
2682/// futures to detect that they should indeed resolve after being woken up
2683#[ram]
2684pub(super) fn intr_handler(uart: &Info, state: &State) {
2685    let interrupts = uart.regs().int_st().read();
2686    let interrupt_bits = interrupts.bits(); // = int_raw & int_ena
2687    let rx_wake = interrupts.rxfifo_full().bit_is_set()
2688        | interrupts.rxfifo_ovf().bit_is_set()
2689        | interrupts.rxfifo_tout().bit_is_set()
2690        | interrupts.at_cmd_char_det().bit_is_set()
2691        | interrupts.glitch_det().bit_is_set()
2692        | interrupts.frm_err().bit_is_set()
2693        | interrupts.parity_err().bit_is_set()
2694        | interrupts.brk_det().bit_is_set();
2695    let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2696
2697    uart.regs()
2698        .int_ena()
2699        .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2700
2701    if tx_wake {
2702        state.tx_waker.wake();
2703    }
2704    if rx_wake {
2705        state.rx_waker.wake();
2706    }
2707}
2708
2709/// Low-power UART
2710#[cfg(lp_uart_driver_supported)]
2711#[instability::unstable]
2712pub mod lp_uart {
2713    use crate::{
2714        gpio::lp_io::{LowPowerInput, LowPowerOutput},
2715        peripherals::{LP_AON, LP_CLKRST, LP_IO, LP_UART, LPWR},
2716        soc::clocks::ClockTree,
2717        uart::{DataBits, Parity, StopBits},
2718    };
2719
2720    /// LP-UART Configuration
2721    #[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
2722    #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2723    #[non_exhaustive]
2724    pub struct Config {
2725        /// The baud rate (speed) of the UART communication in bits per second
2726        /// (bps).
2727        baudrate: u32,
2728        /// Number of data bits in each frame (5, 6, 7, or 8 bits).
2729        data_bits: DataBits,
2730        /// Parity setting (None, Even, or Odd).
2731        parity: Parity,
2732        /// Number of stop bits in each frame (1, 1.5, or 2 bits).
2733        stop_bits: StopBits,
2734        /// Clock source used by the UART peripheral.
2735        #[builder_lite(unstable)]
2736        clock_source: ClockSource,
2737    }
2738
2739    impl Default for Config {
2740        fn default() -> Config {
2741            Config {
2742                baudrate: 115_200,
2743                data_bits: Default::default(),
2744                parity: Default::default(),
2745                stop_bits: Default::default(),
2746                clock_source: Default::default(),
2747            }
2748        }
2749    }
2750
2751    /// LP-UART clock source
2752    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
2753    #[cfg_attr(feature = "defmt", derive(defmt::Format))]
2754    #[non_exhaustive]
2755    #[instability::unstable]
2756    pub enum ClockSource {
2757        /// RC_FAST_CLK clock source
2758        RcFast,
2759
2760        /// XTAL_D2 clock source
2761        #[default]
2762        Xtal,
2763    }
2764
2765    /// LP-UART driver
2766    pub struct LpUart {
2767        uart: LP_UART<'static>,
2768    }
2769
2770    impl LpUart {
2771        /// Initialize the UART driver using the provided configuration
2772        // TODO: CTS and RTS pins
2773        pub fn new(
2774            uart: LP_UART<'static>,
2775            config: Config,
2776            _tx: LowPowerOutput<'_, 5>,
2777            _rx: LowPowerInput<'_, 4>,
2778        ) -> Self {
2779            // FIXME: use GPIO APIs to configure pins
2780            LP_AON::regs()
2781                .gpio_mux()
2782                .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2783
2784            LP_IO::regs()
2785                .gpio(4)
2786                .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2787            LP_IO::regs()
2788                .gpio(5)
2789                .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2790
2791            let mut me = Self { uart };
2792            let uart = me.uart.register_block();
2793
2794            // Set UART mode - do nothing for LP
2795
2796            // Disable UART parity
2797            // 8-bit world
2798            // 1-bit stop bit
2799            uart.conf0().modify(|_, w| unsafe {
2800                w.parity().clear_bit();
2801                w.parity_en().clear_bit();
2802                w.bit_num().bits(0x3);
2803                w.stop_bit_num().bits(0x1)
2804            });
2805            // Set tx idle
2806            uart.idle_conf()
2807                .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2808            // Disable hw-flow control
2809            uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2810
2811            // Get source clock frequency
2812            // default == SOC_MOD_CLK_RTC_FAST == 2
2813
2814            // LPWR.lpperi.lp_uart_clk_sel = 0;
2815            LPWR::regs()
2816                .lpperi()
2817                .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2818
2819            // Override protocol parameters from the configuration
2820            // uart_hal_set_baudrate(&hal, cfg->uart_proto_cfg.baud_rate, sclk_freq);
2821            me.change_baud_internal(&config);
2822            // uart_hal_set_parity(&hal, cfg->uart_proto_cfg.parity);
2823            me.change_parity(config.parity);
2824            // uart_hal_set_data_bit_num(&hal, cfg->uart_proto_cfg.data_bits);
2825            me.change_data_bits(config.data_bits);
2826            // uart_hal_set_stop_bits(&hal, cfg->uart_proto_cfg.stop_bits);
2827            me.change_stop_bits(config.stop_bits);
2828            // uart_hal_set_tx_idle_num(&hal, LP_UART_TX_IDLE_NUM_DEFAULT);
2829            me.change_tx_idle(0); // LP_UART_TX_IDLE_NUM_DEFAULT == 0
2830
2831            // Reset Tx/Rx FIFOs
2832            me.rxfifo_reset();
2833            me.txfifo_reset();
2834
2835            me
2836        }
2837
2838        fn rxfifo_reset(&mut self) {
2839            self.uart
2840                .register_block()
2841                .conf0()
2842                .modify(|_, w| w.rxfifo_rst().set_bit());
2843            self.update();
2844
2845            self.uart
2846                .register_block()
2847                .conf0()
2848                .modify(|_, w| w.rxfifo_rst().clear_bit());
2849            self.update();
2850        }
2851
2852        fn txfifo_reset(&mut self) {
2853            self.uart
2854                .register_block()
2855                .conf0()
2856                .modify(|_, w| w.txfifo_rst().set_bit());
2857            self.update();
2858
2859            self.uart
2860                .register_block()
2861                .conf0()
2862                .modify(|_, w| w.txfifo_rst().clear_bit());
2863            self.update();
2864        }
2865
2866        fn update(&mut self) {
2867            let register_block = self.uart.register_block();
2868            register_block
2869                .reg_update()
2870                .modify(|_, w| w.reg_update().set_bit());
2871            while register_block.reg_update().read().reg_update().bit_is_set() {
2872                // wait
2873            }
2874        }
2875
2876        fn change_baud_internal(&mut self, config: &Config) {
2877            let clk = ClockTree::with(|clocks| match config.clock_source {
2878                ClockSource::RcFast => crate::soc::clocks::rc_fast_clk_frequency(clocks),
2879                ClockSource::Xtal => crate::soc::clocks::xtal_d2_clk_frequency(clocks),
2880            });
2881
2882            LP_CLKRST::regs().lpperi().modify(|_, w| {
2883                w.lp_uart_clk_sel().bit(match config.clock_source {
2884                    ClockSource::RcFast => false,
2885                    ClockSource::Xtal => true,
2886                })
2887            });
2888            self.uart.register_block().clk_conf().modify(|_, w| {
2889                w.rx_sclk_en().set_bit();
2890                w.tx_sclk_en().set_bit()
2891            });
2892
2893            let divider = clk / config.baudrate;
2894            let divider = divider as u16;
2895
2896            self.uart
2897                .register_block()
2898                .clkdiv()
2899                .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2900
2901            self.update();
2902        }
2903
2904        /// Modify UART baud rate and reset TX/RX fifo.
2905        pub fn change_baud(&mut self, config: &Config) {
2906            self.change_baud_internal(config);
2907            self.txfifo_reset();
2908            self.rxfifo_reset();
2909        }
2910
2911        fn change_parity(&mut self, parity: Parity) -> &mut Self {
2912            if parity != Parity::None {
2913                self.uart
2914                    .register_block()
2915                    .conf0()
2916                    .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2917            }
2918
2919            self.uart
2920                .register_block()
2921                .conf0()
2922                .modify(|_, w| match parity {
2923                    Parity::None => w.parity_en().clear_bit(),
2924                    Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2925                    Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2926                });
2927
2928            self
2929        }
2930
2931        fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2932            self.uart
2933                .register_block()
2934                .conf0()
2935                .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2936
2937            self.update();
2938            self
2939        }
2940
2941        fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2942            self.uart
2943                .register_block()
2944                .conf0()
2945                .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2946
2947            self.update();
2948            self
2949        }
2950
2951        fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2952            self.uart
2953                .register_block()
2954                .idle_conf()
2955                .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2956
2957            self.update();
2958            self
2959        }
2960    }
2961}
2962
2963/// A peripheral singleton compatible with the UART driver.
2964pub trait Instance: crate::private::Sealed + any::Degrade {
2965    #[doc(hidden)]
2966    /// Returns the peripheral data and state describing this UART instance.
2967    fn parts(&self) -> (&'static Info, &'static State);
2968
2969    /// Returns the peripheral data describing this UART instance.
2970    #[inline(always)]
2971    #[doc(hidden)]
2972    fn info(&self) -> &'static Info {
2973        self.parts().0
2974    }
2975
2976    /// Returns the peripheral state for this UART instance.
2977    #[inline(always)]
2978    #[doc(hidden)]
2979    fn state(&self) -> &'static State {
2980        self.parts().1
2981    }
2982}
2983
2984/// Peripheral data describing a particular UART instance.
2985#[doc(hidden)]
2986#[non_exhaustive]
2987#[allow(private_interfaces, reason = "Unstable details")]
2988pub struct Info {
2989    /// Pointer to the register block for this UART instance.
2990    ///
2991    /// Use [Self::register_block] to access the register block.
2992    pub register_block: *const RegisterBlock,
2993
2994    /// The system peripheral marker.
2995    pub peripheral: crate::system::Peripheral,
2996
2997    /// UART clock group instance.
2998    pub clock_instance: clocks::UartInstance,
2999
3000    /// Interrupt handler for the asynchronous operations of this UART instance.
3001    pub async_handler: InterruptHandler,
3002
3003    /// TX pin
3004    pub tx_signal: OutputSignal,
3005
3006    /// RX pin
3007    pub rx_signal: InputSignal,
3008
3009    /// CTS (Clear to Send) pin
3010    pub cts_signal: InputSignal,
3011
3012    /// RTS (Request to Send) pin
3013    pub rts_signal: OutputSignal,
3014}
3015
3016/// Peripheral state for a UART instance.
3017#[doc(hidden)]
3018#[non_exhaustive]
3019pub struct State {
3020    /// Waker for the asynchronous RX operations.
3021    pub rx_waker: AtomicWaker,
3022
3023    /// Waker for the asynchronous TX operations.
3024    pub tx_waker: AtomicWaker,
3025
3026    /// Stores whether the RX half is configured for async operation.
3027    pub is_rx_async: AtomicBool,
3028
3029    /// Stores whether the TX half is configured for async operation.
3030    pub is_tx_async: AtomicBool,
3031}
3032
3033impl Info {
3034    // Currently we don't support merging adjacent FIFO memory, so the max size is
3035    // 128 bytes, the max threshold is 127 bytes.
3036    const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
3037    const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
3038    const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
3039
3040    /// Returns the register block for this UART instance.
3041    pub fn regs(&self) -> &RegisterBlock {
3042        unsafe { &*self.register_block }
3043    }
3044
3045    /// Listen for the given interrupts
3046    fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
3047        let reg_block = self.regs();
3048
3049        reg_block.int_ena().modify(|_, w| {
3050            for interrupt in interrupts {
3051                match interrupt {
3052                    UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
3053                    UartInterrupt::TxDone => w.tx_done().bit(enable),
3054                    UartInterrupt::RxBreakDetected => w.brk_det().bit(enable),
3055                    UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
3056                    UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
3057                };
3058            }
3059            w
3060        });
3061    }
3062
3063    fn interrupts(&self) -> EnumSet<UartInterrupt> {
3064        let mut res = EnumSet::new();
3065        let reg_block = self.regs();
3066
3067        let ints = reg_block.int_raw().read();
3068
3069        if ints.at_cmd_char_det().bit_is_set() {
3070            res.insert(UartInterrupt::AtCmd);
3071        }
3072        if ints.tx_done().bit_is_set() {
3073            res.insert(UartInterrupt::TxDone);
3074        }
3075        if ints.brk_det().bit_is_set() {
3076            res.insert(UartInterrupt::RxBreakDetected);
3077        }
3078        if ints.rxfifo_full().bit_is_set() {
3079            res.insert(UartInterrupt::RxFifoFull);
3080        }
3081        if ints.rxfifo_tout().bit_is_set() {
3082            res.insert(UartInterrupt::RxTimeout);
3083        }
3084
3085        res
3086    }
3087
3088    fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
3089        let reg_block = self.regs();
3090
3091        reg_block.int_clr().write(|w| {
3092            for interrupt in interrupts {
3093                match interrupt {
3094                    UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
3095                    UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
3096                    UartInterrupt::RxBreakDetected => w.brk_det().clear_bit_by_one(),
3097                    UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
3098                    UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
3099                };
3100            }
3101            w
3102        });
3103    }
3104
3105    fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
3106        config.validate()?;
3107        self.change_baud(config)?;
3108        self.change_data_bits(config.data_bits);
3109        self.change_parity(config.parity);
3110        self.change_stop_bits(config.stop_bits);
3111        self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
3112
3113        // Avoid glitch interrupts.
3114        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
3115
3116        Ok(())
3117    }
3118
3119    fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
3120        self.regs().int_ena().modify(|_, w| {
3121            for event in events {
3122                match event {
3123                    TxEvent::Done => w.tx_done().bit(enable),
3124                    TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
3125                };
3126            }
3127            w
3128        });
3129    }
3130
3131    fn tx_events(&self) -> EnumSet<TxEvent> {
3132        let pending_interrupts = self.regs().int_raw().read();
3133        let mut active_events = EnumSet::new();
3134
3135        if pending_interrupts.tx_done().bit_is_set() {
3136            active_events |= TxEvent::Done;
3137        }
3138        if pending_interrupts.txfifo_empty().bit_is_set() {
3139            active_events |= TxEvent::FiFoEmpty;
3140        }
3141
3142        active_events
3143    }
3144
3145    fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
3146        let events = events.into();
3147        self.regs().int_clr().write(|w| {
3148            for event in events {
3149                match event {
3150                    TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
3151                    TxEvent::Done => w.tx_done().clear_bit_by_one(),
3152                };
3153            }
3154            w
3155        });
3156    }
3157
3158    fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
3159        self.regs().int_ena().modify(|_, w| {
3160            for event in events {
3161                match event {
3162                    RxEvent::FifoFull => w.rxfifo_full().bit(enable),
3163                    RxEvent::BreakDetected => w.brk_det().bit(enable),
3164                    RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
3165
3166                    RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
3167                    RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
3168                    RxEvent::GlitchDetected => w.glitch_det().bit(enable),
3169                    RxEvent::FrameError => w.frm_err().bit(enable),
3170                    RxEvent::ParityError => w.parity_err().bit(enable),
3171                };
3172            }
3173            w
3174        });
3175    }
3176
3177    fn rx_events(&self) -> EnumSet<RxEvent> {
3178        let pending_interrupts = self.regs().int_raw().read();
3179        let mut active_events = EnumSet::new();
3180
3181        if pending_interrupts.rxfifo_full().bit_is_set() {
3182            active_events |= RxEvent::FifoFull;
3183        }
3184        if pending_interrupts.brk_det().bit_is_set() {
3185            active_events |= RxEvent::BreakDetected;
3186        }
3187        if pending_interrupts.at_cmd_char_det().bit_is_set() {
3188            active_events |= RxEvent::CmdCharDetected;
3189        }
3190        if pending_interrupts.rxfifo_ovf().bit_is_set() {
3191            active_events |= RxEvent::FifoOvf;
3192        }
3193        if pending_interrupts.rxfifo_tout().bit_is_set() {
3194            active_events |= RxEvent::FifoTout;
3195        }
3196        if pending_interrupts.glitch_det().bit_is_set() {
3197            active_events |= RxEvent::GlitchDetected;
3198        }
3199        if pending_interrupts.frm_err().bit_is_set() {
3200            active_events |= RxEvent::FrameError;
3201        }
3202        if pending_interrupts.parity_err().bit_is_set() {
3203            active_events |= RxEvent::ParityError;
3204        }
3205
3206        active_events
3207    }
3208
3209    fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
3210        let events = events.into();
3211        self.regs().int_clr().write(|w| {
3212            for event in events {
3213                match event {
3214                    RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
3215                    RxEvent::BreakDetected => w.brk_det().clear_bit_by_one(),
3216                    RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
3217
3218                    RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
3219                    RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
3220                    RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
3221                    RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
3222                    RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
3223                };
3224            }
3225            w
3226        });
3227    }
3228
3229    /// Configures the RX-FIFO threshold
3230    ///
3231    /// ## Errors
3232    ///
3233    /// [`ConfigError::RxFifoThresholdNotSupported`] if the provided value is zero
3234    /// or exceeds [`Info::RX_FIFO_MAX_THRHD`].
3235    fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3236        if threshold == 0 || threshold > Self::RX_FIFO_MAX_THRHD {
3237            return Err(ConfigError::RxFifoThresholdNotSupported);
3238        }
3239
3240        self.regs()
3241            .conf1()
3242            .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
3243
3244        Ok(())
3245    }
3246
3247    /// Reads the RX-FIFO threshold
3248    #[allow(clippy::useless_conversion)]
3249    fn rx_fifo_full_threshold(&self) -> u16 {
3250        self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
3251    }
3252
3253    /// Configures the TX-FIFO threshold
3254    ///
3255    /// ## Errors
3256    ///
3257    /// [`ConfigError::TxFifoThresholdNotSupported`] if the provided value exceeds
3258    /// [`Info::TX_FIFO_MAX_THRHD`].
3259    fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3260        if threshold > Self::TX_FIFO_MAX_THRHD {
3261            return Err(ConfigError::TxFifoThresholdNotSupported);
3262        }
3263
3264        self.regs()
3265            .conf1()
3266            .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3267
3268        Ok(())
3269    }
3270
3271    /// Configures the Receive Timeout detection setting
3272    ///
3273    /// ## Arguments
3274    ///
3275    /// `timeout` - the number of symbols ("bytes") to wait for before
3276    /// triggering a timeout. Pass None to disable the timeout.
3277    ///
3278    /// ## Errors
3279    ///
3280    /// [`ConfigError::TimeoutTooLong`] if the provided value exceeds
3281    /// the maximum value for SOC:
3282    /// - `esp32`: Symbol size is fixed to 8, do not pass a value > **0x7F**.
3283    /// - `esp32c2`, `esp32c3`, `esp32c6`, `esp32h2`, esp32s2`, esp32s3`: The value you pass times
3284    ///   the symbol size must be <= **0x3FF**
3285    fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3286        cfg_if::cfg_if! {
3287            if #[cfg(esp32)] {
3288                const MAX_THRHD: u8 = 0x7F; // 7 bits
3289            } else {
3290                const MAX_THRHD: u16 = 0x3FF; // 10 bits
3291            }
3292        }
3293
3294        let register_block = self.regs();
3295
3296        if let Some(timeout) = timeout {
3297            // the esp32 counts directly in number of symbols (symbol len fixed to 8)
3298            #[cfg(esp32)]
3299            let timeout_reg = timeout;
3300            // all other count in bits, so we need to multiply by the symbol len.
3301            #[cfg(not(esp32))]
3302            let timeout_reg = timeout as u16 * _symbol_len as u16;
3303
3304            if timeout_reg > MAX_THRHD {
3305                return Err(ConfigError::TimeoutTooLong);
3306            }
3307
3308            cfg_if::cfg_if! {
3309                if #[cfg(esp32)] {
3310                    let reg_thrhd = register_block.conf1();
3311                } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3312                    let reg_thrhd = register_block.tout_conf();
3313                } else {
3314                    let reg_thrhd = register_block.mem_conf();
3315                }
3316            }
3317            reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3318        }
3319
3320        cfg_if::cfg_if! {
3321            if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3322                let reg_en = register_block.tout_conf();
3323            } else {
3324                let reg_en = register_block.conf1();
3325            }
3326        }
3327        reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3328
3329        self.sync_regs();
3330
3331        Ok(())
3332    }
3333
3334    fn sync_regs(&self) {
3335        sync_regs(self.regs());
3336    }
3337
3338    fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3339        ClockTree::with(|clocks| {
3340            let clock = self.clock_instance;
3341
3342            let source_config = ClockConfig::new(
3343                config.clock_source,
3344                #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3345                0,
3346            );
3347            let clk = clock.function_clock_config_frequency(clocks, source_config);
3348
3349            // The UART baud rate clock divider is, depending on the device, either a
3350            // 20.4 bit, or a 12.4 bit divider.
3351            const FRAC_BITS: u32 = const {
3352                let largest_divider: u32 =
3353                    property!("clock_tree.uart.baud_rate_generator.fractional").1;
3354                ::core::assert!((largest_divider + 1).is_power_of_two());
3355                largest_divider.count_ones()
3356            };
3357            const FRAC_MASK: u32 = (1 << FRAC_BITS) - 1;
3358
3359            // TODO: this block should only prepare the new clock config, and it should
3360            // be applied only after validating the resulting baud rate.
3361            cfg_if::cfg_if! {
3362                if #[cfg(any(uart_has_sclk_divider, soc_has_pcr))] {
3363                    const MAX_DIV: u32 = property!("clock_tree.uart.baud_rate_generator.integral").1;
3364                    let clk_div = clk.div_ceil(MAX_DIV).div_ceil(config.baudrate);
3365                    debug!("SCLK: {} divider: {}", clk, clk_div);
3366
3367                    let conf = ClockConfig::new(config.clock_source, clk_div - 1);
3368                    let divider = (clk << FRAC_BITS) / (config.baudrate * clk_div);
3369                } else {
3370                    debug!("SCLK: {}", clk);
3371                    let conf = ClockConfig::new(config.clock_source);
3372                    let divider = (clk << FRAC_BITS) / config.baudrate;
3373                }
3374            }
3375
3376            let divider_integer = divider >> FRAC_BITS;
3377            let divider_frag = divider & FRAC_MASK;
3378            debug!(
3379                "UART CLK divider: {} + {}/16",
3380                divider_integer, divider_frag
3381            );
3382
3383            clock.configure_function_clock(clocks, conf);
3384            clock.configure_baud_rate_generator(
3385                clocks,
3386                BaudRateConfig::new(divider_frag, divider_integer),
3387            );
3388
3389            self.sync_regs();
3390
3391            #[cfg(feature = "unstable")]
3392            {
3393                let deviation_limit = match config.baudrate_tolerance {
3394                    BaudrateTolerance::Exact => 1, // Still allow a tiny deviation
3395                    BaudrateTolerance::ErrorPercent(percent) => percent as u32,
3396                    _ => return Ok(()),
3397                };
3398
3399                let actual_baud = clock.baud_rate_generator_frequency(clocks);
3400                if actual_baud == 0 {
3401                    return Err(ConfigError::BaudrateNotAchievable);
3402                }
3403
3404                let deviation = (config.baudrate.abs_diff(actual_baud) * 100) / actual_baud;
3405                debug!(
3406                    "Nominal baud: {}, actual: {}, deviation: {}%",
3407                    config.baudrate, actual_baud, deviation
3408                );
3409
3410                if deviation > deviation_limit {
3411                    return Err(ConfigError::BaudrateNotAchievable);
3412                }
3413            }
3414
3415            Ok(())
3416        })
3417    }
3418
3419    fn change_data_bits(&self, data_bits: DataBits) {
3420        self.regs()
3421            .conf0()
3422            .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3423    }
3424
3425    fn change_parity(&self, parity: Parity) {
3426        self.regs().conf0().modify(|_, w| match parity {
3427            Parity::None => w.parity_en().clear_bit(),
3428            Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3429            Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3430        });
3431    }
3432
3433    fn change_stop_bits(&self, stop_bits: StopBits) {
3434        #[cfg(esp32)]
3435        {
3436            // workaround for hardware issue, when UART stop bit set as 2-bit mode.
3437            if stop_bits == StopBits::_2 {
3438                self.regs()
3439                    .rs485_conf()
3440                    .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3441
3442                self.regs()
3443                    .conf0()
3444                    .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3445            }
3446        }
3447
3448        #[cfg(not(esp32))]
3449        self.regs()
3450            .conf0()
3451            .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3452    }
3453
3454    fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3455        // set SW flow control
3456        match sw_flow_ctrl {
3457            SwFlowControl::Enabled {
3458                xon_char,
3459                xoff_char,
3460                xon_threshold,
3461                xoff_threshold,
3462            } => {
3463                cfg_if::cfg_if! {
3464                    if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3465                        self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3466                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3467                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3468                    } else if #[cfg(esp32)]{
3469                        self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3470                        self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3471                        self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3472                    } else {
3473                        self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3474                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3475                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3476                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3477                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3478                    }
3479                }
3480            }
3481            SwFlowControl::Disabled => {
3482                cfg_if::cfg_if! {
3483                    if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3484                        let reg = self.regs().swfc_conf0();
3485                    } else {
3486                        let reg = self.regs().flow_conf();
3487                    }
3488                }
3489
3490                reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3491                reg.modify(|_, w| w.xonoff_del().clear_bit());
3492            }
3493        }
3494
3495        self.regs().conf0().modify(|_, w| {
3496            w.tx_flow_en()
3497                .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3498        });
3499
3500        match hw_flow_ctrl.rts {
3501            RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3502            RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3503        }
3504
3505        sync_regs(self.regs());
3506    }
3507
3508    fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3509        if let Some(threshold) = threshold {
3510            cfg_if::cfg_if! {
3511                if #[cfg(esp32)] {
3512                    self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3513                } else if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3514                    self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3515                } else {
3516                    self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3517                }
3518            }
3519        }
3520
3521        cfg_if::cfg_if! {
3522            if #[cfg(any(esp32c5, esp32c6, esp32c61, esp32h2))] {
3523                self.regs().hwfc_conf().modify(|_, w| {
3524                    w.rx_flow_en().bit(enable)
3525                });
3526            } else {
3527                self.regs().conf1().modify(|_, w| {
3528                    w.rx_flow_en().bit(enable)
3529                });
3530            }
3531        }
3532    }
3533
3534    fn rxfifo_reset(&self) {
3535        fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3536            reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3537            sync_regs(reg_block);
3538        }
3539
3540        rxfifo_rst(self.regs(), true);
3541        rxfifo_rst(self.regs(), false);
3542    }
3543
3544    fn txfifo_reset(&self) {
3545        fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3546            reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3547            sync_regs(reg_block);
3548        }
3549
3550        txfifo_rst(self.regs(), true);
3551        txfifo_rst(self.regs(), false);
3552    }
3553
3554    fn current_symbol_length(&self) -> u8 {
3555        let conf0 = self.regs().conf0().read();
3556        let data_bits = conf0.bit_num().bits() + 5; // 5 data bits are encoded as variant 0
3557        let parity = conf0.parity_en().bit() as u8;
3558        let mut stop_bits = conf0.stop_bit_num().bits();
3559
3560        match stop_bits {
3561            1 => {
3562                // workaround for hardware issue, when UART stop bit set as 2-bit mode.
3563                #[cfg(esp32)]
3564                if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3565                    stop_bits = 2;
3566                }
3567            }
3568            // esp-idf also counts 2 bits for settings 1.5 and 2 stop bits
3569            _ => stop_bits = 2,
3570        }
3571
3572        1 + data_bits + parity + stop_bits
3573    }
3574
3575    /// Reads one byte from the RX FIFO.
3576    ///
3577    /// If the FIFO is empty, the value of the returned byte is not specified.
3578    fn read_next_from_fifo(&self) -> u8 {
3579        fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3580            // https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/cpu-subsequent-access-halted-when-get-interrupted.html
3581            cfg_if::cfg_if! {
3582                if #[cfg(esp32)] {
3583                    crate::interrupt::free(f)
3584                } else {
3585                    f()
3586                }
3587            }
3588        }
3589
3590        let fifo_reg = self.regs().fifo();
3591        cfg_if::cfg_if! {
3592            if #[cfg(esp32s2)] {
3593                // On the ESP32-S2 we need to use PeriBus2 to read the FIFO:
3594                let fifo_reg = unsafe {
3595                    &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3596                };
3597            }
3598        }
3599
3600        access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3601    }
3602
3603    #[allow(clippy::useless_conversion)]
3604    fn tx_fifo_count(&self) -> u16 {
3605        u16::from(self.regs().status().read().txfifo_cnt().bits())
3606    }
3607
3608    fn write_byte(&self, byte: u8) {
3609        self.regs()
3610            .fifo()
3611            .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3612    }
3613
3614    fn check_for_errors(&self) -> Result<(), RxError> {
3615        let errors = RxEvent::FifoOvf
3616            | RxEvent::FifoTout
3617            | RxEvent::GlitchDetected
3618            | RxEvent::FrameError
3619            | RxEvent::ParityError;
3620        let events = self.rx_events().intersection(errors);
3621        let result = rx_event_check_for_error(events);
3622        if result.is_err() {
3623            self.clear_rx_events(errors);
3624            if events.contains(RxEvent::FifoOvf) {
3625                self.rxfifo_reset();
3626            }
3627        }
3628        result
3629    }
3630
3631    #[cfg(not(esp32))]
3632    #[allow(clippy::unnecessary_cast)]
3633    fn rx_fifo_count(&self) -> u16 {
3634        self.regs().status().read().rxfifo_cnt().bits() as u16
3635    }
3636
3637    #[cfg(esp32)]
3638    fn rx_fifo_count(&self) -> u16 {
3639        let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3640
3641        // Calculate the real count based on the FIFO read and write offset address:
3642        // https://docs.espressif.com/projects/esp-chip-errata/en/latest/esp32/03-errata-description/esp32/uart-fifo-cnt-indicates-data-length-incorrectly.html
3643        let status = self.regs().mem_rx_status().read();
3644        let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3645        let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3646
3647        if wr_addr > rd_addr {
3648            wr_addr - rd_addr
3649        } else if wr_addr < rd_addr {
3650            (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3651        } else if fifo_cnt > 0 {
3652            Info::UART_FIFO_SIZE
3653        } else {
3654            0
3655        }
3656    }
3657
3658    fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3659        if data.is_empty() {
3660            return Ok(0);
3661        }
3662
3663        while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3664
3665        let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3666        let to_write = space.min(data.len());
3667        for &byte in &data[..to_write] {
3668            self.write_byte(byte);
3669        }
3670
3671        Ok(to_write)
3672    }
3673
3674    fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3675        if buf.is_empty() {
3676            return Ok(0);
3677        }
3678
3679        while self.rx_fifo_count() == 0 {
3680            // Block until we received at least one byte
3681            self.check_for_errors()?;
3682        }
3683
3684        self.read_buffered(buf)
3685    }
3686
3687    fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3688        // Get the count first, to avoid accidentally reading a corrupted byte received
3689        // after the error check.
3690        let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3691        self.check_for_errors()?;
3692
3693        for byte_into in buf[..to_read].iter_mut() {
3694            *byte_into = self.read_next_from_fifo();
3695        }
3696
3697        // This bit is not cleared until the FIFO actually drops below the threshold.
3698        self.clear_rx_events(RxEvent::FifoFull);
3699
3700        Ok(to_read)
3701    }
3702}
3703
3704impl PartialEq for Info {
3705    fn eq(&self, other: &Self) -> bool {
3706        core::ptr::eq(self.register_block, other.register_block)
3707    }
3708}
3709
3710unsafe impl Sync for Info {}
3711
3712for_each_uart! {
3713    ($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3714        impl Instance for crate::peripherals::$inst<'_> {
3715            fn parts(&self) -> (&'static Info, &'static State) {
3716                #[handler]
3717                #[ram]
3718                pub(super) fn irq_handler() {
3719                    intr_handler(&PERIPHERAL, &STATE);
3720                }
3721
3722                static STATE: State = State {
3723                    tx_waker: AtomicWaker::new(),
3724                    rx_waker: AtomicWaker::new(),
3725                    is_rx_async: AtomicBool::new(false),
3726                    is_tx_async: AtomicBool::new(false),
3727                };
3728
3729                static PERIPHERAL: Info = Info {
3730                    register_block: crate::peripherals::$inst::ptr(),
3731                    peripheral: crate::system::Peripheral::$peri,
3732                    clock_instance: clocks::UartInstance::$peri,
3733                    async_handler: irq_handler,
3734                    tx_signal: OutputSignal::$txd,
3735                    rx_signal: InputSignal::$rxd,
3736                    cts_signal: InputSignal::$cts,
3737                    rts_signal: OutputSignal::$rts,
3738                };
3739                (&PERIPHERAL, &STATE)
3740            }
3741        }
3742    };
3743}
3744
3745crate::any_peripheral! {
3746    /// Any UART peripheral.
3747    pub peripheral AnyUart<'d> {
3748        #[cfg(soc_has_uart0)]
3749        Uart0(crate::peripherals::UART0<'d>),
3750        #[cfg(soc_has_uart1)]
3751        Uart1(crate::peripherals::UART1<'d>),
3752        #[cfg(soc_has_uart2)]
3753        Uart2(crate::peripherals::UART2<'d>),
3754    }
3755}
3756
3757impl Instance for AnyUart<'_> {
3758    #[inline]
3759    fn parts(&self) -> (&'static Info, &'static State) {
3760        any::delegate!(self, uart => { uart.parts() })
3761    }
3762}
3763
3764impl AnyUart<'_> {
3765    fn bind_peri_interrupt(&self, handler: InterruptHandler) {
3766        any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3767    }
3768
3769    fn disable_peri_interrupt_on_all_cores(&self) {
3770        any::delegate!(self, uart => { uart.disable_peri_interrupt_on_all_cores() })
3771    }
3772
3773    fn set_interrupt_handler(&self, handler: InterruptHandler) {
3774        self.disable_peri_interrupt_on_all_cores();
3775
3776        self.info().enable_listen(EnumSet::all(), false);
3777        self.info().clear_interrupts(EnumSet::all());
3778
3779        self.bind_peri_interrupt(handler);
3780    }
3781}
3782
3783struct UartClockGuard<'t> {
3784    uart: AnyUart<'t>,
3785}
3786
3787impl<'t> UartClockGuard<'t> {
3788    fn new(uart: AnyUart<'t>) -> Self {
3789        ClockTree::with(|clocks| {
3790            let clock = uart.info().clock_instance;
3791
3792            // Apply default SCLK configuration
3793            let sclk_config = ClockConfig::new(
3794                Default::default(),
3795                #[cfg(any(uart_has_sclk_divider, soc_has_pcr))]
3796                0,
3797            );
3798            clock.configure_function_clock(clocks, sclk_config);
3799            clock.request_function_clock(clocks);
3800            clock.request_baud_rate_generator(clocks);
3801            #[cfg(soc_has_clock_node_uart_mem_clock)]
3802            clock.request_mem_clock(clocks);
3803        });
3804
3805        Self { uart }
3806    }
3807}
3808
3809impl Clone for UartClockGuard<'_> {
3810    fn clone(&self) -> Self {
3811        Self::new(unsafe { self.uart.clone_unchecked() })
3812    }
3813}
3814
3815impl Drop for UartClockGuard<'_> {
3816    fn drop(&mut self) {
3817        ClockTree::with(|clocks| {
3818            let clock = self.uart.info().clock_instance;
3819
3820            #[cfg(soc_has_clock_node_uart_mem_clock)]
3821            clock.release_mem_clock(clocks);
3822            clock.release_baud_rate_generator(clocks);
3823            clock.release_function_clock(clocks);
3824        });
3825    }
3826}