esp_hal/
uart.rs

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