1#[cfg(all(soc_has_uhci0, gdma))]
47#[cfg(feature = "unstable")]
48pub mod uhci;
49
50use core::{marker::PhantomData, sync::atomic::Ordering, task::Poll};
51
52use enumset::{EnumSet, EnumSetType};
53use portable_atomic::AtomicBool;
54
55use crate::{
56    Async,
57    Blocking,
58    DriverMode,
59    asynch::AtomicWaker,
60    clock::Clocks,
61    gpio::{
62        InputConfig,
63        InputSignal,
64        OutputConfig,
65        OutputSignal,
66        PinGuard,
67        Pull,
68        interconnect::{PeripheralInput, PeripheralOutput},
69    },
70    interrupt::InterruptHandler,
71    pac::uart0::RegisterBlock,
72    private::OnDrop,
73    system::PeripheralGuard,
74};
75
76#[derive(Debug, Clone, Copy, PartialEq)]
78#[cfg_attr(feature = "defmt", derive(defmt::Format))]
79#[non_exhaustive]
80pub enum RxError {
81    FifoOverflowed,
86
87    GlitchOccurred,
93
94    FrameFormatViolated,
99
100    ParityMismatch,
105}
106
107impl core::error::Error for RxError {}
108
109impl core::fmt::Display for RxError {
110    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
111        match self {
112            RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
113            RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
114            RxError::FrameFormatViolated => {
115                write!(f, "A framing error was detected on the RX line")
116            }
117            RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
118        }
119    }
120}
121
122#[instability::unstable]
123impl embedded_io_06::Error for RxError {
124    fn kind(&self) -> embedded_io_06::ErrorKind {
125        embedded_io_06::ErrorKind::Other
126    }
127}
128
129#[instability::unstable]
130impl embedded_io_07::Error for RxError {
131    fn kind(&self) -> embedded_io_07::ErrorKind {
132        embedded_io_07::ErrorKind::Other
133    }
134}
135
136#[derive(Debug, Clone, Copy, PartialEq)]
138#[cfg_attr(feature = "defmt", derive(defmt::Format))]
139#[non_exhaustive]
140pub enum TxError {}
141
142impl core::fmt::Display for TxError {
143    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
144        write!(f, "Tx error")
145    }
146}
147
148impl core::error::Error for TxError {}
149
150#[instability::unstable]
151impl embedded_io_06::Error for TxError {
152    fn kind(&self) -> embedded_io_06::ErrorKind {
153        embedded_io_06::ErrorKind::Other
154    }
155}
156#[instability::unstable]
157impl embedded_io_07::Error for TxError {
158    fn kind(&self) -> embedded_io_07::ErrorKind {
159        embedded_io_07::ErrorKind::Other
160    }
161}
162
163#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
165#[cfg_attr(feature = "defmt", derive(defmt::Format))]
166#[non_exhaustive]
167#[instability::unstable]
168pub enum ClockSource {
169    #[cfg_attr(not(any(esp32c6, esp32h2, soc_has_lp_uart)), default)]
171    Apb,
172    #[cfg(not(any(esp32, esp32s2)))]
174    RcFast,
175    #[cfg(not(any(esp32, esp32s2)))]
177    #[cfg_attr(any(esp32c6, esp32h2, soc_has_lp_uart), default)]
178    Xtal,
179    #[cfg(any(esp32, esp32s2))]
181    RefTick,
182}
183
184#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
190#[cfg_attr(feature = "defmt", derive(defmt::Format))]
191pub enum DataBits {
192    _5,
194    _6,
196    _7,
198    #[default]
200    _8,
201}
202
203#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
210#[cfg_attr(feature = "defmt", derive(defmt::Format))]
211pub enum Parity {
212    #[default]
214    None,
215    Even,
218    Odd,
221}
222
223#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
229#[cfg_attr(feature = "defmt", derive(defmt::Format))]
230pub enum StopBits {
231    #[default]
233    _1,
234    _1p5,
236    _2,
238}
239
240#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
242#[cfg_attr(feature = "defmt", derive(defmt::Format))]
243#[instability::unstable]
244pub enum SwFlowControl {
245    #[default]
246    Disabled,
248    Enabled {
250        xon_char: u8,
252        xoff_char: u8,
254        xon_threshold: u8,
257        xoff_threshold: u8,
260    },
261}
262
263#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
265#[cfg_attr(feature = "defmt", derive(defmt::Format))]
266#[instability::unstable]
267pub enum CtsConfig {
268    Enabled,
270    #[default]
271    Disabled,
273}
274
275#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
277#[cfg_attr(feature = "defmt", derive(defmt::Format))]
278#[instability::unstable]
279pub enum RtsConfig {
280    Enabled(u8),
282    #[default]
283    Disabled,
285}
286
287#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
289#[cfg_attr(feature = "defmt", derive(defmt::Format))]
290#[instability::unstable]
291pub struct HwFlowControl {
292    pub cts: CtsConfig,
294    pub rts: RtsConfig,
296}
297
298#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
300#[cfg_attr(feature = "defmt", derive(defmt::Format))]
301#[instability::unstable]
302pub enum BaudrateTolerance {
303    #[default]
305    Closest,
306    Exact,
309    ErrorPercent(u8),
311}
312
313#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
315#[cfg_attr(feature = "defmt", derive(defmt::Format))]
316#[non_exhaustive]
317pub struct Config {
318    baudrate: u32,
321    #[builder_lite(unstable)]
324    baudrate_tolerance: BaudrateTolerance,
325    data_bits: DataBits,
327    parity: Parity,
329    stop_bits: StopBits,
331    #[builder_lite(unstable)]
333    sw_flow_ctrl: SwFlowControl,
334    #[builder_lite(unstable)]
336    hw_flow_ctrl: HwFlowControl,
337    #[builder_lite(unstable)]
339    clock_source: ClockSource,
340    rx: RxConfig,
342    tx: TxConfig,
344}
345
346impl Default for Config {
347    fn default() -> Config {
348        Config {
349            rx: RxConfig::default(),
350            tx: TxConfig::default(),
351            baudrate: 115_200,
352            baudrate_tolerance: BaudrateTolerance::default(),
353            data_bits: Default::default(),
354            parity: Default::default(),
355            stop_bits: Default::default(),
356            sw_flow_ctrl: Default::default(),
357            hw_flow_ctrl: Default::default(),
358            clock_source: Default::default(),
359        }
360    }
361}
362
363impl Config {
364    fn validate(&self) -> Result<(), ConfigError> {
365        if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
366            assert!(percentage > 0 && percentage <= 100);
367        }
368
369        if self.baudrate == 0 || self.baudrate > 5_000_000 {
371            return Err(ConfigError::BaudrateNotSupported);
372        }
373        Ok(())
374    }
375}
376
377#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
379#[cfg_attr(feature = "defmt", derive(defmt::Format))]
380#[non_exhaustive]
381pub struct RxConfig {
382    fifo_full_threshold: u16,
384    timeout: Option<u8>,
386}
387
388impl Default for RxConfig {
389    fn default() -> RxConfig {
390        RxConfig {
391            fifo_full_threshold: 120,
393            timeout: Some(10),
395        }
396    }
397}
398
399#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
401#[cfg_attr(feature = "defmt", derive(defmt::Format))]
402#[non_exhaustive]
403pub struct TxConfig {
404    fifo_empty_threshold: u16,
406}
407
408impl Default for TxConfig {
409    fn default() -> TxConfig {
410        TxConfig {
411            fifo_empty_threshold: 10,
413        }
414    }
415}
416
417#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
419#[cfg_attr(feature = "defmt", derive(defmt::Format))]
420#[instability::unstable]
421#[non_exhaustive]
422pub struct AtCmdConfig {
423    pre_idle_count: Option<u16>,
426    post_idle_count: Option<u16>,
429    gap_timeout: Option<u16>,
432    cmd_char: u8,
434    char_num: u8,
436}
437
438impl Default for AtCmdConfig {
439    fn default() -> Self {
440        Self {
441            pre_idle_count: None,
442            post_idle_count: None,
443            gap_timeout: None,
444            cmd_char: b'+',
445            char_num: 1,
446        }
447    }
448}
449
450struct UartBuilder<'d, Dm: DriverMode> {
451    uart: AnyUart<'d>,
452    phantom: PhantomData<Dm>,
453}
454
455impl<'d, Dm> UartBuilder<'d, Dm>
456where
457    Dm: DriverMode,
458{
459    fn new(uart: impl Instance + 'd) -> Self {
460        Self {
461            uart: uart.degrade(),
462            phantom: PhantomData,
463        }
464    }
465
466    fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
467        let rx_guard = PeripheralGuard::new(self.uart.info().peripheral);
468        let tx_guard = PeripheralGuard::new(self.uart.info().peripheral);
469
470        let mem_guard = create_mem_guard(unsafe { self.uart.clone_unchecked() });
471
472        let rts_pin = PinGuard::new_unconnected(self.uart.info().rts_signal);
473        let tx_pin = PinGuard::new_unconnected(self.uart.info().tx_signal);
474
475        let mut serial = Uart {
476            rx: UartRx {
477                uart: unsafe { self.uart.clone_unchecked() },
478                phantom: PhantomData,
479                guard: rx_guard,
480                mem_guard: mem_guard.clone(),
481            },
482            tx: UartTx {
483                uart: self.uart,
484                phantom: PhantomData,
485                guard: tx_guard,
486                mem_guard,
487                rts_pin,
488                tx_pin,
489            },
490        };
491        serial.init(config)?;
492
493        Ok(serial)
494    }
495}
496
497#[procmacros::doc_replace]
498pub struct Uart<'d, Dm: DriverMode> {
513    rx: UartRx<'d, Dm>,
514    tx: UartTx<'d, Dm>,
515}
516
517#[instability::unstable]
519pub struct UartTx<'d, Dm: DriverMode> {
520    uart: AnyUart<'d>,
521    phantom: PhantomData<Dm>,
522    guard: PeripheralGuard,
523    mem_guard: MemoryGuard<'d>,
524    rts_pin: PinGuard,
525    tx_pin: PinGuard,
526}
527
528#[instability::unstable]
530pub struct UartRx<'d, Dm: DriverMode> {
531    uart: AnyUart<'d>,
532    phantom: PhantomData<Dm>,
533    guard: PeripheralGuard,
534    mem_guard: MemoryGuard<'d>,
535}
536
537#[derive(Debug, Clone, Copy, PartialEq, Eq)]
539#[cfg_attr(feature = "defmt", derive(defmt::Format))]
540#[non_exhaustive]
541pub enum ConfigError {
542    #[cfg(feature = "unstable")]
544    #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
545    BaudrateNotAchievable,
546
547    BaudrateNotSupported,
554
555    #[cfg_attr(esp32, doc = "127")]
557    #[cfg_attr(not(esp32), doc = "1023")]
558    TimeoutTooLong,
560
561    RxFifoThresholdNotSupported,
563
564    TxFifoThresholdNotSupported,
566}
567
568impl core::error::Error for ConfigError {}
569
570impl core::fmt::Display for ConfigError {
571    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
572        match self {
573            #[cfg(feature = "unstable")]
574            ConfigError::BaudrateNotAchievable => {
575                write!(f, "The requested baud rate is not achievable")
576            }
577            ConfigError::BaudrateNotSupported => {
578                write!(f, "The requested baud rate is not supported")
579            }
580            ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
581            ConfigError::RxFifoThresholdNotSupported => {
582                write!(f, "The requested RX FIFO threshold is not supported")
583            }
584            ConfigError::TxFifoThresholdNotSupported => {
585                write!(f, "The requested TX FIFO threshold is not supported")
586            }
587        }
588    }
589}
590
591#[instability::unstable]
592impl<Dm> embassy_embedded_hal::SetConfig for Uart<'_, Dm>
593where
594    Dm: DriverMode,
595{
596    type Config = Config;
597    type ConfigError = ConfigError;
598
599    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
600        self.apply_config(config)
601    }
602}
603
604#[instability::unstable]
605impl<Dm> embassy_embedded_hal::SetConfig for UartRx<'_, Dm>
606where
607    Dm: DriverMode,
608{
609    type Config = Config;
610    type ConfigError = ConfigError;
611
612    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
613        self.apply_config(config)
614    }
615}
616
617#[instability::unstable]
618impl<Dm> embassy_embedded_hal::SetConfig for UartTx<'_, Dm>
619where
620    Dm: DriverMode,
621{
622    type Config = Config;
623    type ConfigError = ConfigError;
624
625    fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
626        self.apply_config(config)
627    }
628}
629
630impl<'d> UartTx<'d, Blocking> {
631    #[procmacros::doc_replace]
632    #[instability::unstable]
648    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
649        let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
650
651        Ok(uart_tx)
652    }
653
654    #[instability::unstable]
656    pub fn into_async(self) -> UartTx<'d, Async> {
657        if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
658            self.uart
659                .set_interrupt_handler(self.uart.info().async_handler);
660        }
661        self.uart.state().is_tx_async.store(true, Ordering::Release);
662
663        UartTx {
664            uart: self.uart,
665            phantom: PhantomData,
666            guard: self.guard,
667            mem_guard: self.mem_guard,
668            rts_pin: self.rts_pin,
669            tx_pin: self.tx_pin,
670        }
671    }
672}
673
674impl<'d> UartTx<'d, Async> {
675    #[instability::unstable]
677    pub fn into_blocking(self) -> UartTx<'d, Blocking> {
678        self.uart
679            .state()
680            .is_tx_async
681            .store(false, Ordering::Release);
682        if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
683            self.uart.disable_peri_interrupt();
684        }
685
686        UartTx {
687            uart: self.uart,
688            phantom: PhantomData,
689            guard: self.guard,
690            mem_guard: self.mem_guard,
691            rts_pin: self.rts_pin,
692            tx_pin: self.tx_pin,
693        }
694    }
695
696    pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
712        let space = loop {
715            let tx_fifo_count = self.uart.info().tx_fifo_count();
716            let space = Info::UART_FIFO_SIZE - tx_fifo_count;
717            if space != 0 {
718                break space;
719            }
720            UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
721        };
722
723        let free = (space as usize).min(bytes.len());
724
725        for &byte in &bytes[..free] {
726            self.uart
727                .info()
728                .regs()
729                .fifo()
730                .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
731        }
732
733        Ok(free)
734    }
735
736    pub async fn flush_async(&mut self) -> Result<(), TxError> {
746        while self.uart.info().tx_fifo_count() > 0 {
750            UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
751        }
752
753        self.flush_last_byte();
754
755        Ok(())
756    }
757}
758
759impl<'d, Dm> UartTx<'d, Dm>
760where
761    Dm: DriverMode,
762{
763    #[instability::unstable]
765    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
766        let rts = rts.into();
767
768        rts.apply_output_config(&OutputConfig::default());
769        rts.set_output_enable(true);
770
771        self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
772
773        self
774    }
775
776    #[instability::unstable]
783    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
784        let tx = tx.into();
785
786        tx.set_output_high(true);
788        tx.apply_output_config(&OutputConfig::default());
789        tx.set_output_enable(true);
790
791        self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
792
793        self
794    }
795
796    #[instability::unstable]
803    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
804        self.uart
805            .info()
806            .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
807        self.uart.info().txfifo_reset();
808        Ok(())
809    }
810
811    #[instability::unstable]
815    pub fn write_ready(&mut self) -> bool {
816        self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
817    }
818
819    #[instability::unstable]
833    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
834        self.uart.info().write(data)
835    }
836
837    fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
838        while !data.is_empty() {
839            let bytes_written = self.write(data)?;
840            data = &data[bytes_written..];
841        }
842        Ok(())
843    }
844
845    #[instability::unstable]
850    pub fn flush(&mut self) -> Result<(), TxError> {
851        while self.uart.info().tx_fifo_count() > 0 {}
852        self.flush_last_byte();
853        Ok(())
854    }
855
856    fn flush_last_byte(&mut self) {
857        crate::rom::ets_delay_us(10);
863        while !self.is_tx_idle() {}
864    }
865
866    fn is_tx_idle(&self) -> bool {
871        #[cfg(esp32)]
872        let status = self.regs().status();
873        #[cfg(not(esp32))]
874        let status = self.regs().fsm_status();
875
876        status.read().st_utx_out().bits() == 0x0
877    }
878
879    fn disable_tx_interrupts(&self) {
885        self.regs().int_clr().write(|w| {
886            w.txfifo_empty().clear_bit_by_one();
887            w.tx_brk_done().clear_bit_by_one();
888            w.tx_brk_idle_done().clear_bit_by_one();
889            w.tx_done().clear_bit_by_one()
890        });
891
892        self.regs().int_ena().write(|w| {
893            w.txfifo_empty().clear_bit();
894            w.tx_brk_done().clear_bit();
895            w.tx_brk_idle_done().clear_bit();
896            w.tx_done().clear_bit()
897        });
898    }
899
900    fn regs(&self) -> &RegisterBlock {
901        self.uart.info().regs()
902    }
903}
904
905#[inline(always)]
906fn sync_regs(_register_block: &RegisterBlock) {
907    #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
908    {
909        cfg_if::cfg_if! {
910            if #[cfg(any(esp32c6, esp32h2))] {
911                let update_reg = _register_block.reg_update();
912            } else {
913                let update_reg = _register_block.id();
914            }
915        }
916
917        update_reg.modify(|_, w| w.reg_update().set_bit());
918
919        while update_reg.read().reg_update().bit_is_set() {
920            }
922    }
923}
924
925impl<'d> UartRx<'d, Blocking> {
926    #[procmacros::doc_replace]
927    #[instability::unstable]
941    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
942        let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
943
944        Ok(uart_rx)
945    }
946
947    #[instability::unstable]
949    pub fn into_async(self) -> UartRx<'d, Async> {
950        if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
951            self.uart
952                .set_interrupt_handler(self.uart.info().async_handler);
953        }
954        self.uart.state().is_rx_async.store(true, Ordering::Release);
955
956        UartRx {
957            uart: self.uart,
958            phantom: PhantomData,
959            guard: self.guard,
960            mem_guard: self.mem_guard,
961        }
962    }
963}
964
965impl<'d> UartRx<'d, Async> {
966    #[instability::unstable]
968    pub fn into_blocking(self) -> UartRx<'d, Blocking> {
969        self.uart
970            .state()
971            .is_rx_async
972            .store(false, Ordering::Release);
973        if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
974            self.uart.disable_peri_interrupt();
975        }
976
977        UartRx {
978            uart: self.uart,
979            phantom: PhantomData,
980            guard: self.guard,
981            mem_guard: self.mem_guard,
982        }
983    }
984
985    async fn wait_for_buffered_data(
986        &mut self,
987        minimum: usize,
988        preferred: usize,
989        listen_for_timeout: bool,
990    ) -> Result<(), RxError> {
991        while self.uart.info().rx_fifo_count() < (minimum as u16).min(Info::RX_FIFO_MAX_THRHD) {
992            let amount = u16::try_from(preferred)
993                .unwrap_or(Info::RX_FIFO_MAX_THRHD)
994                .min(Info::RX_FIFO_MAX_THRHD);
995
996            let current = self.uart.info().rx_fifo_full_threshold();
997            let _guard = if current > amount {
998                let info = self.uart.info();
1002                unwrap!(info.set_rx_fifo_full_threshold(amount));
1003                Some(OnDrop::new(|| {
1004                    unwrap!(info.set_rx_fifo_full_threshold(current));
1005                }))
1006            } else {
1007                None
1008            };
1009
1010            let mut events = RxEvent::FifoFull
1012                | RxEvent::FifoOvf
1013                | RxEvent::FrameError
1014                | RxEvent::GlitchDetected
1015                | RxEvent::ParityError;
1016
1017            if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1018                events |= RxEvent::CmdCharDetected;
1019            }
1020
1021            cfg_if::cfg_if! {
1022                if #[cfg(any(esp32c6, esp32h2))] {
1023                    let reg_en = self.regs().tout_conf();
1024                } else {
1025                    let reg_en = self.regs().conf1();
1026                }
1027            };
1028            if listen_for_timeout && reg_en.read().rx_tout_en().bit_is_set() {
1029                events |= RxEvent::FifoTout;
1030            }
1031
1032            let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1033
1034            let result = rx_event_check_for_error(events);
1035            if let Err(error) = result {
1036                if error == RxError::FifoOverflowed {
1037                    self.uart.info().rxfifo_reset();
1038                }
1039                return Err(error);
1040            }
1041        }
1042
1043        Ok(())
1044    }
1045
1046    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1065        if buf.is_empty() {
1066            return Ok(0);
1067        }
1068
1069        self.wait_for_buffered_data(1, buf.len(), true).await?;
1070
1071        self.read_buffered(buf)
1072    }
1073
1074    pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1089        while !buf.is_empty() {
1090            self.wait_for_buffered_data(buf.len(), buf.len(), false)
1094                .await?;
1095
1096            let read = self.uart.info().read_buffered(buf)?;
1097            buf = &mut buf[read..];
1098        }
1099
1100        Ok(())
1101    }
1102}
1103
1104impl<'d, Dm> UartRx<'d, Dm>
1105where
1106    Dm: DriverMode,
1107{
1108    fn regs(&self) -> &RegisterBlock {
1109        self.uart.info().regs()
1110    }
1111
1112    #[instability::unstable]
1116    pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1117        let cts = cts.into();
1118
1119        cts.apply_input_config(&InputConfig::default());
1120        cts.set_input_enable(true);
1121
1122        self.uart.info().cts_signal.connect_to(&cts);
1123
1124        self
1125    }
1126
1127    #[instability::unstable]
1136    pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1137        let rx = rx.into();
1138
1139        rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1140        rx.set_input_enable(true);
1141
1142        self.uart.info().rx_signal.connect_to(&rx);
1143
1144        self
1145    }
1146
1147    #[instability::unstable]
1154    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1155        self.uart
1156            .info()
1157            .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1158        self.uart
1159            .info()
1160            .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1161
1162        self.uart.info().rxfifo_reset();
1163        Ok(())
1164    }
1165
1166    #[instability::unstable]
1170    pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1171        self.uart.info().check_for_errors()
1172    }
1173
1174    #[instability::unstable]
1178    pub fn read_ready(&mut self) -> bool {
1179        self.uart.info().rx_fifo_count() > 0
1180    }
1181
1182    #[instability::unstable]
1201    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1202        self.uart.info().read(buf)
1203    }
1204
1205    #[instability::unstable]
1223    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1224        self.uart.info().read_buffered(buf)
1225    }
1226
1227    fn disable_rx_interrupts(&self) {
1233        self.regs().int_clr().write(|w| {
1234            w.rxfifo_full().clear_bit_by_one();
1235            w.rxfifo_ovf().clear_bit_by_one();
1236            w.rxfifo_tout().clear_bit_by_one();
1237            w.at_cmd_char_det().clear_bit_by_one()
1238        });
1239
1240        self.regs().int_ena().write(|w| {
1241            w.rxfifo_full().clear_bit();
1242            w.rxfifo_ovf().clear_bit();
1243            w.rxfifo_tout().clear_bit();
1244            w.at_cmd_char_det().clear_bit()
1245        });
1246    }
1247}
1248
1249impl<'d> Uart<'d, Blocking> {
1250    #[procmacros::doc_replace]
1251    pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1269        UartBuilder::new(uart).init(config)
1270    }
1271
1272    pub fn into_async(self) -> Uart<'d, Async> {
1277        Uart {
1278            rx: self.rx.into_async(),
1279            tx: self.tx.into_async(),
1280        }
1281    }
1282
1283    #[cfg_attr(
1284        not(multi_core),
1285        doc = "Registers an interrupt handler for the peripheral."
1286    )]
1287    #[cfg_attr(
1288        multi_core,
1289        doc = "Registers an interrupt handler for the peripheral on the current core."
1290    )]
1291    #[doc = ""]
1292    #[instability::unstable]
1298    pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1299        self.tx.uart.set_interrupt_handler(handler);
1301    }
1302
1303    #[procmacros::doc_replace]
1304    #[instability::unstable]
1371    pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1372        self.tx.uart.info().enable_listen(interrupts.into(), true)
1373    }
1374
1375    #[instability::unstable]
1377    pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1378        self.tx.uart.info().enable_listen(interrupts.into(), false)
1379    }
1380
1381    #[instability::unstable]
1383    pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1384        self.tx.uart.info().interrupts()
1385    }
1386
1387    #[instability::unstable]
1389    pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1390        self.tx.uart.info().clear_interrupts(interrupts)
1391    }
1392}
1393
1394impl<'d> Uart<'d, Async> {
1395    pub fn into_blocking(self) -> Uart<'d, Blocking> {
1400        Uart {
1401            rx: self.rx.into_blocking(),
1402            tx: self.tx.into_blocking(),
1403        }
1404    }
1405
1406    #[procmacros::doc_replace]
1407    pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1438        self.tx.write_async(words).await
1439    }
1440
1441    #[procmacros::doc_replace]
1442    pub async fn flush_async(&mut self) -> Result<(), TxError> {
1468        self.tx.flush_async().await
1469    }
1470
1471    #[procmacros::doc_replace]
1472    pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1510        self.rx.read_async(buf).await
1511    }
1512
1513    #[instability::unstable]
1528    pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1529        self.rx.read_exact_async(buf).await
1530    }
1531}
1532
1533#[derive(Debug, EnumSetType)]
1535#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1536#[non_exhaustive]
1537#[instability::unstable]
1538pub enum UartInterrupt {
1539    AtCmd,
1542
1543    TxDone,
1545
1546    RxFifoFull,
1549
1550    RxTimeout,
1553}
1554
1555impl<'d, Dm> Uart<'d, Dm>
1556where
1557    Dm: DriverMode,
1558{
1559    #[procmacros::doc_replace]
1560    pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1579        self.rx = self.rx.with_rx(rx);
1580        self
1581    }
1582
1583    #[procmacros::doc_replace]
1584    pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1599        self.tx = self.tx.with_tx(tx);
1600        self
1601    }
1602
1603    #[procmacros::doc_replace]
1604    pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1618        self.rx = self.rx.with_cts(cts);
1619        self
1620    }
1621
1622    #[procmacros::doc_replace]
1623    pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1637        self.tx = self.tx.with_rts(rts);
1638        self
1639    }
1640
1641    fn regs(&self) -> &RegisterBlock {
1642        self.tx.uart.info().regs()
1644    }
1645
1646    #[instability::unstable]
1650    pub fn write_ready(&mut self) -> bool {
1651        self.tx.write_ready()
1652    }
1653
1654    #[procmacros::doc_replace]
1655    pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
1681        self.tx.write(data)
1682    }
1683
1684    #[procmacros::doc_replace]
1685    pub fn flush(&mut self) -> Result<(), TxError> {
1700        self.tx.flush()
1701    }
1702
1703    #[instability::unstable]
1707    pub fn read_ready(&mut self) -> bool {
1708        self.rx.read_ready()
1709    }
1710
1711    #[procmacros::doc_replace]
1712    pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1747        self.rx.read(buf)
1748    }
1749
1750    #[procmacros::doc_replace]
1751    pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1769        self.rx.uart.info().apply_config(config)?;
1772        self.rx.apply_config(config)?;
1773        self.tx.apply_config(config)?;
1774        Ok(())
1775    }
1776
1777    #[procmacros::doc_replace]
1778    #[instability::unstable]
1802    pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
1803        (self.rx, self.tx)
1804    }
1805
1806    #[instability::unstable]
1808    pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
1809        self.rx.check_for_errors()
1810    }
1811
1812    #[instability::unstable]
1829    pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1830        self.rx.read_buffered(buf)
1831    }
1832
1833    #[instability::unstable]
1835    pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
1836        #[cfg(not(any(esp32, esp32s2)))]
1837        self.regs()
1838            .clk_conf()
1839            .modify(|_, w| w.sclk_en().clear_bit());
1840
1841        self.regs().at_cmd_char().write(|w| unsafe {
1842            w.at_cmd_char().bits(config.cmd_char);
1843            w.char_num().bits(config.char_num)
1844        });
1845
1846        if let Some(pre_idle_count) = config.pre_idle_count {
1847            self.regs()
1848                .at_cmd_precnt()
1849                .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
1850        }
1851
1852        if let Some(post_idle_count) = config.post_idle_count {
1853            self.regs()
1854                .at_cmd_postcnt()
1855                .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
1856        }
1857
1858        if let Some(gap_timeout) = config.gap_timeout {
1859            self.regs()
1860                .at_cmd_gaptout()
1861                .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
1862        }
1863
1864        #[cfg(not(any(esp32, esp32s2)))]
1865        self.regs().clk_conf().modify(|_, w| w.sclk_en().set_bit());
1866
1867        sync_regs(self.regs());
1868    }
1869
1870    #[inline(always)]
1871    fn init(&mut self, config: Config) -> Result<(), ConfigError> {
1872        self.rx.disable_rx_interrupts();
1873        self.tx.disable_tx_interrupts();
1874
1875        self.apply_config(&config)?;
1876
1877        self.rx.uart.info().rxfifo_reset();
1879        self.rx.uart.info().txfifo_reset();
1880
1881        self.regs()
1884            .idle_conf()
1885            .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
1886
1887        self.regs().conf0().modify(|_, w| w.err_wr_mask().set_bit());
1890
1891        crate::rom::ets_delay_us(15);
1892
1893        self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
1896
1897        Ok(())
1898    }
1899}
1900
1901impl crate::private::Sealed for Uart<'_, Blocking> {}
1902
1903#[instability::unstable]
1904impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> {
1905    fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1906        self.tx.uart.set_interrupt_handler(handler);
1908    }
1909}
1910
1911#[instability::unstable]
1912impl<Dm> ufmt_write::uWrite for Uart<'_, Dm>
1913where
1914    Dm: DriverMode,
1915{
1916    type Error = TxError;
1917
1918    #[inline]
1919    fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1920        self.tx.write_str(s)
1921    }
1922
1923    #[inline]
1924    fn write_char(&mut self, ch: char) -> Result<(), Self::Error> {
1925        self.tx.write_char(ch)
1926    }
1927}
1928
1929#[instability::unstable]
1930impl<Dm> ufmt_write::uWrite for UartTx<'_, Dm>
1931where
1932    Dm: DriverMode,
1933{
1934    type Error = TxError;
1935
1936    #[inline]
1937    fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
1938        self.write_all(s.as_bytes())
1939    }
1940}
1941
1942impl<Dm> core::fmt::Write for Uart<'_, Dm>
1943where
1944    Dm: DriverMode,
1945{
1946    #[inline]
1947    fn write_str(&mut self, s: &str) -> core::fmt::Result {
1948        self.tx.write_str(s)
1949    }
1950}
1951
1952impl<Dm> core::fmt::Write for UartTx<'_, Dm>
1953where
1954    Dm: DriverMode,
1955{
1956    #[inline]
1957    fn write_str(&mut self, s: &str) -> core::fmt::Result {
1958        self.write_all(s.as_bytes()).map_err(|_| core::fmt::Error)
1959    }
1960}
1961
1962#[instability::unstable]
1964#[derive(Debug, Clone, Copy, PartialEq)]
1965#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1966#[non_exhaustive]
1967pub enum IoError {
1968    Tx(TxError),
1970    Rx(RxError),
1972}
1973
1974#[instability::unstable]
1975impl core::error::Error for IoError {}
1976
1977#[instability::unstable]
1978impl core::fmt::Display for IoError {
1979    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1980        match self {
1981            IoError::Tx(e) => e.fmt(f),
1982            IoError::Rx(e) => e.fmt(f),
1983        }
1984    }
1985}
1986
1987#[instability::unstable]
1988impl embedded_io_06::Error for IoError {
1989    fn kind(&self) -> embedded_io_06::ErrorKind {
1990        embedded_io_06::ErrorKind::Other
1991    }
1992}
1993
1994#[instability::unstable]
1995impl embedded_io_07::Error for IoError {
1996    fn kind(&self) -> embedded_io_07::ErrorKind {
1997        embedded_io_07::ErrorKind::Other
1998    }
1999}
2000
2001#[instability::unstable]
2002impl From<RxError> for IoError {
2003    fn from(e: RxError) -> Self {
2004        IoError::Rx(e)
2005    }
2006}
2007
2008#[instability::unstable]
2009impl From<TxError> for IoError {
2010    fn from(e: TxError) -> Self {
2011        IoError::Tx(e)
2012    }
2013}
2014
2015#[instability::unstable]
2016impl<Dm: DriverMode> embedded_io_06::ErrorType for Uart<'_, Dm> {
2017    type Error = IoError;
2018}
2019
2020#[instability::unstable]
2021impl<Dm: DriverMode> embedded_io_06::ErrorType for UartTx<'_, Dm> {
2022    type Error = TxError;
2023}
2024
2025#[instability::unstable]
2026impl<Dm: DriverMode> embedded_io_06::ErrorType for UartRx<'_, Dm> {
2027    type Error = RxError;
2028}
2029
2030#[instability::unstable]
2031impl<Dm> embedded_io_06::Read for Uart<'_, Dm>
2032where
2033    Dm: DriverMode,
2034{
2035    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2036        self.rx.read(buf).map_err(IoError::Rx)
2037    }
2038}
2039
2040#[instability::unstable]
2041impl<Dm> embedded_io_06::Read for UartRx<'_, Dm>
2042where
2043    Dm: DriverMode,
2044{
2045    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2046        self.read(buf)
2047    }
2048}
2049
2050#[instability::unstable]
2051impl<Dm> embedded_io_06::ReadReady for Uart<'_, Dm>
2052where
2053    Dm: DriverMode,
2054{
2055    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2056        Ok(self.rx.read_ready())
2057    }
2058}
2059
2060#[instability::unstable]
2061impl<Dm> embedded_io_06::ReadReady for UartRx<'_, Dm>
2062where
2063    Dm: DriverMode,
2064{
2065    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2066        Ok(self.read_ready())
2067    }
2068}
2069
2070#[instability::unstable]
2071impl<Dm> embedded_io_06::Write for Uart<'_, Dm>
2072where
2073    Dm: DriverMode,
2074{
2075    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2076        self.tx.write(buf).map_err(IoError::Tx)
2077    }
2078
2079    fn flush(&mut self) -> Result<(), Self::Error> {
2080        self.tx.flush().map_err(IoError::Tx)
2081    }
2082}
2083
2084#[instability::unstable]
2085impl<Dm> embedded_io_06::Write for UartTx<'_, Dm>
2086where
2087    Dm: DriverMode,
2088{
2089    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2090        self.write(buf)
2091    }
2092
2093    fn flush(&mut self) -> Result<(), Self::Error> {
2094        self.flush()
2095    }
2096}
2097
2098#[instability::unstable]
2099impl<Dm> embedded_io_06::WriteReady for UartTx<'_, Dm>
2100where
2101    Dm: DriverMode,
2102{
2103    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2104        Ok(self.write_ready())
2105    }
2106}
2107
2108#[instability::unstable]
2109impl<Dm> embedded_io_06::WriteReady for Uart<'_, Dm>
2110where
2111    Dm: DriverMode,
2112{
2113    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2114        Ok(self.tx.write_ready())
2115    }
2116}
2117
2118#[instability::unstable]
2119impl<Dm: DriverMode> embedded_io_07::ErrorType for Uart<'_, Dm> {
2120    type Error = IoError;
2121}
2122
2123#[instability::unstable]
2124impl<Dm: DriverMode> embedded_io_07::ErrorType for UartTx<'_, Dm> {
2125    type Error = TxError;
2126}
2127
2128#[instability::unstable]
2129impl<Dm: DriverMode> embedded_io_07::ErrorType for UartRx<'_, Dm> {
2130    type Error = RxError;
2131}
2132
2133#[instability::unstable]
2134impl<Dm> embedded_io_07::Read for Uart<'_, Dm>
2135where
2136    Dm: DriverMode,
2137{
2138    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2139        self.rx.read(buf).map_err(IoError::Rx)
2140    }
2141}
2142
2143#[instability::unstable]
2144impl<Dm> embedded_io_07::Read for UartRx<'_, Dm>
2145where
2146    Dm: DriverMode,
2147{
2148    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2149        self.read(buf)
2150    }
2151}
2152
2153#[instability::unstable]
2154impl<Dm> embedded_io_07::ReadReady for Uart<'_, Dm>
2155where
2156    Dm: DriverMode,
2157{
2158    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2159        Ok(self.rx.read_ready())
2160    }
2161}
2162
2163#[instability::unstable]
2164impl<Dm> embedded_io_07::ReadReady for UartRx<'_, Dm>
2165where
2166    Dm: DriverMode,
2167{
2168    fn read_ready(&mut self) -> Result<bool, Self::Error> {
2169        Ok(self.read_ready())
2170    }
2171}
2172
2173#[instability::unstable]
2174impl<Dm> embedded_io_07::Write for Uart<'_, Dm>
2175where
2176    Dm: DriverMode,
2177{
2178    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2179        self.tx.write(buf).map_err(IoError::Tx)
2180    }
2181
2182    fn flush(&mut self) -> Result<(), Self::Error> {
2183        self.tx.flush().map_err(IoError::Tx)
2184    }
2185}
2186
2187#[instability::unstable]
2188impl<Dm> embedded_io_07::Write for UartTx<'_, Dm>
2189where
2190    Dm: DriverMode,
2191{
2192    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2193        self.write(buf)
2194    }
2195
2196    fn flush(&mut self) -> Result<(), Self::Error> {
2197        self.flush()
2198    }
2199}
2200
2201#[instability::unstable]
2202impl<Dm> embedded_io_07::WriteReady for UartTx<'_, Dm>
2203where
2204    Dm: DriverMode,
2205{
2206    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2207        Ok(self.write_ready())
2208    }
2209}
2210
2211#[instability::unstable]
2212impl<Dm> embedded_io_07::WriteReady for Uart<'_, Dm>
2213where
2214    Dm: DriverMode,
2215{
2216    fn write_ready(&mut self) -> Result<bool, Self::Error> {
2217        Ok(self.tx.write_ready())
2218    }
2219}
2220
2221#[derive(Debug, EnumSetType)]
2222pub(crate) enum TxEvent {
2223    Done,
2224    FiFoEmpty,
2225}
2226
2227#[derive(Debug, EnumSetType)]
2228pub(crate) enum RxEvent {
2229    FifoFull,
2230    CmdCharDetected,
2231    FifoOvf,
2232    FifoTout,
2233    GlitchDetected,
2234    FrameError,
2235    ParityError,
2236}
2237
2238fn rx_event_check_for_error(events: EnumSet<RxEvent>) -> Result<(), RxError> {
2239    for event in events {
2240        match event {
2241            RxEvent::FifoOvf => return Err(RxError::FifoOverflowed),
2242            RxEvent::GlitchDetected => return Err(RxError::GlitchOccurred),
2243            RxEvent::FrameError => return Err(RxError::FrameFormatViolated),
2244            RxEvent::ParityError => return Err(RxError::ParityMismatch),
2245            RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => continue,
2246        }
2247    }
2248
2249    Ok(())
2250}
2251
2252#[must_use = "futures do nothing unless you `.await` or poll them"]
2258struct UartRxFuture {
2259    events: EnumSet<RxEvent>,
2260    uart: &'static Info,
2261    state: &'static State,
2262    registered: bool,
2263}
2264
2265impl UartRxFuture {
2266    fn new(uart: impl Instance, events: impl Into<EnumSet<RxEvent>>) -> Self {
2267        Self {
2268            events: events.into(),
2269            uart: uart.info(),
2270            state: uart.state(),
2271            registered: false,
2272        }
2273    }
2274}
2275
2276impl core::future::Future for UartRxFuture {
2277    type Output = EnumSet<RxEvent>;
2278
2279    fn poll(
2280        mut self: core::pin::Pin<&mut Self>,
2281        cx: &mut core::task::Context<'_>,
2282    ) -> core::task::Poll<Self::Output> {
2283        let events = self.uart.rx_events().intersection(self.events);
2284        if !events.is_empty() {
2285            self.uart.clear_rx_events(events);
2286            Poll::Ready(events)
2287        } else {
2288            self.state.rx_waker.register(cx.waker());
2289            if !self.registered {
2290                self.uart.enable_listen_rx(self.events, true);
2291                self.registered = true;
2292            }
2293            Poll::Pending
2294        }
2295    }
2296}
2297
2298impl Drop for UartRxFuture {
2299    fn drop(&mut self) {
2300        self.uart.enable_listen_rx(self.events, false);
2304    }
2305}
2306
2307#[must_use = "futures do nothing unless you `.await` or poll them"]
2308struct UartTxFuture {
2309    events: EnumSet<TxEvent>,
2310    uart: &'static Info,
2311    state: &'static State,
2312    registered: bool,
2313}
2314
2315impl UartTxFuture {
2316    fn new(uart: impl Instance, events: impl Into<EnumSet<TxEvent>>) -> Self {
2317        Self {
2318            events: events.into(),
2319            uart: uart.info(),
2320            state: uart.state(),
2321            registered: false,
2322        }
2323    }
2324}
2325
2326impl core::future::Future for UartTxFuture {
2327    type Output = ();
2328
2329    fn poll(
2330        mut self: core::pin::Pin<&mut Self>,
2331        cx: &mut core::task::Context<'_>,
2332    ) -> core::task::Poll<Self::Output> {
2333        let events = self.uart.tx_events().intersection(self.events);
2334        if !events.is_empty() {
2335            self.uart.clear_tx_events(events);
2336            Poll::Ready(())
2337        } else {
2338            self.state.tx_waker.register(cx.waker());
2339            if !self.registered {
2340                self.uart.enable_listen_tx(self.events, true);
2341                self.registered = true;
2342            }
2343            Poll::Pending
2344        }
2345    }
2346}
2347
2348impl Drop for UartTxFuture {
2349    fn drop(&mut self) {
2350        self.uart.enable_listen_tx(self.events, false);
2354    }
2355}
2356
2357#[instability::unstable]
2358impl embedded_io_async_06::Read for Uart<'_, Async> {
2359    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2360        self.read_async(buf).await.map_err(IoError::Rx)
2361    }
2362
2363    async fn read_exact(
2364        &mut self,
2365        buf: &mut [u8],
2366    ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2367        self.read_exact_async(buf)
2368            .await
2369            .map_err(|e| embedded_io_06::ReadExactError::Other(IoError::Rx(e)))
2370    }
2371}
2372
2373#[instability::unstable]
2374impl embedded_io_async_06::Read for UartRx<'_, Async> {
2375    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2376        self.read_async(buf).await
2377    }
2378
2379    async fn read_exact(
2380        &mut self,
2381        buf: &mut [u8],
2382    ) -> Result<(), embedded_io_06::ReadExactError<Self::Error>> {
2383        self.read_exact_async(buf)
2384            .await
2385            .map_err(embedded_io_06::ReadExactError::Other)
2386    }
2387}
2388
2389#[instability::unstable]
2390impl embedded_io_async_06::Write for Uart<'_, Async> {
2391    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2392        self.write_async(buf).await.map_err(IoError::Tx)
2393    }
2394
2395    async fn flush(&mut self) -> Result<(), Self::Error> {
2396        self.flush_async().await.map_err(IoError::Tx)
2397    }
2398}
2399
2400#[instability::unstable]
2401impl embedded_io_async_06::Write for UartTx<'_, Async> {
2402    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2403        self.write_async(buf).await
2404    }
2405
2406    async fn flush(&mut self) -> Result<(), Self::Error> {
2407        self.flush_async().await
2408    }
2409}
2410
2411#[instability::unstable]
2412impl embedded_io_async_07::Read for Uart<'_, Async> {
2413    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2414        self.read_async(buf).await.map_err(IoError::Rx)
2415    }
2416
2417    async fn read_exact(
2418        &mut self,
2419        buf: &mut [u8],
2420    ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2421        self.read_exact_async(buf)
2422            .await
2423            .map_err(|e| embedded_io_07::ReadExactError::Other(IoError::Rx(e)))
2424    }
2425}
2426
2427#[instability::unstable]
2428impl embedded_io_async_07::Read for UartRx<'_, Async> {
2429    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
2430        self.read_async(buf).await
2431    }
2432
2433    async fn read_exact(
2434        &mut self,
2435        buf: &mut [u8],
2436    ) -> Result<(), embedded_io_07::ReadExactError<Self::Error>> {
2437        self.read_exact_async(buf)
2438            .await
2439            .map_err(embedded_io_07::ReadExactError::Other)
2440    }
2441}
2442
2443#[instability::unstable]
2444impl embedded_io_async_07::Write for Uart<'_, Async> {
2445    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2446        self.write_async(buf).await.map_err(IoError::Tx)
2447    }
2448
2449    async fn flush(&mut self) -> Result<(), Self::Error> {
2450        self.flush_async().await.map_err(IoError::Tx)
2451    }
2452}
2453
2454#[instability::unstable]
2455impl embedded_io_async_07::Write for UartTx<'_, Async> {
2456    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
2457        self.write_async(buf).await
2458    }
2459
2460    async fn flush(&mut self) -> Result<(), Self::Error> {
2461        self.flush_async().await
2462    }
2463}
2464
2465pub(super) fn intr_handler(uart: &Info, state: &State) {
2470    let interrupts = uart.regs().int_st().read();
2471    let interrupt_bits = interrupts.bits(); let rx_wake = interrupts.rxfifo_full().bit_is_set()
2473        | interrupts.rxfifo_ovf().bit_is_set()
2474        | interrupts.rxfifo_tout().bit_is_set()
2475        | interrupts.at_cmd_char_det().bit_is_set()
2476        | interrupts.glitch_det().bit_is_set()
2477        | interrupts.frm_err().bit_is_set()
2478        | interrupts.parity_err().bit_is_set();
2479    let tx_wake = interrupts.tx_done().bit_is_set() | interrupts.txfifo_empty().bit_is_set();
2480
2481    uart.regs()
2482        .int_ena()
2483        .modify(|r, w| unsafe { w.bits(r.bits() & !interrupt_bits) });
2484
2485    if tx_wake {
2486        state.tx_waker.wake();
2487    }
2488    if rx_wake {
2489        state.rx_waker.wake();
2490    }
2491}
2492
2493#[cfg(lp_uart)]
2495#[instability::unstable]
2496pub mod lp_uart {
2497    use crate::{
2498        gpio::lp_io::{LowPowerInput, LowPowerOutput},
2499        peripherals::{LP_AON, LP_IO, LP_UART, LPWR},
2500        uart::{Config, DataBits, Parity, StopBits},
2501    };
2502    pub struct LpUart {
2506        uart: LP_UART<'static>,
2507    }
2508
2509    impl LpUart {
2510        pub fn new(
2519            uart: LP_UART<'static>,
2520            config: Config,
2521            _tx: LowPowerOutput<'_, 5>,
2522            _rx: LowPowerInput<'_, 4>,
2523        ) -> Self {
2524            LP_AON::regs()
2526                .gpio_mux()
2527                .modify(|r, w| unsafe { w.sel().bits(r.sel().bits() | (1 << 4) | (1 << 5)) });
2528
2529            LP_IO::regs()
2530                .gpio(4)
2531                .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2532            LP_IO::regs()
2533                .gpio(5)
2534                .modify(|_, w| unsafe { w.mcu_sel().bits(1) });
2535
2536            let mut me = Self { uart };
2537            let uart = me.uart.register_block();
2538
2539            uart.conf0().modify(|_, w| unsafe {
2545                w.parity().clear_bit();
2546                w.parity_en().clear_bit();
2547                w.bit_num().bits(0x3);
2548                w.stop_bit_num().bits(0x1)
2549            });
2550            uart.idle_conf()
2552                .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2553            uart.hwfc_conf().modify(|_, w| w.rx_flow_en().clear_bit());
2555
2556            LPWR::regs()
2561                .lpperi()
2562                .modify(|_, w| w.lp_uart_clk_sel().clear_bit());
2563
2564            me.change_baud_internal(&config);
2567            me.change_parity(config.parity);
2569            me.change_data_bits(config.data_bits);
2571            me.change_stop_bits(config.stop_bits);
2573            me.change_tx_idle(0); me.rxfifo_reset();
2578            me.txfifo_reset();
2579
2580            me
2581        }
2582
2583        fn rxfifo_reset(&mut self) {
2584            self.uart
2585                .register_block()
2586                .conf0()
2587                .modify(|_, w| w.rxfifo_rst().set_bit());
2588            self.update();
2589
2590            self.uart
2591                .register_block()
2592                .conf0()
2593                .modify(|_, w| w.rxfifo_rst().clear_bit());
2594            self.update();
2595        }
2596
2597        fn txfifo_reset(&mut self) {
2598            self.uart
2599                .register_block()
2600                .conf0()
2601                .modify(|_, w| w.txfifo_rst().set_bit());
2602            self.update();
2603
2604            self.uart
2605                .register_block()
2606                .conf0()
2607                .modify(|_, w| w.txfifo_rst().clear_bit());
2608            self.update();
2609        }
2610
2611        fn update(&mut self) {
2612            let register_block = self.uart.register_block();
2613            register_block
2614                .reg_update()
2615                .modify(|_, w| w.reg_update().set_bit());
2616            while register_block.reg_update().read().reg_update().bit_is_set() {
2617                }
2619        }
2620
2621        fn change_baud_internal(&mut self, config: &Config) {
2622            let clk = 16_000_000_u32;
2624            let max_div = 0b1111_1111_1111 - 1;
2625            let clk_div = clk.div_ceil(max_div * config.baudrate);
2626
2627            self.uart.register_block().clk_conf().modify(|_, w| unsafe {
2628                w.sclk_div_a().bits(0);
2629                w.sclk_div_b().bits(0);
2630                w.sclk_div_num().bits(clk_div as u8 - 1);
2631                w.sclk_sel().bits(match config.clock_source {
2632                    super::ClockSource::Xtal => 3,
2633                    super::ClockSource::RcFast => 2,
2634                    super::ClockSource::Apb => panic!("Wrong clock source for LP_UART"),
2635                });
2636                w.sclk_en().set_bit()
2637            });
2638
2639            let clk = clk / clk_div;
2640            let divider = clk / config.baudrate;
2641            let divider = divider as u16;
2642
2643            self.uart
2644                .register_block()
2645                .clkdiv()
2646                .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
2647
2648            self.update();
2649        }
2650
2651        pub fn change_baud(&mut self, config: &Config) {
2659            self.change_baud_internal(config);
2660            self.txfifo_reset();
2661            self.rxfifo_reset();
2662        }
2663
2664        fn change_parity(&mut self, parity: Parity) -> &mut Self {
2665            if parity != Parity::None {
2666                self.uart
2667                    .register_block()
2668                    .conf0()
2669                    .modify(|_, w| w.parity().bit((parity as u8 & 0x1) != 0));
2670            }
2671
2672            self.uart
2673                .register_block()
2674                .conf0()
2675                .modify(|_, w| match parity {
2676                    Parity::None => w.parity_en().clear_bit(),
2677                    Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
2678                    Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
2679                });
2680
2681            self
2682        }
2683
2684        fn change_data_bits(&mut self, data_bits: DataBits) -> &mut Self {
2685            self.uart
2686                .register_block()
2687                .conf0()
2688                .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
2689
2690            self.update();
2691            self
2692        }
2693
2694        fn change_stop_bits(&mut self, stop_bits: StopBits) -> &mut Self {
2695            self.uart
2696                .register_block()
2697                .conf0()
2698                .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
2699
2700            self.update();
2701            self
2702        }
2703
2704        fn change_tx_idle(&mut self, idle_num: u16) -> &mut Self {
2705            self.uart
2706                .register_block()
2707                .idle_conf()
2708                .modify(|_, w| unsafe { w.tx_idle_num().bits(idle_num) });
2709
2710            self.update();
2711            self
2712        }
2713    }
2714}
2715
2716pub trait Instance: crate::private::Sealed + any::Degrade {
2718    #[doc(hidden)]
2719    fn parts(&self) -> (&'static Info, &'static State);
2721
2722    #[inline(always)]
2724    #[doc(hidden)]
2725    fn info(&self) -> &'static Info {
2726        self.parts().0
2727    }
2728
2729    #[inline(always)]
2731    #[doc(hidden)]
2732    fn state(&self) -> &'static State {
2733        self.parts().1
2734    }
2735}
2736
2737#[doc(hidden)]
2739#[non_exhaustive]
2740pub struct Info {
2741    pub register_block: *const RegisterBlock,
2745
2746    pub peripheral: crate::system::Peripheral,
2748
2749    pub async_handler: InterruptHandler,
2751
2752    pub tx_signal: OutputSignal,
2754
2755    pub rx_signal: InputSignal,
2757
2758    pub cts_signal: InputSignal,
2760
2761    pub rts_signal: OutputSignal,
2763}
2764
2765#[doc(hidden)]
2767#[non_exhaustive]
2768pub struct State {
2769    pub rx_waker: AtomicWaker,
2771
2772    pub tx_waker: AtomicWaker,
2774
2775    pub is_rx_async: AtomicBool,
2777
2778    pub is_tx_async: AtomicBool,
2780
2781    #[cfg(uart_peripheral_controls_mem_clk)]
2783    pub mem_ref_count: AtomicUsize,
2784}
2785
2786impl Info {
2787    const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
2790    const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
2791    const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
2792
2793    pub fn regs(&self) -> &RegisterBlock {
2795        unsafe { &*self.register_block }
2796    }
2797
2798    fn enable_listen(&self, interrupts: EnumSet<UartInterrupt>, enable: bool) {
2800        let reg_block = self.regs();
2801
2802        reg_block.int_ena().modify(|_, w| {
2803            for interrupt in interrupts {
2804                match interrupt {
2805                    UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable),
2806                    UartInterrupt::TxDone => w.tx_done().bit(enable),
2807                    UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable),
2808                    UartInterrupt::RxTimeout => w.rxfifo_tout().bit(enable),
2809                };
2810            }
2811            w
2812        });
2813    }
2814
2815    fn interrupts(&self) -> EnumSet<UartInterrupt> {
2816        let mut res = EnumSet::new();
2817        let reg_block = self.regs();
2818
2819        let ints = reg_block.int_raw().read();
2820
2821        if ints.at_cmd_char_det().bit_is_set() {
2822            res.insert(UartInterrupt::AtCmd);
2823        }
2824        if ints.tx_done().bit_is_set() {
2825            res.insert(UartInterrupt::TxDone);
2826        }
2827        if ints.rxfifo_full().bit_is_set() {
2828            res.insert(UartInterrupt::RxFifoFull);
2829        }
2830        if ints.rxfifo_tout().bit_is_set() {
2831            res.insert(UartInterrupt::RxTimeout);
2832        }
2833
2834        res
2835    }
2836
2837    fn clear_interrupts(&self, interrupts: EnumSet<UartInterrupt>) {
2838        let reg_block = self.regs();
2839
2840        reg_block.int_clr().write(|w| {
2841            for interrupt in interrupts {
2842                match interrupt {
2843                    UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(),
2844                    UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(),
2845                    UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(),
2846                    UartInterrupt::RxTimeout => w.rxfifo_tout().clear_bit_by_one(),
2847                };
2848            }
2849            w
2850        });
2851    }
2852
2853    fn apply_config(&self, config: &Config) -> Result<(), ConfigError> {
2854        config.validate()?;
2855        self.change_baud(config)?;
2856        self.change_data_bits(config.data_bits);
2857        self.change_parity(config.parity);
2858        self.change_stop_bits(config.stop_bits);
2859        self.change_flow_control(config.sw_flow_ctrl, config.hw_flow_ctrl);
2860
2861        Ok(())
2862    }
2863
2864    fn enable_listen_tx(&self, events: EnumSet<TxEvent>, enable: bool) {
2865        self.regs().int_ena().modify(|_, w| {
2866            for event in events {
2867                match event {
2868                    TxEvent::Done => w.tx_done().bit(enable),
2869                    TxEvent::FiFoEmpty => w.txfifo_empty().bit(enable),
2870                };
2871            }
2872            w
2873        });
2874    }
2875
2876    fn tx_events(&self) -> EnumSet<TxEvent> {
2877        let pending_interrupts = self.regs().int_raw().read();
2878        let mut active_events = EnumSet::new();
2879
2880        if pending_interrupts.tx_done().bit_is_set() {
2881            active_events |= TxEvent::Done;
2882        }
2883        if pending_interrupts.txfifo_empty().bit_is_set() {
2884            active_events |= TxEvent::FiFoEmpty;
2885        }
2886
2887        active_events
2888    }
2889
2890    fn clear_tx_events(&self, events: impl Into<EnumSet<TxEvent>>) {
2891        let events = events.into();
2892        self.regs().int_clr().write(|w| {
2893            for event in events {
2894                match event {
2895                    TxEvent::FiFoEmpty => w.txfifo_empty().clear_bit_by_one(),
2896                    TxEvent::Done => w.tx_done().clear_bit_by_one(),
2897                };
2898            }
2899            w
2900        });
2901    }
2902
2903    fn enable_listen_rx(&self, events: EnumSet<RxEvent>, enable: bool) {
2904        self.regs().int_ena().modify(|_, w| {
2905            for event in events {
2906                match event {
2907                    RxEvent::FifoFull => w.rxfifo_full().bit(enable),
2908                    RxEvent::CmdCharDetected => w.at_cmd_char_det().bit(enable),
2909
2910                    RxEvent::FifoOvf => w.rxfifo_ovf().bit(enable),
2911                    RxEvent::FifoTout => w.rxfifo_tout().bit(enable),
2912                    RxEvent::GlitchDetected => w.glitch_det().bit(enable),
2913                    RxEvent::FrameError => w.frm_err().bit(enable),
2914                    RxEvent::ParityError => w.parity_err().bit(enable),
2915                };
2916            }
2917            w
2918        });
2919    }
2920
2921    fn rx_events(&self) -> EnumSet<RxEvent> {
2922        let pending_interrupts = self.regs().int_raw().read();
2923        let mut active_events = EnumSet::new();
2924
2925        if pending_interrupts.rxfifo_full().bit_is_set() {
2926            active_events |= RxEvent::FifoFull;
2927        }
2928        if pending_interrupts.at_cmd_char_det().bit_is_set() {
2929            active_events |= RxEvent::CmdCharDetected;
2930        }
2931        if pending_interrupts.rxfifo_ovf().bit_is_set() {
2932            active_events |= RxEvent::FifoOvf;
2933        }
2934        if pending_interrupts.rxfifo_tout().bit_is_set() {
2935            active_events |= RxEvent::FifoTout;
2936        }
2937        if pending_interrupts.glitch_det().bit_is_set() {
2938            active_events |= RxEvent::GlitchDetected;
2939        }
2940        if pending_interrupts.frm_err().bit_is_set() {
2941            active_events |= RxEvent::FrameError;
2942        }
2943        if pending_interrupts.parity_err().bit_is_set() {
2944            active_events |= RxEvent::ParityError;
2945        }
2946
2947        active_events
2948    }
2949
2950    fn clear_rx_events(&self, events: impl Into<EnumSet<RxEvent>>) {
2951        let events = events.into();
2952        self.regs().int_clr().write(|w| {
2953            for event in events {
2954                match event {
2955                    RxEvent::FifoFull => w.rxfifo_full().clear_bit_by_one(),
2956                    RxEvent::CmdCharDetected => w.at_cmd_char_det().clear_bit_by_one(),
2957
2958                    RxEvent::FifoOvf => w.rxfifo_ovf().clear_bit_by_one(),
2959                    RxEvent::FifoTout => w.rxfifo_tout().clear_bit_by_one(),
2960                    RxEvent::GlitchDetected => w.glitch_det().clear_bit_by_one(),
2961                    RxEvent::FrameError => w.frm_err().clear_bit_by_one(),
2962                    RxEvent::ParityError => w.parity_err().clear_bit_by_one(),
2963                };
2964            }
2965            w
2966        });
2967    }
2968
2969    fn set_rx_fifo_full_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
2976        if threshold > Self::RX_FIFO_MAX_THRHD {
2977            return Err(ConfigError::RxFifoThresholdNotSupported);
2978        }
2979
2980        self.regs()
2981            .conf1()
2982            .modify(|_, w| unsafe { w.rxfifo_full_thrhd().bits(threshold as _) });
2983
2984        Ok(())
2985    }
2986
2987    #[allow(clippy::useless_conversion)]
2989    fn rx_fifo_full_threshold(&self) -> u16 {
2990        self.regs().conf1().read().rxfifo_full_thrhd().bits().into()
2991    }
2992
2993    fn set_tx_fifo_empty_threshold(&self, threshold: u16) -> Result<(), ConfigError> {
3000        if threshold > Self::TX_FIFO_MAX_THRHD {
3001            return Err(ConfigError::TxFifoThresholdNotSupported);
3002        }
3003
3004        self.regs()
3005            .conf1()
3006            .modify(|_, w| unsafe { w.txfifo_empty_thrhd().bits(threshold as _) });
3007
3008        Ok(())
3009    }
3010
3011    fn set_rx_timeout(&self, timeout: Option<u8>, _symbol_len: u8) -> Result<(), ConfigError> {
3026        cfg_if::cfg_if! {
3027            if #[cfg(esp32)] {
3028                const MAX_THRHD: u8 = 0x7F; } else {
3030                const MAX_THRHD: u16 = 0x3FF; }
3032        }
3033
3034        let register_block = self.regs();
3035
3036        if let Some(timeout) = timeout {
3037            #[cfg(esp32)]
3039            let timeout_reg = timeout;
3040            #[cfg(not(esp32))]
3042            let timeout_reg = timeout as u16 * _symbol_len as u16;
3043
3044            if timeout_reg > MAX_THRHD {
3045                return Err(ConfigError::TimeoutTooLong);
3046            }
3047
3048            cfg_if::cfg_if! {
3049                if #[cfg(esp32)] {
3050                    let reg_thrhd = register_block.conf1();
3051                } else if #[cfg(any(esp32c6, esp32h2))] {
3052                    let reg_thrhd = register_block.tout_conf();
3053                } else {
3054                    let reg_thrhd = register_block.mem_conf();
3055                }
3056            }
3057            reg_thrhd.modify(|_, w| unsafe { w.rx_tout_thrhd().bits(timeout_reg) });
3058        }
3059
3060        cfg_if::cfg_if! {
3061            if #[cfg(any(esp32c6, esp32h2))] {
3062                let reg_en = register_block.tout_conf();
3063            } else {
3064                let reg_en = register_block.conf1();
3065            }
3066        }
3067        reg_en.modify(|_, w| w.rx_tout_en().bit(timeout.is_some()));
3068
3069        self.sync_regs();
3070
3071        Ok(())
3072    }
3073
3074    #[cfg(soc_has_pcr)]
3075    fn is_instance(&self, other: impl Instance) -> bool {
3076        self == other.info()
3077    }
3078
3079    fn sync_regs(&self) {
3080        sync_regs(self.regs());
3081    }
3082
3083    fn change_baud(&self, config: &Config) -> Result<(), ConfigError> {
3084        let clocks = Clocks::get();
3085        let clk = match config.clock_source {
3086            ClockSource::Apb => clocks.apb_clock.as_hz(),
3087            #[cfg(not(any(esp32, esp32s2)))]
3088            ClockSource::Xtal => clocks.xtal_clock.as_hz(),
3089            #[cfg(not(any(esp32, esp32s2)))]
3090            ClockSource::RcFast => property!("soc.rc_fast_clk_default"), #[cfg(soc_ref_tick_hz_is_set)]
3092            ClockSource::RefTick => property!("soc.ref_tick_hz"),
3093        };
3094
3095        cfg_if::cfg_if! {
3096            if #[cfg(any(esp32c2, esp32c3, esp32s3, esp32c6, esp32h2))] {
3097
3098                const MAX_DIV: u32 = 0b1111_1111_1111 - 1;
3099                let clk_div = (clk.div_ceil(MAX_DIV)).div_ceil(config.baudrate);
3100
3101                cfg_if::cfg_if! {
3103                    if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3104                        if matches!(config.clock_source, ClockSource::RcFast) {
3105                            crate::peripherals::LPWR::regs()
3106                                .clk_conf()
3107                                .modify(|_, w| w.dig_clk8m_en().variant(true));
3108                            crate::rom::ets_delay_us(5);
3110                        }
3111
3112                        let conf = self.regs().clk_conf();
3113                    } else {
3114                        let pcr = crate::peripherals::PCR::regs();
3116                        let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3117                            pcr.uart(0).clk_conf()
3118                        } else {
3119                            pcr.uart(1).clk_conf()
3120                        };
3121                    }
3122                };
3123
3124                conf.write(|w| unsafe {
3125                    w.sclk_sel().bits(match config.clock_source {
3126                        ClockSource::Apb => 1,
3127                        ClockSource::RcFast => 2,
3128                        ClockSource::Xtal => 3,
3129                    });
3130                    w.sclk_div_a().bits(0);
3131                    w.sclk_div_b().bits(0);
3132                    w.sclk_div_num().bits(clk_div as u8 - 1)
3133                });
3134
3135                let divider = (clk << 4) / (config.baudrate * clk_div);
3136            } else {
3137                self.regs().conf0().modify(|_, w| {
3138                    w.tick_ref_always_on()
3139                        .bit(config.clock_source == ClockSource::Apb)
3140                });
3141
3142                let divider = (clk << 4) / config.baudrate;
3143            }
3144        }
3145
3146        let divider_integer = divider >> 4;
3147        let divider_frag = (divider & 0xf) as u8;
3148
3149        self.regs().clkdiv().write(|w| unsafe {
3150            w.clkdiv()
3151                .bits(divider_integer as _)
3152                .frag()
3153                .bits(divider_frag)
3154        });
3155
3156        self.sync_regs();
3157
3158        #[cfg(feature = "unstable")]
3159        self.verify_baudrate(clk, config)?;
3160
3161        Ok(())
3162    }
3163
3164    fn change_data_bits(&self, data_bits: DataBits) {
3165        self.regs()
3166            .conf0()
3167            .modify(|_, w| unsafe { w.bit_num().bits(data_bits as u8) });
3168    }
3169
3170    fn change_parity(&self, parity: Parity) {
3171        self.regs().conf0().modify(|_, w| match parity {
3172            Parity::None => w.parity_en().clear_bit(),
3173            Parity::Even => w.parity_en().set_bit().parity().clear_bit(),
3174            Parity::Odd => w.parity_en().set_bit().parity().set_bit(),
3175        });
3176    }
3177
3178    fn change_stop_bits(&self, stop_bits: StopBits) {
3179        #[cfg(esp32)]
3180        {
3181            if stop_bits == StopBits::_2 {
3183                self.regs()
3184                    .rs485_conf()
3185                    .modify(|_, w| w.dl1_en().bit(stop_bits == StopBits::_2));
3186
3187                self.regs()
3188                    .conf0()
3189                    .modify(|_, w| unsafe { w.stop_bit_num().bits(1) });
3190            }
3191        }
3192
3193        #[cfg(not(esp32))]
3194        self.regs()
3195            .conf0()
3196            .modify(|_, w| unsafe { w.stop_bit_num().bits(stop_bits as u8 + 1) });
3197    }
3198
3199    fn change_flow_control(&self, sw_flow_ctrl: SwFlowControl, hw_flow_ctrl: HwFlowControl) {
3200        match sw_flow_ctrl {
3202            SwFlowControl::Enabled {
3203                xon_char,
3204                xoff_char,
3205                xon_threshold,
3206                xoff_threshold,
3207            } => {
3208                cfg_if::cfg_if! {
3209                    if #[cfg(any(esp32c6, esp32h2))] {
3210                        self.regs().swfc_conf0().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3211                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold)});
3212                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3213                    } else if #[cfg(esp32)]{
3214                        self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3215                        self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold).xoff_threshold().bits(xoff_threshold) });
3216                        self.regs().swfc_conf().modify(|_, w| unsafe { w.xon_char().bits(xon_char).xoff_char().bits(xoff_char) });
3217                    } else {
3218                        self.regs().flow_conf().modify(|_, w| w.xonoff_del().set_bit().sw_flow_con_en().set_bit());
3219                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_threshold().bits(xon_threshold as u16) });
3220                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_threshold().bits(xoff_threshold as u16) });
3221                        self.regs().swfc_conf1().modify(|_, w| unsafe { w.xon_char().bits(xon_char) });
3222                        self.regs().swfc_conf0().modify(|_, w| unsafe { w.xoff_char().bits(xoff_char) });
3223                    }
3224                }
3225            }
3226            SwFlowControl::Disabled => {
3227                cfg_if::cfg_if! {
3228                    if #[cfg(any(esp32c6, esp32h2))] {
3229                        let reg = self.regs().swfc_conf0();
3230                    } else {
3231                        let reg = self.regs().flow_conf();
3232                    }
3233                }
3234
3235                reg.modify(|_, w| w.sw_flow_con_en().clear_bit());
3236                reg.modify(|_, w| w.xonoff_del().clear_bit());
3237            }
3238        }
3239
3240        self.regs().conf0().modify(|_, w| {
3241            w.tx_flow_en()
3242                .bit(matches!(hw_flow_ctrl.cts, CtsConfig::Enabled))
3243        });
3244
3245        match hw_flow_ctrl.rts {
3246            RtsConfig::Enabled(threshold) => self.configure_rts_flow_ctrl(true, Some(threshold)),
3247            RtsConfig::Disabled => self.configure_rts_flow_ctrl(false, None),
3248        }
3249
3250        #[cfg(any(esp32c6, esp32h2))]
3251        sync_regs(self.regs());
3252    }
3253
3254    fn configure_rts_flow_ctrl(&self, enable: bool, threshold: Option<u8>) {
3255        if let Some(threshold) = threshold {
3256            cfg_if::cfg_if! {
3257                if #[cfg(esp32)] {
3258                    self.regs().conf1().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3259                } else if #[cfg(any(esp32c6, esp32h2))] {
3260                    self.regs().hwfc_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold) });
3261                } else {
3262                    self.regs().mem_conf().modify(|_, w| unsafe { w.rx_flow_thrhd().bits(threshold as u16) });
3263                }
3264            }
3265        }
3266
3267        cfg_if::cfg_if! {
3268            if #[cfg(any(esp32c6, esp32h2))] {
3269                self.regs().hwfc_conf().modify(|_, w| {
3270                    w.rx_flow_en().bit(enable)
3271                });
3272            } else {
3273                self.regs().conf1().modify(|_, w| {
3274                    w.rx_flow_en().bit(enable)
3275                });
3276            }
3277        }
3278    }
3279
3280    fn rxfifo_reset(&self) {
3281        fn rxfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3282            reg_block.conf0().modify(|_, w| w.rxfifo_rst().bit(enable));
3283            sync_regs(reg_block);
3284        }
3285
3286        rxfifo_rst(self.regs(), true);
3287        rxfifo_rst(self.regs(), false);
3288    }
3289
3290    fn txfifo_reset(&self) {
3291        fn txfifo_rst(reg_block: &RegisterBlock, enable: bool) {
3292            reg_block.conf0().modify(|_, w| w.txfifo_rst().bit(enable));
3293            sync_regs(reg_block);
3294        }
3295
3296        txfifo_rst(self.regs(), true);
3297        txfifo_rst(self.regs(), false);
3298    }
3299
3300    #[cfg(feature = "unstable")]
3301    fn verify_baudrate(&self, clk: u32, config: &Config) -> Result<(), ConfigError> {
3302        let clkdiv_reg = self.regs().clkdiv().read();
3305        let clkdiv_frag = clkdiv_reg.frag().bits() as u32;
3306        let clkdiv = clkdiv_reg.clkdiv().bits();
3307
3308        cfg_if::cfg_if! {
3309            if #[cfg(any(esp32, esp32s2))] {
3310                let actual_baud = (clk << 4) / ((clkdiv << 4) | clkdiv_frag);
3311            } else if #[cfg(any(esp32c2, esp32c3, esp32s3))] {
3312                let sclk_div_num = self.regs().clk_conf().read().sclk_div_num().bits() as u32;
3313                let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3314            } else { let pcr = crate::peripherals::PCR::regs();
3316                let conf = if self.is_instance(unsafe { crate::peripherals::UART0::steal() }) {
3317                    pcr.uart(0).clk_conf()
3318                } else {
3319                    pcr.uart(1).clk_conf()
3320                };
3321                let sclk_div_num = conf.read().sclk_div_num().bits() as u32;
3322                let actual_baud = (clk << 4) / ((((clkdiv as u32) << 4) | clkdiv_frag) * (sclk_div_num + 1));
3323            }
3324        };
3325
3326        match config.baudrate_tolerance {
3327            BaudrateTolerance::Exact => {
3328                let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3329                    * 100)
3330                    / actual_baud;
3331                if deviation > 1_u32 {
3334                    return Err(ConfigError::BaudrateNotAchievable);
3335                }
3336            }
3337            BaudrateTolerance::ErrorPercent(percent) => {
3338                let deviation = ((config.baudrate as i32 - actual_baud as i32).unsigned_abs()
3339                    * 100)
3340                    / actual_baud;
3341                if deviation > percent as u32 {
3342                    return Err(ConfigError::BaudrateNotAchievable);
3343                }
3344            }
3345            _ => {}
3346        }
3347
3348        Ok(())
3349    }
3350
3351    fn current_symbol_length(&self) -> u8 {
3352        let conf0 = self.regs().conf0().read();
3353        let data_bits = conf0.bit_num().bits() + 5; let parity = conf0.parity_en().bit() as u8;
3355        let mut stop_bits = conf0.stop_bit_num().bits();
3356
3357        match stop_bits {
3358            1 => {
3359                #[cfg(esp32)]
3361                if self.regs().rs485_conf().read().dl1_en().bit_is_set() {
3362                    stop_bits = 2;
3363                }
3364            }
3365            _ => stop_bits = 2,
3367        }
3368
3369        1 + data_bits + parity + stop_bits
3370    }
3371
3372    fn read_next_from_fifo(&self) -> u8 {
3376        fn access_fifo_register<R>(f: impl Fn() -> R) -> R {
3377            cfg_if::cfg_if! {
3379                if #[cfg(esp32)] {
3380                    crate::interrupt::free(f)
3381                } else {
3382                    f()
3383                }
3384            }
3385        }
3386
3387        let fifo_reg = self.regs().fifo();
3388        cfg_if::cfg_if! {
3389            if #[cfg(esp32s2)] {
3390                let fifo_reg = unsafe {
3392                    &*fifo_reg.as_ptr().cast::<u8>().add(0x20C00000).cast::<crate::pac::uart0::FIFO>()
3393                };
3394            }
3395        }
3396
3397        access_fifo_register(|| fifo_reg.read().rxfifo_rd_byte().bits())
3398    }
3399
3400    #[allow(clippy::useless_conversion)]
3401    fn tx_fifo_count(&self) -> u16 {
3402        u16::from(self.regs().status().read().txfifo_cnt().bits())
3403    }
3404
3405    fn write_byte(&self, byte: u8) {
3406        self.regs()
3407            .fifo()
3408            .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
3409    }
3410
3411    fn check_for_errors(&self) -> Result<(), RxError> {
3412        let errors = RxEvent::FifoOvf
3413            | RxEvent::FifoTout
3414            | RxEvent::GlitchDetected
3415            | RxEvent::FrameError
3416            | RxEvent::ParityError;
3417        let events = self.rx_events().intersection(errors);
3418        let result = rx_event_check_for_error(events);
3419        if result.is_err() {
3420            self.clear_rx_events(errors);
3421            if events.contains(RxEvent::FifoOvf) {
3422                self.rxfifo_reset();
3423            }
3424        }
3425        result
3426    }
3427
3428    #[cfg(not(esp32))]
3429    #[allow(clippy::unnecessary_cast)]
3430    fn rx_fifo_count(&self) -> u16 {
3431        self.regs().status().read().rxfifo_cnt().bits() as u16
3432    }
3433
3434    #[cfg(esp32)]
3435    fn rx_fifo_count(&self) -> u16 {
3436        let fifo_cnt = self.regs().status().read().rxfifo_cnt().bits();
3437
3438        let status = self.regs().mem_rx_status().read();
3441        let rd_addr: u16 = status.mem_rx_rd_addr().bits();
3442        let wr_addr: u16 = status.mem_rx_wr_addr().bits();
3443
3444        if wr_addr > rd_addr {
3445            wr_addr - rd_addr
3446        } else if wr_addr < rd_addr {
3447            (wr_addr + Info::UART_FIFO_SIZE) - rd_addr
3448        } else if fifo_cnt > 0 {
3449            Info::UART_FIFO_SIZE
3450        } else {
3451            0
3452        }
3453    }
3454
3455    fn write(&self, data: &[u8]) -> Result<usize, TxError> {
3456        if data.is_empty() {
3457            return Ok(0);
3458        }
3459
3460        while self.tx_fifo_count() >= Info::UART_FIFO_SIZE {}
3461
3462        let space = (Info::UART_FIFO_SIZE - self.tx_fifo_count()) as usize;
3463        let to_write = space.min(data.len());
3464        for &byte in &data[..to_write] {
3465            self.write_byte(byte);
3466        }
3467
3468        Ok(to_write)
3469    }
3470
3471    fn read(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3472        if buf.is_empty() {
3473            return Ok(0);
3474        }
3475
3476        while self.rx_fifo_count() == 0 {
3477            self.check_for_errors()?;
3479        }
3480
3481        self.read_buffered(buf)
3482    }
3483
3484    fn read_buffered(&self, buf: &mut [u8]) -> Result<usize, RxError> {
3485        let to_read = (self.rx_fifo_count() as usize).min(buf.len());
3488        self.check_for_errors()?;
3489
3490        for byte_into in buf[..to_read].iter_mut() {
3491            *byte_into = self.read_next_from_fifo();
3492        }
3493
3494        Ok(to_read)
3495    }
3496}
3497
3498impl PartialEq for Info {
3499    fn eq(&self, other: &Self) -> bool {
3500        core::ptr::eq(self.register_block, other.register_block)
3501    }
3502}
3503
3504unsafe impl Sync for Info {}
3505
3506for_each_uart! {
3507    ($inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3508        impl Instance for crate::peripherals::$inst<'_> {
3509            fn parts(&self) -> (&'static Info, &'static State) {
3510                #[crate::handler]
3511                pub(super) fn irq_handler() {
3512                    intr_handler(&PERIPHERAL, &STATE);
3513                }
3514
3515                static STATE: State = State {
3516                    tx_waker: AtomicWaker::new(),
3517                    rx_waker: AtomicWaker::new(),
3518                    is_rx_async: AtomicBool::new(false),
3519                    is_tx_async: AtomicBool::new(false),
3520                    #[cfg(uart_peripheral_controls_mem_clk)]
3521                    mem_ref_count: AtomicUsize::new(0),
3522                };
3523
3524                static PERIPHERAL: Info = Info {
3525                    register_block: crate::peripherals::$inst::ptr(),
3526                    peripheral: crate::system::Peripheral::$peri,
3527                    async_handler: irq_handler,
3528                    tx_signal: OutputSignal::$txd,
3529                    rx_signal: InputSignal::$rxd,
3530                    cts_signal: InputSignal::$cts,
3531                    rts_signal: OutputSignal::$rts,
3532                };
3533                (&PERIPHERAL, &STATE)
3534            }
3535        }
3536    };
3537}
3538
3539crate::any_peripheral! {
3540    pub peripheral AnyUart<'d> {
3542        #[cfg(soc_has_uart0)]
3543        Uart0(crate::peripherals::UART0<'d>),
3544        #[cfg(soc_has_uart1)]
3545        Uart1(crate::peripherals::UART1<'d>),
3546        #[cfg(soc_has_uart2)]
3547        Uart2(crate::peripherals::UART2<'d>),
3548    }
3549}
3550
3551impl Instance for AnyUart<'_> {
3552    #[inline]
3553    fn parts(&self) -> (&'static Info, &'static State) {
3554        any::delegate!(self, uart => { uart.parts() })
3555    }
3556}
3557
3558impl AnyUart<'_> {
3559    fn bind_peri_interrupt(&self, handler: crate::interrupt::IsrCallback) {
3560        any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
3561    }
3562
3563    fn disable_peri_interrupt(&self) {
3564        any::delegate!(self, uart => { uart.disable_peri_interrupt() })
3565    }
3566
3567    fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority) {
3568        any::delegate!(self, uart => { uart.enable_peri_interrupt(priority) })
3569    }
3570
3571    fn set_interrupt_handler(&self, handler: InterruptHandler) {
3572        self.disable_peri_interrupt();
3573
3574        self.info().enable_listen(EnumSet::all(), false);
3575        self.info().clear_interrupts(EnumSet::all());
3576
3577        self.bind_peri_interrupt(handler.handler());
3578        self.enable_peri_interrupt(handler.priority());
3579    }
3580}
3581
3582cfg_if::cfg_if! {
3589    if #[cfg(uart_peripheral_controls_mem_clk)] {
3590        use portable_atomic::AtomicUsize;
3592
3593        struct MemoryGuard<'t> {
3594            uart: AnyUart<'t>
3595        }
3596
3597        impl<'t> MemoryGuard<'t> {
3598            fn new(uart: AnyUart<'t>) -> Self {
3599                let this = Self { uart };
3600
3601                if this.refcount().fetch_add(1, Ordering::SeqCst) == 0 {
3602                    this.enable_memory_clk(true);
3603                }
3604
3605                this
3606            }
3607
3608            fn enable_memory_clk(&self, clk: bool) {
3609                self.uart.info().regs().conf0().modify(|_, w| w.mem_clk_en().bit(clk));
3610            }
3611
3612            fn refcount(&self) -> &AtomicUsize {
3613                &self.uart.state().mem_ref_count
3614            }
3615        }
3616
3617        impl Clone for MemoryGuard<'_> {
3618            fn clone(&self) -> Self {
3619                self.refcount().fetch_add(1, Ordering::SeqCst);
3620
3621                Self { uart: unsafe { self.uart.clone_unchecked() } }
3622            }
3623        }
3624
3625        impl Drop for MemoryGuard<'_> {
3626            fn drop(&mut self) {
3627                if self.refcount().fetch_sub(1, Ordering::SeqCst) == 1 {
3628                    self.enable_memory_clk(false);
3629                }
3630            }
3631        }
3632
3633        fn create_mem_guard(uart: AnyUart<'_>) -> MemoryGuard<'_> {
3634            MemoryGuard::new(uart)
3635        }
3636    } else {
3637        use crate::system::{Peripheral, GenericPeripheralGuard};
3639        type MemoryGuard<'t> = GenericPeripheralGuard<{ Peripheral::UartMem as u8 }>;
3640
3641        fn create_mem_guard(_uart: AnyUart<'_>) -> MemoryGuard<'_> {
3642            MemoryGuard::new()
3643        }
3644    }
3645}