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