esp_hal/uart/
mod.rs

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