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