Skip to main content

esp_idf_hal/
uart.rs

1//: QueueHandle_t ! UART peripheral control
2//! Controls UART peripherals (UART0, UART1, UART2).
3//!
4//! Notice that UART0 is typically already used for loading firmware and logging.
5//! Therefore use UART1 and UART2 in your application.
6//! Any pin can be used for `rx` and `tx`.
7//!
8//! # Example
9//!
10//! Create a serial peripheral and write to serial port.
11//! ```
12//! use std::fmt::Write;
13//! use esp_idf_hal::prelude::*;
14//! use esp_idf_hal::uart;
15//!
16//! let peripherals = Peripherals::take().unwrap();
17//! let pins = peripherals.pins;
18//!
19//! let config = uart::config::Config::default().baudrate(Hertz(115_200));
20//!
21//! let mut uart: uart::UartDriver = uart::UartDriver::new(
22//!     peripherals.uart1,
23//!     pins.gpio1,
24//!     pins.gpio3,
25//!     Option::<AnyIOPin>::None,
26//!     Option::<AnyIOPin>::None,
27//!     &config
28//! ).unwrap();
29//!
30//! for i in 0..10 {
31//!     writeln!(uart, "{:}", format!("count {:}", i)).unwrap();
32//! }
33//! ```
34//!
35//! # TODO
36//! - Add all extra features esp32 supports
37//! - Free APB lock when TX is idle (and no RX used)
38//! - Address errata 3.17: UART fifo_cnt is inconsistent with FIFO pointer
39
40use core::borrow::BorrowMut;
41use core::ffi::CStr;
42use core::marker::PhantomData;
43use core::mem::ManuallyDrop;
44use core::ptr;
45use core::sync::atomic::{AtomicU8, Ordering};
46
47use crate::cpu::Core;
48use crate::delay::{self, NON_BLOCK};
49use crate::interrupt::InterruptType;
50use crate::io::EspIOError;
51use crate::task::asynch::Notification;
52use crate::task::queue::Queue;
53use crate::units::*;
54use crate::{gpio::*, task};
55
56use embedded_hal_nb::serial::ErrorKind;
57use esp_idf_sys::*;
58
59const UART_FIFO_SIZE: usize = SOC_UART_FIFO_LEN as usize;
60
61pub type UartConfig = config::Config;
62
63/// UART configuration
64pub mod config {
65    use crate::{interrupt::InterruptType, units::*};
66    use enumset::{enum_set, EnumSet, EnumSetType};
67    use esp_idf_sys::*;
68
69    /// Mode
70    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
71    pub enum Mode {
72        /// regular UART mode
73        UART,
74        /// half duplex RS485 UART mode control by RTS pin
75        RS485HalfDuplex,
76    }
77
78    impl From<Mode> for uart_mode_t {
79        fn from(mode: Mode) -> Self {
80            match mode {
81                Mode::UART => uart_mode_t_UART_MODE_UART,
82                Mode::RS485HalfDuplex => uart_mode_t_UART_MODE_RS485_HALF_DUPLEX,
83            }
84        }
85    }
86
87    impl From<uart_mode_t> for Mode {
88        #[allow(non_upper_case_globals)]
89        fn from(uart_mode: uart_mode_t) -> Self {
90            match uart_mode {
91                uart_mode_t_UART_MODE_UART => Mode::UART,
92                uart_mode_t_UART_MODE_RS485_HALF_DUPLEX => Mode::RS485HalfDuplex,
93                _ => unreachable!(),
94            }
95        }
96    }
97
98    /// Number of data bits
99    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
100    pub enum DataBits {
101        DataBits5,
102        DataBits6,
103        DataBits7,
104        DataBits8,
105    }
106
107    impl From<DataBits> for uart_word_length_t {
108        fn from(data_bits: DataBits) -> Self {
109            match data_bits {
110                DataBits::DataBits5 => uart_word_length_t_UART_DATA_5_BITS,
111                DataBits::DataBits6 => uart_word_length_t_UART_DATA_6_BITS,
112                DataBits::DataBits7 => uart_word_length_t_UART_DATA_7_BITS,
113                DataBits::DataBits8 => uart_word_length_t_UART_DATA_8_BITS,
114            }
115        }
116    }
117
118    impl From<uart_word_length_t> for DataBits {
119        #[allow(non_upper_case_globals)]
120        fn from(word_length: uart_word_length_t) -> Self {
121            match word_length {
122                uart_word_length_t_UART_DATA_5_BITS => DataBits::DataBits5,
123                uart_word_length_t_UART_DATA_6_BITS => DataBits::DataBits6,
124                uart_word_length_t_UART_DATA_7_BITS => DataBits::DataBits7,
125                uart_word_length_t_UART_DATA_8_BITS => DataBits::DataBits8,
126                _ => unreachable!(),
127            }
128        }
129    }
130
131    /// Flow control
132    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
133    pub enum FlowControl {
134        None,
135        RTS,
136        CTS,
137        CTSRTS,
138        MAX,
139    }
140
141    impl From<FlowControl> for uart_hw_flowcontrol_t {
142        fn from(flow_control: FlowControl) -> Self {
143            match flow_control {
144                FlowControl::None => uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_DISABLE,
145                FlowControl::RTS => uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_RTS,
146                FlowControl::CTS => uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_CTS,
147                FlowControl::CTSRTS => uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_CTS_RTS,
148                FlowControl::MAX => uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_MAX,
149            }
150        }
151    }
152
153    impl From<uart_hw_flowcontrol_t> for FlowControl {
154        #[allow(non_upper_case_globals)]
155        fn from(flow_control: uart_hw_flowcontrol_t) -> Self {
156            match flow_control {
157                uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_DISABLE => FlowControl::None,
158                uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_RTS => FlowControl::RTS,
159                uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_CTS => FlowControl::CTS,
160                uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_CTS_RTS => FlowControl::CTSRTS,
161                uart_hw_flowcontrol_t_UART_HW_FLOWCTRL_MAX => FlowControl::MAX,
162                _ => unreachable!(),
163            }
164        }
165    }
166
167    /// Parity check
168    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
169    pub enum Parity {
170        ParityNone,
171        ParityEven,
172        ParityOdd,
173    }
174
175    impl From<Parity> for uart_parity_t {
176        fn from(parity: Parity) -> Self {
177            match parity {
178                Parity::ParityNone => uart_parity_t_UART_PARITY_DISABLE,
179                Parity::ParityEven => uart_parity_t_UART_PARITY_EVEN,
180                Parity::ParityOdd => uart_parity_t_UART_PARITY_ODD,
181            }
182        }
183    }
184
185    impl From<uart_parity_t> for Parity {
186        #[allow(non_upper_case_globals)]
187        fn from(parity: uart_parity_t) -> Self {
188            match parity {
189                uart_parity_t_UART_PARITY_DISABLE => Parity::ParityNone,
190                uart_parity_t_UART_PARITY_EVEN => Parity::ParityEven,
191                uart_parity_t_UART_PARITY_ODD => Parity::ParityOdd,
192                _ => unreachable!(),
193            }
194        }
195    }
196
197    /// Number of stop bits
198    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
199    pub enum StopBits {
200        /// 1 stop bit
201        STOP1,
202        /// 1.5 stop bits
203        STOP1P5,
204        /// 2 stop bits
205        STOP2,
206    }
207
208    impl From<StopBits> for uart_stop_bits_t {
209        fn from(stop_bits: StopBits) -> Self {
210            match stop_bits {
211                StopBits::STOP1 => uart_stop_bits_t_UART_STOP_BITS_1,
212                StopBits::STOP1P5 => uart_stop_bits_t_UART_STOP_BITS_1_5,
213                StopBits::STOP2 => uart_stop_bits_t_UART_STOP_BITS_2,
214            }
215        }
216    }
217
218    impl From<uart_stop_bits_t> for StopBits {
219        #[allow(non_upper_case_globals)]
220        fn from(stop_bits: uart_stop_bits_t) -> Self {
221            match stop_bits {
222                uart_stop_bits_t_UART_STOP_BITS_1 => StopBits::STOP1,
223                uart_stop_bits_t_UART_STOP_BITS_1_5 => StopBits::STOP1P5,
224                uart_stop_bits_t_UART_STOP_BITS_2 => StopBits::STOP2,
225                _ => unreachable!(),
226            }
227        }
228    }
229
230    /// UART source clock
231    #[derive(PartialEq, Eq, Copy, Clone, Debug)]
232    pub enum SourceClock {
233        /// UART source clock from `APB`
234        #[cfg(any(
235            esp_idf_soc_uart_support_apb_clk,
236            esp_idf_soc_uart_support_pll_f40m_clk,
237            esp_idf_version_major = "4",
238        ))]
239        APB,
240        /// UART source clock from `RTC`
241        #[cfg(esp_idf_soc_uart_support_rtc_clk)]
242        RTC,
243        /// UART source clock from `XTAL`
244        #[cfg(esp_idf_soc_uart_support_xtal_clk)]
245        Crystal,
246        /// UART source clock from `PLL_F80M`
247        #[allow(non_camel_case_types)]
248        #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)]
249        PLL_F80M,
250        /// UART source clock from `PLL_F48M` (ESP32-H2)
251        #[allow(non_camel_case_types)]
252        #[cfg(not(any(
253            esp_idf_soc_uart_support_apb_clk,
254            esp_idf_soc_uart_support_pll_f40m_clk,
255            esp_idf_soc_uart_support_pll_f80m_clk,
256            esp_idf_soc_uart_support_ref_tick,
257            esp_idf_version_major = "4"
258        )))]
259        PLL_F48M,
260        /// UART source clock from `REF_TICK`
261        #[cfg(esp_idf_soc_uart_support_ref_tick)]
262        RefTick,
263    }
264
265    impl SourceClock {
266        pub const fn default() -> Self {
267            #[cfg(not(esp_idf_version_major = "4"))]
268            const DEFAULT: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_DEFAULT;
269            #[cfg(esp_idf_version_major = "4")]
270            const DEFAULT: uart_sclk_t = uart_sclk_t_UART_SCLK_APB;
271            Self::from_raw(DEFAULT)
272        }
273
274        pub const fn from_raw(source_clock: uart_sclk_t) -> Self {
275            match source_clock {
276                #[cfg(any(
277                    esp_idf_soc_uart_support_apb_clk,
278                    esp_idf_soc_uart_support_pll_f40m_clk,
279                    esp_idf_version_major = "4",
280                ))]
281                APB_SCLK => SourceClock::APB,
282                #[cfg(esp_idf_soc_uart_support_rtc_clk)]
283                RTC_SCLK => SourceClock::RTC,
284                #[cfg(esp_idf_soc_uart_support_xtal_clk)]
285                XTAL_SCLK => SourceClock::Crystal,
286                #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)]
287                PLL_F80M_SCLK => SourceClock::PLL_F80M,
288                #[cfg(not(any(
289                    esp_idf_soc_uart_support_apb_clk,
290                    esp_idf_soc_uart_support_pll_f40m_clk,
291                    esp_idf_soc_uart_support_pll_f80m_clk,
292                    esp_idf_soc_uart_support_ref_tick,
293                    esp_idf_version_major = "4"
294                )))]
295                PLL_F48M_SCLK => SourceClock::PLL_F48M,
296                #[cfg(esp_idf_soc_uart_support_ref_tick)]
297                REF_TICK_SCLK => SourceClock::RefTick,
298                _ => unreachable!(),
299            }
300        }
301
302        #[cfg(not(esp_idf_version_major = "4"))]
303        pub fn frequency(self) -> Result<Hertz, EspError> {
304            let mut frequency: u32 = 0;
305            esp_result! {
306                unsafe { uart_get_sclk_freq(self.into(), &mut frequency) },
307                Hertz(frequency)
308            }
309        }
310    }
311
312    #[cfg(all(not(esp_idf_version_major = "4"), esp_idf_soc_uart_support_apb_clk))]
313    const APB_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_APB;
314    #[cfg(all(
315        not(esp_idf_version_major = "4"),
316        not(esp_idf_soc_uart_support_apb_clk),
317        esp_idf_soc_uart_support_pll_f40m_clk,
318    ))]
319    const APB_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_PLL_F40M;
320    #[cfg(esp_idf_version_major = "4")]
321    const APB_SCLK: uart_sclk_t = uart_sclk_t_UART_SCLK_APB;
322
323    #[cfg(all(not(esp_idf_version_major = "4"), esp_idf_soc_uart_support_rtc_clk))]
324    const RTC_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_RTC;
325    #[cfg(all(esp_idf_version_major = "4", esp_idf_soc_uart_support_rtc_clk))]
326    const RTC_SCLK: uart_sclk_t = uart_sclk_t_UART_SCLK_RTC;
327
328    #[cfg(all(not(esp_idf_version_major = "4"), esp_idf_soc_uart_support_xtal_clk))]
329    const XTAL_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_XTAL;
330    #[cfg(all(esp_idf_version_major = "4", esp_idf_soc_uart_support_xtal_clk))]
331    const XTAL_SCLK: uart_sclk_t = uart_sclk_t_UART_SCLK_XTAL;
332
333    #[cfg(all(
334        not(esp_idf_version_major = "4"),
335        esp_idf_soc_uart_support_pll_f80m_clk
336    ))]
337    const PLL_F80M_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_PLL_F80M;
338    #[cfg(all(esp_idf_version_major = "4", esp_idf_soc_uart_support_pll_f80m_clk))]
339    const PLL_F80M_SCLK: uart_sclk_t = uart_sclk_t_UART_SCLK_PLL_F80M;
340
341    #[cfg(all(
342        not(esp_idf_version_major = "4"),
343        not(any(
344            esp_idf_soc_uart_support_apb_clk,
345            esp_idf_soc_uart_support_pll_f40m_clk,
346            esp_idf_soc_uart_support_pll_f80m_clk,
347            esp_idf_soc_uart_support_ref_tick
348        ))
349    ))]
350    const PLL_F48M_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_PLL_F48M;
351
352    #[cfg(all(not(esp_idf_version_major = "4"), esp_idf_soc_uart_support_ref_tick))]
353    const REF_TICK_SCLK: uart_sclk_t = soc_periph_uart_clk_src_legacy_t_UART_SCLK_REF_TICK;
354    #[cfg(all(esp_idf_version_major = "4", esp_idf_soc_uart_support_ref_tick))]
355    const REF_TICK_SCLK: uart_sclk_t = uart_sclk_t_UART_SCLK_REF_TICK;
356
357    impl Default for SourceClock {
358        fn default() -> Self {
359            SourceClock::default()
360        }
361    }
362
363    impl From<SourceClock> for uart_sclk_t {
364        fn from(source_clock: SourceClock) -> Self {
365            match source_clock {
366                #[cfg(any(
367                    esp_idf_soc_uart_support_apb_clk,
368                    esp_idf_soc_uart_support_pll_f40m_clk,
369                    esp_idf_version_major = "4",
370                ))]
371                SourceClock::APB => APB_SCLK,
372                #[cfg(esp_idf_soc_uart_support_rtc_clk)]
373                SourceClock::RTC => RTC_SCLK,
374                #[cfg(esp_idf_soc_uart_support_xtal_clk)]
375                SourceClock::Crystal => XTAL_SCLK,
376                #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)]
377                SourceClock::PLL_F80M => PLL_F80M_SCLK,
378                #[cfg(not(any(
379                    esp_idf_soc_uart_support_apb_clk,
380                    esp_idf_soc_uart_support_pll_f40m_clk,
381                    esp_idf_soc_uart_support_pll_f80m_clk,
382                    esp_idf_soc_uart_support_ref_tick,
383                    esp_idf_version_major = "4"
384                )))]
385                SourceClock::PLL_F48M => PLL_F48M_SCLK,
386                #[cfg(esp_idf_soc_uart_support_ref_tick)]
387                SourceClock::RefTick => REF_TICK_SCLK,
388            }
389        }
390    }
391
392    impl From<uart_sclk_t> for SourceClock {
393        fn from(source_clock: uart_sclk_t) -> Self {
394            Self::from_raw(source_clock)
395        }
396    }
397
398    /// Configures the interrupts the UART driver should enable
399    /// in order to be able to quickly inform us about the
400    /// related event.
401    #[derive(Debug, Clone)]
402    pub struct EventConfig {
403        /// If `Some(number_of_words)`, an interrupt will trigger
404        /// after `number_of_words` could have been transmitted
405        /// (unit is baudrate dependant).
406        ///
407        /// If `None` or `Some(0)` interrupt will be disabled.
408        pub receive_timeout: Option<u8>,
409        /// Sets the threshold at which an interrupt will
410        /// be generated (the hardware receive FIFO contains more words than
411        /// this number).
412        ///
413        /// If set to `None` interrupt will be disabled.
414        pub rx_fifo_full: Option<u8>,
415        /// Sets the threshold **below** which an interrupt will
416        /// be generated (the hardware transmit FIFO contains less words than
417        /// this number).
418        ///
419        /// If set to `None` interrupt will be disabled.
420        /// Should not be set to `0` as the interrupt will trigger constantly.
421        pub tx_fifo_empty: Option<u8>,
422        /// Other interrupts to enable
423        pub flags: EnumSet<EventFlags>,
424        /// Allow using struct syntax,
425        /// but signal users other fields may be added
426        /// so `..Default::default()` should be used.
427        #[doc(hidden)]
428        pub _non_exhaustive: (),
429    }
430
431    impl EventConfig {
432        pub const fn new() -> Self {
433            EventConfig {
434                receive_timeout: Some(10),
435                rx_fifo_full: Some(120),
436                tx_fifo_empty: Some(10),
437                flags: enum_set!(
438                    EventFlags::RxFifoFull
439                        | EventFlags::RxFifoTimeout
440                        | EventFlags::RxFifoOverflow
441                        | EventFlags::BreakDetected
442                        | EventFlags::ParityError
443                ),
444                _non_exhaustive: (),
445            }
446        }
447    }
448
449    impl Default for EventConfig {
450        fn default() -> Self {
451            EventConfig::new()
452        }
453    }
454
455    impl From<EventConfig> for crate::sys::uart_intr_config_t {
456        fn from(cfg: EventConfig) -> Self {
457            let mut intr_enable_mask = cfg.flags;
458
459            if cfg.receive_timeout.map(|to| to > 0).unwrap_or(false) {
460                intr_enable_mask.insert(EventFlags::RxFifoTimeout);
461            } else {
462                intr_enable_mask.remove(EventFlags::RxFifoTimeout);
463            }
464
465            if cfg.rx_fifo_full.is_some() {
466                intr_enable_mask.insert(EventFlags::RxFifoFull);
467            } else {
468                intr_enable_mask.remove(EventFlags::RxFifoFull);
469            }
470
471            if cfg.tx_fifo_empty.is_some() {
472                intr_enable_mask.insert(EventFlags::TxFifoEmpty);
473            } else {
474                intr_enable_mask.remove(EventFlags::TxFifoEmpty);
475            }
476
477            crate::sys::uart_intr_config_t {
478                intr_enable_mask: intr_enable_mask.as_repr(),
479                rx_timeout_thresh: cfg.receive_timeout.unwrap_or(0),
480                txfifo_empty_intr_thresh: cfg.tx_fifo_empty.unwrap_or(0),
481                rxfifo_full_thresh: cfg.rx_fifo_full.unwrap_or(0),
482            }
483        }
484    }
485
486    #[derive(Debug, EnumSetType)]
487    #[enumset(repr = "u32")]
488    #[non_exhaustive]
489    pub enum EventFlags {
490        #[doc(hidden)]
491        RxFifoFull = 0,
492        #[doc(hidden)]
493        TxFifoEmpty = 1,
494        ParityError = 2,
495        FrameError = 3,
496        RxFifoOverflow = 4,
497        DsrChange = 5,
498        CtsChange = 6,
499        BreakDetected = 7,
500        #[doc(hidden)]
501        RxFifoTimeout = 8,
502        SwXon = 9,
503        SwXoff = 10,
504        GlitchDetected = 11,
505        TxBreakDone = 12,
506        TxBreakIdle = 13,
507        TxDone = 14,
508        Rs485ParityError = 15,
509        Rs485FrameError = 16,
510        Rs485Clash = 17,
511        CmdCharDetected = 18,
512    }
513
514    /// UART configuration
515    #[derive(Debug, Clone)]
516    pub struct Config {
517        pub mode: Mode,
518        pub baudrate: Hertz,
519        pub data_bits: DataBits,
520        pub parity: Parity,
521        pub stop_bits: StopBits,
522        pub flow_control: FlowControl,
523        pub flow_control_rts_threshold: u8,
524        pub source_clock: SourceClock,
525        /// Configures the flags to use for interrupt allocation,
526        /// e.g. priority to use for the interrupt.
527        ///
528        /// Note that you should not set `Iram` here, because it will
529        /// be automatically set depending on the value of `CONFIG_UART_ISR_IN_IRAM`.
530        pub intr_flags: EnumSet<InterruptType>,
531        /// Configures the interrupts the driver should enable.
532        pub event_config: EventConfig,
533        /// The size of the software rx buffer. Must be bigger than the hardware FIFO.
534        pub rx_fifo_size: usize,
535        /// The size of the software tx buffer. Must be bigger than the hardware FIFO
536        /// or 0 to disable transmit buffering (note that this will make write operations
537        /// block until data has been sent out).
538        pub tx_fifo_size: usize,
539        /// Number of events that should fit into the event queue.
540        /// Specify 0 to prevent the creation of an event queue.
541        pub queue_size: usize,
542        /// Allow using struct syntax,
543        /// but signal users other fields may be added
544        /// so `..Default::default()` should be used.
545        #[doc(hidden)]
546        pub _non_exhaustive: (),
547    }
548
549    impl From<&Config> for uart_config_t {
550        fn from(config: &Config) -> Self {
551            #[allow(clippy::needless_update)]
552            Self {
553                baud_rate: config.baudrate.0 as i32,
554                data_bits: config.data_bits.into(),
555                parity: config.parity.into(),
556                stop_bits: config.stop_bits.into(),
557                flow_ctrl: config.flow_control.into(),
558                rx_flow_ctrl_thresh: config.flow_control_rts_threshold,
559                // ESP-IDF 5.0 and 5.1
560                #[cfg(all(
561                    esp_idf_version_major = "5",
562                    any(esp_idf_version_minor = "0", esp_idf_version_minor = "1")
563                ))]
564                source_clk: config.source_clock.into(),
565                // All others
566                #[cfg(not(all(
567                    esp_idf_version_major = "5",
568                    any(esp_idf_version_minor = "0", esp_idf_version_minor = "1")
569                )))]
570                __bindgen_anon_1: uart_config_t__bindgen_ty_1 {
571                    source_clk: config.source_clock.into(),
572                },
573                ..Default::default()
574            }
575        }
576    }
577
578    impl Config {
579        pub const fn new() -> Config {
580            Config {
581                mode: Mode::UART,
582                baudrate: Hertz(115_200),
583                data_bits: DataBits::DataBits8,
584                parity: Parity::ParityNone,
585                stop_bits: StopBits::STOP1,
586                flow_control: FlowControl::None,
587                flow_control_rts_threshold: 122,
588                source_clock: SourceClock::default(),
589                intr_flags: EnumSet::empty(),
590                event_config: EventConfig::new(),
591                rx_fifo_size: super::UART_FIFO_SIZE * 2,
592                tx_fifo_size: super::UART_FIFO_SIZE * 2,
593                queue_size: 10,
594                _non_exhaustive: (),
595            }
596        }
597
598        #[must_use]
599        pub fn mode(mut self, mode: Mode) -> Self {
600            self.mode = mode;
601            self
602        }
603
604        #[must_use]
605        pub fn baudrate(mut self, baudrate: Hertz) -> Self {
606            self.baudrate = baudrate;
607            self
608        }
609
610        #[must_use]
611        pub fn parity_none(mut self) -> Self {
612            self.parity = Parity::ParityNone;
613            self
614        }
615
616        #[must_use]
617        pub fn parity_even(mut self) -> Self {
618            self.parity = Parity::ParityEven;
619            self
620        }
621
622        #[must_use]
623        pub fn parity_odd(mut self) -> Self {
624            self.parity = Parity::ParityOdd;
625            self
626        }
627
628        #[must_use]
629        pub fn data_bits(mut self, data_bits: DataBits) -> Self {
630            self.data_bits = data_bits;
631            self
632        }
633
634        #[must_use]
635        pub fn stop_bits(mut self, stop_bits: StopBits) -> Self {
636            self.stop_bits = stop_bits;
637            self
638        }
639
640        #[must_use]
641        pub fn flow_control(mut self, flow_control: FlowControl) -> Self {
642            self.flow_control = flow_control;
643            self
644        }
645
646        #[must_use]
647        /// This setting only has effect if flow control is enabled.
648        /// It determines how many bytes must be received before `RTS` line is asserted.
649        /// Notice that count starts from `0` which means that `RTS` is asserted after every received byte.
650        pub fn flow_control_rts_threshold(mut self, flow_control_rts_threshold: u8) -> Self {
651            self.flow_control_rts_threshold = flow_control_rts_threshold;
652            self
653        }
654
655        #[must_use]
656        pub fn source_clock(mut self, source_clock: SourceClock) -> Self {
657            self.source_clock = source_clock;
658            self
659        }
660
661        #[must_use]
662        pub fn tx_fifo_size(mut self, tx_fifo_size: usize) -> Self {
663            self.tx_fifo_size = tx_fifo_size;
664            self
665        }
666
667        #[must_use]
668        pub fn rx_fifo_size(mut self, rx_fifo_size: usize) -> Self {
669            self.rx_fifo_size = rx_fifo_size;
670            self
671        }
672
673        #[must_use]
674        pub fn queue_size(mut self, queue_size: usize) -> Self {
675            self.queue_size = queue_size;
676            self
677        }
678    }
679
680    impl Default for Config {
681        fn default() -> Config {
682            Config::new()
683        }
684    }
685}
686
687pub trait Uart {
688    fn port() -> uart_port_t;
689}
690
691crate::embedded_hal_error!(
692    SerialError,
693    embedded_hal_nb::serial::Error,
694    embedded_hal_nb::serial::ErrorKind
695);
696
697#[derive(Clone, Copy)]
698#[repr(transparent)]
699pub struct UartEvent {
700    raw: uart_event_t,
701}
702
703impl UartEvent {
704    pub fn payload(&self) -> UartEventPayload {
705        #[allow(non_upper_case_globals)]
706        match self.raw.type_ {
707            uart_event_type_t_UART_DATA => UartEventPayload::Data {
708                size: self.raw.size,
709                timeout: self.raw.timeout_flag,
710            },
711            uart_event_type_t_UART_BREAK => UartEventPayload::Break,
712            uart_event_type_t_UART_BUFFER_FULL => UartEventPayload::RxBufferFull,
713            uart_event_type_t_UART_FIFO_OVF => UartEventPayload::RxFifoOverflow,
714            uart_event_type_t_UART_FRAME_ERR => UartEventPayload::FrameError,
715            uart_event_type_t_UART_PARITY_ERR => UartEventPayload::ParityError,
716            uart_event_type_t_UART_DATA_BREAK => UartEventPayload::DataBreak,
717            uart_event_type_t_UART_PATTERN_DET => UartEventPayload::PatternDetected,
718            _ => UartEventPayload::Unknown,
719        }
720    }
721}
722
723#[derive(Clone, Copy, Debug)]
724#[non_exhaustive]
725pub enum UartEventPayload {
726    /// UART data was received and/or a timeout was triggered
727    Data {
728        /// The number of bytes received
729        size: usize,
730        /// Whether a timeout has occurred.
731        /// It is possible that bytes have been received
732        /// and this is set to `true` in case the driver
733        /// processed both interrupts at the same time.
734        timeout: bool,
735    },
736    /// Represents DATA event with timeout_flag set
737    Break,
738    RxBufferFull,
739    RxFifoOverflow,
740    FrameError,
741    ParityError,
742    DataBreak,
743    PatternDetected,
744    Unknown,
745}
746
747/// Serial abstraction
748pub struct UartDriver<'d> {
749    port: u8,
750    queue: Option<Queue<UartEvent>>,
751    _p: PhantomData<&'d mut ()>,
752}
753
754unsafe impl Send for UartDriver<'_> {}
755unsafe impl Sync for UartDriver<'_> {}
756
757/// Serial receiver
758pub struct UartRxDriver<'d> {
759    port: u8,
760    owner: Owner,
761    queue: Option<Queue<UartEvent>>,
762    _p: PhantomData<&'d mut ()>,
763}
764
765/// Serial transmitter
766pub struct UartTxDriver<'d> {
767    port: u8,
768    owner: Owner,
769    queue: Option<Queue<UartEvent>>,
770    _p: PhantomData<&'d mut ()>,
771}
772
773impl<'d> UartDriver<'d> {
774    /// Create a new serial driver
775    pub fn new<UART: Uart + 'd>(
776        uart: UART,
777        tx: impl OutputPin + 'd,
778        rx: impl InputPin + 'd,
779        cts: Option<impl InputPin + 'd>,
780        rts: Option<impl OutputPin + 'd>,
781        config: &config::Config,
782    ) -> Result<Self, EspError> {
783        let mut q_handle_raw = ptr::null_mut();
784        let q_handle = if config.queue_size > 0 {
785            Some(&mut q_handle_raw)
786        } else {
787            None
788        };
789        if let Err(err) = new_common(uart, Some(tx), Some(rx), cts, rts, config, q_handle) {
790            // Roll back driver registration on failure to avoid dangling driver state
791            if let Err(e) = delete_driver(UART::port() as _) {
792                ::log::error!("Failed to delete UART driver: {}", e);
793            }
794
795            return Err(err);
796        }
797
798        // SAFTEY: okay because Queue borrows self
799        // SAFETY: we can safely use UartEvent instead of uart_event_t because of repr(transparent)
800        let queue = match q_handle_raw.is_null() {
801            false => Some(unsafe { Queue::new_borrowed(q_handle_raw) }),
802            true => None,
803        };
804
805        Ok(Self {
806            port: UART::port() as _,
807            queue,
808            _p: PhantomData,
809        })
810    }
811
812    /// Retrieves the event queue for this UART. Returns `None` if
813    /// the config specified 0 for `queue_size`.
814    pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
815        self.queue.as_ref()
816    }
817
818    /// Change the number of stop bits
819    pub fn change_stop_bits(&self, stop_bits: config::StopBits) -> Result<&Self, EspError> {
820        change_stop_bits(self.port(), stop_bits).map(|_| self)
821    }
822
823    /// Returns the current number of stop bits
824    pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
825        stop_bits(self.port())
826    }
827
828    /// Change the number of data bits
829    pub fn change_data_bits(&self, data_bits: config::DataBits) -> Result<&Self, EspError> {
830        change_data_bits(self.port(), data_bits).map(|_| self)
831    }
832
833    /// Return the current number of data bits
834    pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
835        data_bits(self.port())
836    }
837
838    /// Change the type of parity checking
839    pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
840        change_parity(self.port(), parity).map(|_| self)
841    }
842
843    /// Returns the current type of parity checking
844    pub fn parity(&self) -> Result<config::Parity, EspError> {
845        parity(self.port())
846    }
847
848    /// Change the baudrate.
849    ///
850    /// Will automatically select the clock source. When possible the reference clock (1MHz) will
851    /// be used, because this is constant when the clock source/frequency changes.
852    /// However if one of the clock frequencies is below 10MHz or if the baudrate is above
853    /// the reference clock or if the baudrate cannot be set within 1.5%
854    /// then use the APB clock.
855    pub fn change_baudrate<T: Into<Hertz> + Copy>(&self, baudrate: T) -> Result<&Self, EspError> {
856        change_baudrate(self.port(), baudrate).map(|_| self)
857    }
858
859    /// Returns the current baudrate
860    pub fn baudrate(&self) -> Result<Hertz, EspError> {
861        baudrate(self.port())
862    }
863
864    /// Split the serial driver in separate TX and RX drivers
865    pub fn split(&mut self) -> (UartTxDriver<'_>, UartRxDriver<'_>) {
866        (
867            UartTxDriver {
868                port: self.port,
869                owner: Owner::Borrowed,
870                queue: self
871                    .queue
872                    .as_ref()
873                    .map(|queue| unsafe { Queue::new_borrowed(queue.as_raw()) }),
874                _p: PhantomData,
875            },
876            UartRxDriver {
877                port: self.port,
878                owner: Owner::Borrowed,
879                queue: self
880                    .queue
881                    .as_ref()
882                    .map(|queue| unsafe { Queue::new_borrowed(queue.as_raw()) }),
883                _p: PhantomData,
884            },
885        )
886    }
887
888    /// Split the serial driver in separate TX and RX drivers.
889    ///
890    /// Unlike [`split`], the halves are owned and reference counted.
891    pub fn into_split(self) -> (UartTxDriver<'d>, UartRxDriver<'d>) {
892        let port = self.port;
893        let tx_queue = self
894            .queue
895            .as_ref()
896            .map(|queue| unsafe { Queue::new_borrowed(queue.as_raw()) });
897        let rx_queue = self
898            .queue
899            .as_ref()
900            .map(|queue| unsafe { Queue::new_borrowed(queue.as_raw()) });
901        let _ = ManuallyDrop::new(self);
902        REFS[port as usize].fetch_add(2, Ordering::SeqCst);
903        (
904            UartTxDriver {
905                port,
906                owner: Owner::Shared,
907                queue: tx_queue,
908                _p: PhantomData,
909            },
910            UartRxDriver {
911                port,
912                owner: Owner::Shared,
913                queue: rx_queue,
914                _p: PhantomData,
915            },
916        )
917    }
918
919    /// Read multiple bytes into a slice
920    pub fn read(&self, buf: &mut [u8], timeout: TickType_t) -> Result<usize, EspError> {
921        self.rx().read(buf, timeout)
922    }
923
924    /// Write multiple bytes from a slice
925    pub fn write(&self, bytes: &[u8]) -> Result<usize, EspError> {
926        self.tx().write(bytes)
927    }
928
929    /// Write multiple bytes from a slice, then send a break condition.
930    pub fn write_with_break(&self, bytes: &[u8], brk_len: i32) -> Result<usize, EspError> {
931        self.tx().write_with_break(bytes, brk_len)
932    }
933
934    /// Write multiple bytes from a slice directly to the TX FIFO hardware.
935    /// Returns the number of bytes written, where 0 would mean that the TX FIFO is full.
936    ///
937    /// NOTE: In case the UART TX buffer is enabled, this method might have unpredictable results
938    /// when used together with method `write`, as the latter will push the data to be sent to the
939    /// TX buffer first.
940    ///
941    /// To avoid this, always call `wait_done` after the last call to `write` and before
942    /// calling this method.
943    pub fn write_nb(&self, bytes: &[u8]) -> Result<usize, EspError> {
944        self.tx().write_nb(bytes)
945    }
946
947    /// Clears the receive buffer.
948    #[deprecated(since = "0.41.3", note = "Use UartDriver::clear_rx instead")]
949    pub fn flush_read(&self) -> Result<(), EspError> {
950        self.rx().clear()
951    }
952
953    /// Clears the receive buffer.
954    pub fn clear_rx(&self) -> Result<(), EspError> {
955        self.rx().clear()
956    }
957
958    /// Waits for the transmission to complete.
959    #[deprecated(since = "0.41.3", note = "Use UartDriver::wait_tx_done instead")]
960    pub fn flush_write(&self) -> Result<(), EspError> {
961        self.tx().wait_done(delay::BLOCK)
962    }
963
964    /// Waits until the transmission is complete or until the specified timeout expires.
965    pub fn wait_tx_done(&self, timeout: TickType_t) -> Result<(), EspError> {
966        self.tx().wait_done(timeout)
967    }
968
969    pub fn port(&self) -> uart_port_t {
970        self.port as _
971    }
972
973    /// Get count of remaining bytes in the receive ring buffer
974    pub fn remaining_read(&self) -> Result<usize, EspError> {
975        remaining_unread_bytes(self.port())
976    }
977
978    /// Get count of remaining capacity in the transmit ring buffer
979    #[cfg(any(
980        not(esp_idf_version_major = "4"),
981        all(
982            esp_idf_version_minor = "4",
983            not(any(esp_idf_version_patch = "0", esp_idf_version_patch = "1")),
984        ),
985    ))]
986    pub fn remaining_write(&self) -> Result<usize, EspError> {
987        remaining_write_capacity(self.port())
988    }
989
990    fn rx(&self) -> ManuallyDrop<UartRxDriver<'_>> {
991        ManuallyDrop::new(UartRxDriver {
992            port: self.port,
993            owner: Owner::Borrowed,
994            queue: self
995                .queue
996                .as_ref()
997                .map(|queue| unsafe { Queue::new_borrowed(queue.as_raw()) }),
998            _p: PhantomData,
999        })
1000    }
1001
1002    fn tx(&self) -> ManuallyDrop<UartTxDriver<'_>> {
1003        ManuallyDrop::new(UartTxDriver {
1004            port: self.port,
1005            owner: Owner::Borrowed,
1006            queue: self
1007                .queue
1008                .as_ref()
1009                .map(|queue| unsafe { Queue::new_borrowed(queue.as_raw()) }),
1010            _p: PhantomData,
1011        })
1012    }
1013}
1014
1015impl Drop for UartDriver<'_> {
1016    fn drop(&mut self) {
1017        delete_driver(self.port()).unwrap();
1018    }
1019}
1020
1021impl embedded_io::ErrorType for UartDriver<'_> {
1022    type Error = EspIOError;
1023}
1024
1025impl embedded_io::Read for UartDriver<'_> {
1026    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1027        UartDriver::read(self, buf, delay::BLOCK).map_err(EspIOError)
1028    }
1029}
1030
1031impl embedded_io::Write for UartDriver<'_> {
1032    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1033        UartDriver::write(self, buf).map_err(EspIOError)
1034    }
1035
1036    fn flush(&mut self) -> Result<(), Self::Error> {
1037        UartDriver::wait_tx_done(self, delay::BLOCK).map_err(EspIOError)
1038    }
1039}
1040
1041impl embedded_hal_0_2::serial::Read<u8> for UartDriver<'_> {
1042    type Error = SerialError;
1043
1044    fn read(&mut self) -> nb::Result<u8, Self::Error> {
1045        embedded_hal_0_2::serial::Read::read(&mut *self.rx())
1046    }
1047}
1048
1049impl embedded_hal_0_2::serial::Write<u8> for UartDriver<'_> {
1050    type Error = SerialError;
1051
1052    fn flush(&mut self) -> nb::Result<(), Self::Error> {
1053        embedded_hal_0_2::serial::Write::flush(&mut *self.tx())
1054    }
1055
1056    fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
1057        embedded_hal_0_2::serial::Write::write(&mut *self.tx(), byte)
1058    }
1059}
1060
1061impl embedded_hal_nb::serial::ErrorType for UartDriver<'_> {
1062    type Error = SerialError;
1063}
1064
1065impl embedded_hal_nb::serial::Read<u8> for UartDriver<'_> {
1066    fn read(&mut self) -> nb::Result<u8, Self::Error> {
1067        embedded_hal_nb::serial::Read::read(&mut *self.rx())
1068    }
1069}
1070
1071impl embedded_hal_nb::serial::Write<u8> for UartDriver<'_> {
1072    fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
1073        embedded_hal_nb::serial::Write::write(&mut *self.tx(), byte)
1074    }
1075
1076    fn flush(&mut self) -> nb::Result<(), Self::Error> {
1077        embedded_hal_nb::serial::Write::flush(&mut *self.tx())
1078    }
1079}
1080
1081impl core::fmt::Write for UartDriver<'_> {
1082    fn write_str(&mut self, s: &str) -> core::fmt::Result {
1083        self.tx().write_str(s)
1084    }
1085}
1086
1087impl<'d> UartRxDriver<'d> {
1088    /// Create a new serial receiver
1089    pub fn new<UART: Uart + 'd>(
1090        uart: UART,
1091        rx: impl InputPin + 'd,
1092        cts: Option<impl InputPin + 'd>,
1093        rts: Option<impl OutputPin + 'd>,
1094        config: &config::Config,
1095    ) -> Result<Self, EspError> {
1096        let mut q_handle_raw = ptr::null_mut();
1097        let q_handle = if config.queue_size > 0 {
1098            Some(&mut q_handle_raw)
1099        } else {
1100            None
1101        };
1102        new_common(
1103            uart,
1104            None::<AnyOutputPin>,
1105            Some(rx),
1106            cts,
1107            rts,
1108            config,
1109            q_handle,
1110        )?;
1111
1112        // SAFTEY: okay because Queue borrows self
1113        // SAFETY: we can safely use UartEvent instead of uart_event_t because of repr(transparent)
1114        let queue = match q_handle_raw.is_null() {
1115            false => Some(unsafe { Queue::new_borrowed(q_handle_raw) }),
1116            true => None,
1117        };
1118
1119        Ok(Self {
1120            port: UART::port() as _,
1121            owner: Owner::Owned,
1122            queue,
1123            _p: PhantomData,
1124        })
1125    }
1126
1127    /// Retrieves the event queue for this UART. Returns `None` if
1128    /// the config specified 0 for `queue_size`.
1129    pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
1130        self.queue.as_ref()
1131    }
1132
1133    /// Change the number of stop bits
1134    pub fn change_stop_bits(&self, stop_bits: config::StopBits) -> Result<&Self, EspError> {
1135        change_stop_bits(self.port(), stop_bits).map(|_| self)
1136    }
1137
1138    /// Returns the current number of stop bits
1139    pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
1140        stop_bits(self.port())
1141    }
1142
1143    /// Change the number of data bits
1144    pub fn change_data_bits(&self, data_bits: config::DataBits) -> Result<&Self, EspError> {
1145        change_data_bits(self.port(), data_bits).map(|_| self)
1146    }
1147
1148    /// Return the current number of data bits
1149    pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
1150        data_bits(self.port())
1151    }
1152
1153    /// Change the type of parity checking
1154    pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
1155        change_parity(self.port(), parity).map(|_| self)
1156    }
1157
1158    /// Returns the current type of parity checking
1159    pub fn parity(&self) -> Result<config::Parity, EspError> {
1160        parity(self.port())
1161    }
1162
1163    /// Change the baudrate.
1164    ///
1165    /// Will automatically select the clock source. When possible the reference clock (1MHz) will
1166    /// be used, because this is constant when the clock source/frequency changes.
1167    /// However if one of the clock frequencies is below 10MHz or if the baudrate is above
1168    /// the reference clock or if the baudrate cannot be set within 1.5%
1169    /// then use the APB clock.
1170    pub fn change_baudrate<T: Into<Hertz> + Copy>(&self, baudrate: T) -> Result<&Self, EspError> {
1171        change_baudrate(self.port(), baudrate).map(|_| self)
1172    }
1173
1174    /// Returns the current baudrate
1175    pub fn baudrate(&self) -> Result<Hertz, EspError> {
1176        baudrate(self.port())
1177    }
1178
1179    /// Read multiple bytes into a slice; block until specified timeout
1180    /// Returns:
1181    /// - `Ok(0)` if the buffer is of length 0
1182    /// - `Ok(n)` if `n` bytes were read, where n is > 0
1183    /// - `Err(EspError::Timeout)` if no bytes were read within the specified timeout
1184    pub fn read(&self, buf: &mut [u8], delay: TickType_t) -> Result<usize, EspError> {
1185        // `uart_read_bytes` has a WEIRD semantics:
1186        // - If the data in the internal ring-buffer is LESS than the passed `length`
1187        //   **it will wait (with a `delay` timeout) UNTIL it can return up to `length` bytes**
1188        //   (and if the timeout had expired, it will return whatever it was able to read - possibly nothing too)
1189        // - This is not matching the typical `read` syscall semantics where it only
1190        //   returns what is available in the internal buffer and does not wait for more;
1191        //   and only blocks if the internal buffer is empty, and only until _some_ data becomes available
1192        //   but NOT until `buf.len()` data is available.
1193        //
1194        // Therefore - and to avoid confusion - we will implement the typical `read` syscall
1195        // semantics here
1196
1197        // Passing an empty buffer is valid, but it means we'll always read 0 bytes
1198        if buf.is_empty() {
1199            return Ok(0);
1200        }
1201
1202        // First try to read without blocking
1203        let len = unsafe {
1204            uart_read_bytes(
1205                self.port(),
1206                buf.as_mut_ptr().cast(),
1207                buf.len() as u32,
1208                delay::NON_BLOCK,
1209            )
1210        };
1211
1212        if len > 0 || delay == delay::NON_BLOCK {
1213            // Some data was read, or the user requested a non-blocking read anyway
1214            return match len {
1215                -1 | 0 => Err(EspError::from_infallible::<ESP_ERR_TIMEOUT>()),
1216                len => Ok(len as usize),
1217            };
1218        }
1219
1220        // Now block until at least one byte is available
1221        let mut len =
1222            unsafe { uart_read_bytes(self.port(), buf.as_mut_ptr().cast(), 1_u32, delay) };
1223
1224        if len > 0 && buf.len() > 1 {
1225            // Try to read more than that one byte in a non-blocking way
1226            // just because we can, and this lowers the latency of `read`.
1227            // To comply with the `read` syscall semantics we don't have to necessarily do this
1228            let extra_len = unsafe {
1229                uart_read_bytes(
1230                    self.port(),
1231                    buf[1..].as_mut_ptr().cast(),
1232                    (buf.len() - 1) as u32,
1233                    delay::NON_BLOCK,
1234                )
1235            };
1236
1237            if extra_len > 0 {
1238                len += extra_len;
1239            }
1240        }
1241
1242        match len {
1243            -1 | 0 => Err(EspError::from_infallible::<ESP_ERR_TIMEOUT>()),
1244            len => Ok(len as usize),
1245        }
1246    }
1247
1248    /// Clears the receive buffer.
1249    #[deprecated(since = "0.41.3", note = "Use `UartRxDriver::clear` instead")]
1250    pub fn flush(&self) -> Result<(), EspError> {
1251        self.clear()
1252    }
1253
1254    pub fn clear(&self) -> Result<(), EspError> {
1255        esp!(unsafe { uart_flush_input(self.port()) })?;
1256
1257        Ok(())
1258    }
1259
1260    pub fn port(&self) -> uart_port_t {
1261        self.port as _
1262    }
1263
1264    /// Get count of remaining bytes in the receive ring buffer
1265    pub fn count(&self) -> Result<usize, EspError> {
1266        remaining_unread_bytes(self.port())
1267    }
1268}
1269
1270impl Drop for UartRxDriver<'_> {
1271    fn drop(&mut self) {
1272        self.owner.drop_impl(self.port()).unwrap()
1273    }
1274}
1275
1276impl embedded_io::ErrorType for UartRxDriver<'_> {
1277    type Error = EspIOError;
1278}
1279
1280impl embedded_io::Read for UartRxDriver<'_> {
1281    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1282        UartRxDriver::read(self, buf, delay::BLOCK).map_err(EspIOError)
1283    }
1284}
1285
1286impl embedded_hal_0_2::serial::Read<u8> for UartRxDriver<'_> {
1287    type Error = SerialError;
1288
1289    fn read(&mut self) -> nb::Result<u8, Self::Error> {
1290        let mut buf = [0_u8];
1291
1292        let result = UartRxDriver::read(self, &mut buf, NON_BLOCK);
1293
1294        check_nb(result, buf[0])
1295    }
1296}
1297
1298impl embedded_hal_nb::serial::ErrorType for UartRxDriver<'_> {
1299    type Error = SerialError;
1300}
1301
1302impl embedded_hal_nb::serial::Read<u8> for UartRxDriver<'_> {
1303    fn read(&mut self) -> nb::Result<u8, Self::Error> {
1304        let mut buf = [0_u8];
1305
1306        let result = UartRxDriver::read(self, &mut buf, NON_BLOCK);
1307
1308        check_nb(result, buf[0])
1309    }
1310}
1311
1312impl<'d> UartTxDriver<'d> {
1313    /// Create a new serial transmitter
1314    pub fn new<UART: Uart + 'd>(
1315        uart: UART,
1316        tx: impl OutputPin + 'd,
1317        cts: Option<impl InputPin + 'd>,
1318        rts: Option<impl OutputPin + 'd>,
1319        config: &config::Config,
1320    ) -> Result<Self, EspError> {
1321        let mut q_handle_raw = ptr::null_mut();
1322        let q_handle = if config.queue_size > 0 {
1323            Some(&mut q_handle_raw)
1324        } else {
1325            None
1326        };
1327        new_common(
1328            uart,
1329            Some(tx),
1330            None::<AnyInputPin>,
1331            cts,
1332            rts,
1333            config,
1334            q_handle,
1335        )?;
1336
1337        // SAFTEY: okay because Queue borrows self
1338        // SAFETY: we can safely use UartEvent instead of uart_event_t because of repr(transparent)
1339        let queue = match q_handle_raw.is_null() {
1340            false => Some(unsafe { Queue::new_borrowed(q_handle_raw) }),
1341            true => None,
1342        };
1343
1344        Ok(Self {
1345            port: UART::port() as _,
1346            owner: Owner::Owned,
1347            queue,
1348            _p: PhantomData,
1349        })
1350    }
1351
1352    /// Retrieves the event queue for this UART. Returns `None` if
1353    /// the config specified 0 for `queue_size`.
1354    pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
1355        self.queue.as_ref()
1356    }
1357
1358    /// Change the number of stop bits
1359    pub fn change_stop_bits(&self, stop_bits: config::StopBits) -> Result<&Self, EspError> {
1360        change_stop_bits(self.port(), stop_bits).map(|_| self)
1361    }
1362
1363    /// Returns the current number of stop bits
1364    pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
1365        stop_bits(self.port())
1366    }
1367
1368    /// Change the number of data bits
1369    pub fn change_data_bits(&self, data_bits: config::DataBits) -> Result<&Self, EspError> {
1370        change_data_bits(self.port(), data_bits).map(|_| self)
1371    }
1372
1373    /// Return the current number of data bits
1374    pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
1375        data_bits(self.port())
1376    }
1377
1378    /// Change the type of parity checking
1379    pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
1380        change_parity(self.port(), parity).map(|_| self)
1381    }
1382
1383    /// Returns the current type of parity checking
1384    pub fn parity(&self) -> Result<config::Parity, EspError> {
1385        parity(self.port())
1386    }
1387
1388    /// Change the baudrate.
1389    ///
1390    /// Will automatically select the clock source. When possible the reference clock (1MHz) will
1391    /// be used, because this is constant when the clock source/frequency changes.
1392    /// However if one of the clock frequencies is below 10MHz or if the baudrate is above
1393    /// the reference clock or if the baudrate cannot be set within 1.5%
1394    /// then use the APB clock.
1395    pub fn change_baudrate<T: Into<Hertz> + Copy>(&self, baudrate: T) -> Result<&Self, EspError> {
1396        change_baudrate(self.port(), baudrate).map(|_| self)
1397    }
1398
1399    /// Returns the current baudrate
1400    pub fn baudrate(&self) -> Result<Hertz, EspError> {
1401        baudrate(self.port())
1402    }
1403
1404    /// Write multiple bytes from a slice
1405    pub fn write(&mut self, bytes: &[u8]) -> Result<usize, EspError> {
1406        // `uart_write_bytes()` returns error (-1) or how many bytes were written
1407        let len = unsafe { uart_write_bytes(self.port(), bytes.as_ptr().cast(), bytes.len()) };
1408
1409        if len >= 0 {
1410            Ok(len as usize)
1411        } else {
1412            Err(EspError::from_infallible::<ESP_ERR_INVALID_STATE>())
1413        }
1414    }
1415
1416    /// Write multiple bytes from a slice, then send a break condition.
1417    pub fn write_with_break(&mut self, bytes: &[u8], brk_len: i32) -> Result<usize, EspError> {
1418        // `uart_write_bytes_with_break()` returns error (-1) or how many bytes were written
1419        let len = unsafe {
1420            uart_write_bytes_with_break(self.port(), bytes.as_ptr().cast(), bytes.len(), brk_len)
1421        };
1422
1423        if len >= 0 {
1424            Ok(len as usize)
1425        } else {
1426            Err(EspError::from_infallible::<ESP_ERR_INVALID_STATE>())
1427        }
1428    }
1429
1430    /// Write multiple bytes from a slice directly to the TX FIFO hardware.
1431    /// Returns the number of bytes written, where 0 would mean that the TX FIFO is full.
1432    ///
1433    /// NOTE: In case the UART TX buffer is enabled, this method might have unpredictable results
1434    /// when used together with method `write`, as the latter will push the data to be sent to the
1435    /// TX buffer first.
1436    ///
1437    /// To avoid this, always call `wait_done` after the last call to `write` and before
1438    /// calling this method.
1439    pub fn write_nb(&self, bytes: &[u8]) -> Result<usize, EspError> {
1440        let ret = unsafe { uart_tx_chars(self.port(), bytes.as_ptr().cast(), bytes.len() as _) };
1441
1442        if ret < 0 {
1443            esp!(ret)?;
1444        }
1445
1446        Ok(ret as usize)
1447    }
1448
1449    /// Waits until the transmission is complete or until the specified timeout expires.
1450    pub fn wait_done(&self, timeout: TickType_t) -> Result<(), EspError> {
1451        esp!(unsafe { uart_wait_tx_done(self.port(), timeout) })?;
1452
1453        Ok(())
1454    }
1455
1456    /// Waits until the transmission is complete.
1457    #[deprecated(since = "0.41.3", note = "Use `UartTxDriver::wait_done` instead")]
1458    pub fn flush(&mut self) -> Result<(), EspError> {
1459        self.wait_done(delay::BLOCK)
1460    }
1461
1462    pub fn port(&self) -> uart_port_t {
1463        self.port as _
1464    }
1465
1466    /// Get count of remaining capacity in the transmit ring buffer
1467    #[cfg(any(
1468        not(esp_idf_version_major = "4"),
1469        all(
1470            esp_idf_version_minor = "4",
1471            not(any(esp_idf_version_patch = "0", esp_idf_version_patch = "1")),
1472        ),
1473    ))]
1474    pub fn count(&self) -> Result<usize, EspError> {
1475        remaining_write_capacity(self.port())
1476    }
1477}
1478
1479impl Drop for UartTxDriver<'_> {
1480    fn drop(&mut self) {
1481        self.owner.drop_impl(self.port()).unwrap()
1482    }
1483}
1484
1485impl embedded_io::Write for UartTxDriver<'_> {
1486    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1487        UartTxDriver::write(self, buf).map_err(EspIOError)
1488    }
1489
1490    fn flush(&mut self) -> Result<(), Self::Error> {
1491        UartTxDriver::wait_done(self, delay::BLOCK).map_err(EspIOError)
1492    }
1493}
1494
1495impl embedded_io::ErrorType for UartTxDriver<'_> {
1496    type Error = EspIOError;
1497}
1498
1499impl embedded_hal_0_2::serial::Write<u8> for UartTxDriver<'_> {
1500    type Error = SerialError;
1501
1502    fn flush(&mut self) -> nb::Result<(), Self::Error> {
1503        check_nb_timeout(UartTxDriver::wait_done(self, delay::NON_BLOCK))
1504    }
1505
1506    fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
1507        check_nb(UartTxDriver::write_nb(self, &[byte]), ())
1508    }
1509}
1510
1511impl embedded_hal_nb::serial::ErrorType for UartTxDriver<'_> {
1512    type Error = SerialError;
1513}
1514
1515impl embedded_hal_nb::serial::Write<u8> for UartTxDriver<'_> {
1516    fn flush(&mut self) -> nb::Result<(), Self::Error> {
1517        check_nb_timeout(UartTxDriver::wait_done(self, delay::NON_BLOCK))
1518    }
1519
1520    fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
1521        check_nb(UartTxDriver::write_nb(self, &[byte]), ())
1522    }
1523}
1524
1525impl core::fmt::Write for UartTxDriver<'_> {
1526    fn write_str(&mut self, s: &str) -> core::fmt::Result {
1527        let buf = s.as_bytes();
1528        let mut offset = 0;
1529
1530        while offset < buf.len() {
1531            offset += self.write(buf).map_err(|_| core::fmt::Error)?
1532        }
1533
1534        Ok(())
1535    }
1536}
1537
1538pub struct AsyncUartDriver<'d, T>
1539where
1540    T: BorrowMut<UartDriver<'d>>,
1541{
1542    driver: T,
1543    task: TaskHandle_t,
1544    _data: PhantomData<&'d ()>,
1545}
1546
1547impl<'d> AsyncUartDriver<'d, UartDriver<'d>> {
1548    pub fn new<UART: Uart + 'd>(
1549        uart: UART,
1550        tx: impl OutputPin + 'd,
1551        rx: impl InputPin + 'd,
1552        cts: Option<impl InputPin + 'd>,
1553        rts: Option<impl OutputPin + 'd>,
1554        config: &config::Config,
1555    ) -> Result<Self, EspError> {
1556        Self::wrap(UartDriver::new(uart, tx, rx, cts, rts, config)?)
1557    }
1558}
1559
1560impl<'d, T> AsyncUartDriver<'d, T>
1561where
1562    T: BorrowMut<UartDriver<'d>>,
1563{
1564    pub fn wrap(driver: T) -> Result<Self, EspError> {
1565        Self::wrap_custom(driver, None, None)
1566    }
1567
1568    pub fn wrap_custom(
1569        driver: T,
1570        priority: Option<u8>,
1571        pin_to_core: Option<Core>,
1572    ) -> Result<Self, EspError> {
1573        let task = new_task_common(
1574            driver.borrow().port,
1575            driver.borrow().event_queue(),
1576            priority,
1577            pin_to_core,
1578        )?;
1579
1580        Ok(Self {
1581            driver,
1582            task,
1583            _data: PhantomData,
1584        })
1585    }
1586
1587    pub fn driver(&self) -> &UartDriver<'d> {
1588        self.driver.borrow()
1589    }
1590
1591    pub fn driver_mut(&mut self) -> &mut UartDriver<'d> {
1592        self.driver.borrow_mut()
1593    }
1594
1595    /// Split the serial driver in separate TX and RX drivers
1596    pub fn split(
1597        &mut self,
1598    ) -> (
1599        AsyncUartTxDriver<'_, UartTxDriver<'_>>,
1600        AsyncUartRxDriver<'_, UartRxDriver<'_>>,
1601    ) {
1602        let (tx, rx) = self.driver_mut().split();
1603
1604        (
1605            AsyncUartTxDriver {
1606                driver: tx,
1607                task: None,
1608                _data: PhantomData,
1609            },
1610            AsyncUartRxDriver {
1611                driver: rx,
1612                task: None,
1613                _data: PhantomData,
1614            },
1615        )
1616    }
1617
1618    pub async fn read(&self, buf: &mut [u8]) -> Result<usize, EspError> {
1619        if buf.is_empty() {
1620            Ok(0)
1621        } else {
1622            loop {
1623                let res = self.driver.borrow().read(buf, delay::NON_BLOCK);
1624
1625                match res {
1626                    Ok(len) if len > 0 => return Ok(len),
1627                    Err(e) if e.code() != ESP_ERR_TIMEOUT => return Err(e),
1628                    _ => (),
1629                }
1630
1631                let port = self.driver.borrow().port as usize;
1632                READ_NOTIFS[port].wait().await;
1633            }
1634        }
1635    }
1636
1637    pub async fn write(&self, bytes: &[u8]) -> Result<usize, EspError> {
1638        if bytes.is_empty() {
1639            Ok(0)
1640        } else {
1641            loop {
1642                let res = self.driver.borrow().write_nb(bytes);
1643
1644                match res {
1645                    Ok(len) if len > 0 => return Ok(len),
1646                    Err(e) => return Err(e),
1647                    _ => (),
1648                }
1649
1650                // We cannot properly wait for the TX FIFO queue to become non-full
1651                // because the ESP IDF UART ISR does not notify us on that
1652                //
1653                // Instead, spin a busy loop, however still allowing other futures to be polled too.
1654                crate::task::yield_now().await;
1655            }
1656        }
1657    }
1658
1659    pub async fn wait_tx_done(&self) -> Result<(), EspError> {
1660        loop {
1661            let res = self.driver.borrow().wait_tx_done(delay::NON_BLOCK);
1662
1663            match res {
1664                Ok(()) => return Ok(()),
1665                Err(e) if e.code() != ESP_ERR_TIMEOUT => return Err(e),
1666                _ => (),
1667            }
1668
1669            // We cannot properly wait for the TX FIFO queue to become empty
1670            // because the ESP IDF UART ISR does not notify us on that
1671            //
1672            // Instead, spin a busy loop, however still allowing other futures to be polled too.
1673            crate::task::yield_now().await;
1674        }
1675    }
1676}
1677
1678unsafe impl<'d, T> Send for AsyncUartDriver<'d, T> where T: BorrowMut<UartDriver<'d>> + Send {}
1679unsafe impl<'d, T> Sync for AsyncUartDriver<'d, T> where T: BorrowMut<UartDriver<'d>> + Send + Sync {}
1680
1681impl<'d, T> Drop for AsyncUartDriver<'d, T>
1682where
1683    T: BorrowMut<UartDriver<'d>>,
1684{
1685    fn drop(&mut self) {
1686        drop_task_common(self.task, self.driver.borrow().port);
1687    }
1688}
1689
1690impl<'d, T> embedded_io::ErrorType for AsyncUartDriver<'d, T>
1691where
1692    T: BorrowMut<UartDriver<'d>>,
1693{
1694    type Error = EspIOError;
1695}
1696
1697impl<'d, T> embedded_io_async::Read for AsyncUartDriver<'d, T>
1698where
1699    T: BorrowMut<UartDriver<'d>>,
1700{
1701    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1702        AsyncUartDriver::read(self, buf).await.map_err(EspIOError)
1703    }
1704}
1705
1706impl<'d, T> embedded_io_async::Write for AsyncUartDriver<'d, T>
1707where
1708    T: BorrowMut<UartDriver<'d>>,
1709{
1710    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1711        AsyncUartDriver::write(self, buf).await.map_err(EspIOError)
1712    }
1713
1714    async fn flush(&mut self) -> Result<(), Self::Error> {
1715        AsyncUartDriver::wait_tx_done(self)
1716            .await
1717            .map_err(EspIOError)
1718    }
1719}
1720
1721pub struct AsyncUartRxDriver<'d, T>
1722where
1723    T: BorrowMut<UartRxDriver<'d>>,
1724{
1725    driver: T,
1726    task: Option<TaskHandle_t>,
1727    _data: PhantomData<&'d ()>,
1728}
1729
1730impl<'d> AsyncUartRxDriver<'d, UartRxDriver<'d>> {
1731    pub fn new<UART: Uart + 'd>(
1732        uart: UART,
1733        rx: impl InputPin + 'd,
1734        cts: Option<impl InputPin + 'd>,
1735        rts: Option<impl OutputPin + 'd>,
1736        config: &config::Config,
1737    ) -> Result<Self, EspError> {
1738        Self::wrap(UartRxDriver::new(uart, rx, cts, rts, config)?)
1739    }
1740}
1741
1742impl<'d, T> AsyncUartRxDriver<'d, T>
1743where
1744    T: BorrowMut<UartRxDriver<'d>>,
1745{
1746    pub fn wrap(driver: T) -> Result<Self, EspError> {
1747        Self::wrap_custom(driver, None, None)
1748    }
1749
1750    pub fn wrap_custom(
1751        driver: T,
1752        priority: Option<u8>,
1753        pin_to_core: Option<Core>,
1754    ) -> Result<Self, EspError> {
1755        let task = new_task_common(
1756            driver.borrow().port,
1757            driver.borrow().event_queue(),
1758            priority,
1759            pin_to_core,
1760        )?;
1761
1762        Ok(Self {
1763            driver,
1764            task: Some(task),
1765            _data: PhantomData,
1766        })
1767    }
1768
1769    pub fn driver(&self) -> &UartRxDriver<'d> {
1770        self.driver.borrow()
1771    }
1772
1773    pub fn driver_mut(&mut self) -> &mut UartRxDriver<'d> {
1774        self.driver.borrow_mut()
1775    }
1776
1777    pub async fn read(&self, buf: &mut [u8]) -> Result<usize, EspError> {
1778        if buf.is_empty() {
1779            Ok(0)
1780        } else {
1781            loop {
1782                let res = self.driver.borrow().read(buf, delay::NON_BLOCK);
1783
1784                match res {
1785                    Ok(len) if len > 0 => return Ok(len),
1786                    Err(e) if e.code() != ESP_ERR_TIMEOUT => return Err(e),
1787                    _ => (),
1788                }
1789
1790                let port = self.driver.borrow().port as usize;
1791                READ_NOTIFS[port].wait().await;
1792            }
1793        }
1794    }
1795}
1796
1797impl<'d, T> Drop for AsyncUartRxDriver<'d, T>
1798where
1799    T: BorrowMut<UartRxDriver<'d>>,
1800{
1801    fn drop(&mut self) {
1802        if let Some(task) = self.task {
1803            drop_task_common(task, self.driver.borrow().port);
1804        }
1805    }
1806}
1807
1808impl<'d, T> embedded_io::ErrorType for AsyncUartRxDriver<'d, T>
1809where
1810    T: BorrowMut<UartRxDriver<'d>>,
1811{
1812    type Error = EspIOError;
1813}
1814
1815impl<'d, T> embedded_io_async::Read for AsyncUartRxDriver<'d, T>
1816where
1817    T: BorrowMut<UartRxDriver<'d>>,
1818{
1819    async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
1820        AsyncUartRxDriver::read(self, buf).await.map_err(EspIOError)
1821    }
1822}
1823
1824pub struct AsyncUartTxDriver<'d, T>
1825where
1826    T: BorrowMut<UartTxDriver<'d>>,
1827{
1828    driver: T,
1829    task: Option<TaskHandle_t>,
1830    _data: PhantomData<&'d ()>,
1831}
1832
1833impl<'d> AsyncUartTxDriver<'d, UartTxDriver<'d>> {
1834    pub fn new<UART: Uart + 'd>(
1835        uart: UART,
1836        tx: impl OutputPin + 'd,
1837        cts: Option<impl InputPin + 'd>,
1838        rts: Option<impl OutputPin + 'd>,
1839        config: &config::Config,
1840    ) -> Result<Self, EspError> {
1841        Self::wrap(UartTxDriver::new(uart, tx, cts, rts, config)?)
1842    }
1843}
1844
1845impl<'d, T> AsyncUartTxDriver<'d, T>
1846where
1847    T: BorrowMut<UartTxDriver<'d>>,
1848{
1849    pub fn wrap(driver: T) -> Result<Self, EspError> {
1850        Self::wrap_custom(driver, None, None)
1851    }
1852
1853    pub fn wrap_custom(
1854        driver: T,
1855        priority: Option<u8>,
1856        pin_to_core: Option<Core>,
1857    ) -> Result<Self, EspError> {
1858        let task = new_task_common(
1859            driver.borrow().port,
1860            driver.borrow().event_queue(),
1861            priority,
1862            pin_to_core,
1863        )?;
1864
1865        Ok(Self {
1866            driver,
1867            task: Some(task),
1868            _data: PhantomData,
1869        })
1870    }
1871
1872    pub fn driver(&self) -> &UartTxDriver<'d> {
1873        self.driver.borrow()
1874    }
1875
1876    pub fn driver_mut(&mut self) -> &mut UartTxDriver<'d> {
1877        self.driver.borrow_mut()
1878    }
1879
1880    pub async fn write(&self, bytes: &[u8]) -> Result<usize, EspError> {
1881        if bytes.is_empty() {
1882            Ok(0)
1883        } else {
1884            loop {
1885                let res = self.driver.borrow().write_nb(bytes);
1886
1887                match res {
1888                    Ok(len) if len > 0 => return Ok(len),
1889                    Err(e) => return Err(e),
1890                    _ => (),
1891                }
1892
1893                // We cannot properly wait for the TX FIFO queue to become non-full
1894                // because the ESP IDF UART ISR does not notify us on that
1895                //
1896                // Instead, spin a busy loop, however still allowing other futures to be polled too.
1897                crate::task::yield_now().await;
1898            }
1899        }
1900    }
1901
1902    pub async fn wait_done(&self) -> Result<(), EspError> {
1903        loop {
1904            let res = self.driver.borrow().wait_done(delay::NON_BLOCK);
1905
1906            match res {
1907                Ok(()) => return Ok(()),
1908                Err(e) if e.code() != ESP_ERR_TIMEOUT => return Err(e),
1909                _ => (),
1910            }
1911
1912            // We cannot properly wait for the TX FIFO queue to become empty
1913            // because the ESP IDF UART ISR does not notify us on that
1914            //
1915            // Instead, spin a busy loop, however still allowing other futures to be polled too.
1916            crate::task::yield_now().await;
1917        }
1918    }
1919}
1920
1921impl<'d, T> Drop for AsyncUartTxDriver<'d, T>
1922where
1923    T: BorrowMut<UartTxDriver<'d>>,
1924{
1925    fn drop(&mut self) {
1926        if let Some(task) = self.task {
1927            drop_task_common(task, self.driver.borrow().port);
1928        }
1929    }
1930}
1931
1932impl<'d, T> embedded_io::ErrorType for AsyncUartTxDriver<'d, T>
1933where
1934    T: BorrowMut<UartTxDriver<'d>>,
1935{
1936    type Error = EspIOError;
1937}
1938
1939impl<'d, T> embedded_io_async::Write for AsyncUartTxDriver<'d, T>
1940where
1941    T: BorrowMut<UartTxDriver<'d>>,
1942{
1943    async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
1944        AsyncUartTxDriver::write(self, buf)
1945            .await
1946            .map_err(EspIOError)
1947    }
1948
1949    async fn flush(&mut self) -> Result<(), Self::Error> {
1950        AsyncUartTxDriver::wait_done(self).await.map_err(EspIOError)
1951    }
1952}
1953
1954fn new_task_common(
1955    port: u8,
1956    queue: Option<&Queue<UartEvent>>,
1957    priority: Option<u8>,
1958    pin_to_core: Option<Core>,
1959) -> Result<TaskHandle_t, EspError> {
1960    if let Some(queue) = queue {
1961        let port = port as usize;
1962
1963        unsafe {
1964            QUEUES[port] = queue.as_raw() as _;
1965        }
1966
1967        let res = unsafe {
1968            task::create(
1969                process_events,
1970                CStr::from_bytes_until_nul(b"UART - Events task\0").unwrap(),
1971                2048,
1972                port as _,
1973                priority.unwrap_or(6),
1974                pin_to_core,
1975            )
1976        };
1977
1978        if res.is_err() {
1979            unsafe {
1980                QUEUES[port] = core::ptr::null();
1981            }
1982        }
1983
1984        res
1985    } else {
1986        Err(EspError::from_infallible::<ESP_ERR_INVALID_ARG>())
1987    }
1988}
1989
1990fn drop_task_common(task: TaskHandle_t, port: u8) {
1991    unsafe {
1992        task::destroy(task);
1993        QUEUES[port as usize] = core::ptr::null_mut();
1994
1995        READ_NOTIFS[port as usize].reset();
1996        WRITE_NOTIFS[port as usize].reset();
1997        TX_NOTIFS[port as usize].reset();
1998    }
1999}
2000
2001extern "C" fn process_events(arg: *mut core::ffi::c_void) {
2002    let port: usize = arg as _;
2003    let queue: Queue<UartEvent> = unsafe { Queue::new_borrowed(QUEUES[port] as _) };
2004
2005    loop {
2006        if let Some((event, _)) = queue.recv_front(delay::BLOCK) {
2007            match event.payload() {
2008                UartEventPayload::Data { .. }
2009                | UartEventPayload::RxBufferFull
2010                | UartEventPayload::RxFifoOverflow => {
2011                    READ_NOTIFS[port].notify_lsb();
2012                }
2013                UartEventPayload::Break | UartEventPayload::DataBreak => {
2014                    WRITE_NOTIFS[port].notify_lsb();
2015                    TX_NOTIFS[port].notify_lsb();
2016                }
2017                _ => (),
2018            }
2019        }
2020    }
2021}
2022
2023fn new_common<'d, UART: Uart + 'd>(
2024    _uart: UART,
2025    tx: Option<impl OutputPin + 'd>,
2026    rx: Option<impl InputPin + 'd>,
2027    cts: Option<impl InputPin + 'd>,
2028    rts: Option<impl OutputPin + 'd>,
2029    config: &config::Config,
2030    queue: Option<&mut QueueHandle_t>,
2031) -> Result<(), EspError> {
2032    let uart_config = config.into();
2033
2034    esp!(unsafe { uart_param_config(UART::port(), &uart_config) })?;
2035
2036    #[cfg(esp_idf_version_at_least_6_0_0)]
2037    {
2038        esp!(unsafe {
2039            _uart_set_pin6(
2040                UART::port(),
2041                tx.as_ref().map_or(-1, |p| p.pin() as _),
2042                rx.as_ref().map_or(-1, |p| p.pin() as _),
2043                rts.as_ref().map_or(-1, |p| p.pin() as _),
2044                cts.as_ref().map_or(-1, |p| p.pin() as _),
2045                -1,
2046                -1,
2047            )
2048        })?;
2049    }
2050
2051    #[cfg(not(esp_idf_version_at_least_6_0_0))]
2052    {
2053        esp!(unsafe {
2054            uart_set_pin(
2055                UART::port(),
2056                tx.as_ref().map_or(-1, |p| p.pin() as _),
2057                rx.as_ref().map_or(-1, |p| p.pin() as _),
2058                rts.as_ref().map_or(-1, |p| p.pin() as _),
2059                cts.as_ref().map_or(-1, |p| p.pin() as _),
2060            )
2061        })?;
2062    }
2063
2064    esp!(unsafe {
2065        #[allow(clippy::unwrap_or_default)]
2066        uart_driver_install(
2067            UART::port(),
2068            if rx.is_some() {
2069                config.rx_fifo_size as _
2070            } else {
2071                0
2072            },
2073            if tx.is_some() {
2074                config.tx_fifo_size as _
2075            } else {
2076                0
2077            },
2078            config.queue_size as _,
2079            queue.map(|q| q as *mut _).unwrap_or(ptr::null_mut()),
2080            InterruptType::to_native(config.intr_flags) as i32,
2081        )
2082    })?;
2083
2084    esp!(unsafe { uart_set_mode(UART::port(), config.mode.into()) })?;
2085
2086    // Configure interrupts after installing the driver
2087    // so it won't get overwritten.
2088    let usr_intrs = config.event_config.clone().into();
2089    esp!(unsafe { uart_intr_config(UART::port(), &usr_intrs as *const _) })?;
2090
2091    Ok(())
2092}
2093
2094fn stop_bits(port: uart_port_t) -> Result<config::StopBits, EspError> {
2095    let mut stop_bits: uart_stop_bits_t = 0;
2096    esp_result!(
2097        unsafe { uart_get_stop_bits(port, &mut stop_bits) },
2098        stop_bits.into()
2099    )
2100}
2101
2102fn change_stop_bits(port: uart_port_t, stop_bits: config::StopBits) -> Result<(), EspError> {
2103    esp!(unsafe { uart_set_stop_bits(port, stop_bits.into()) })
2104}
2105
2106fn data_bits(port: uart_port_t) -> Result<config::DataBits, EspError> {
2107    let mut data_bits: uart_word_length_t = 0;
2108    esp_result!(
2109        unsafe { uart_get_word_length(port, &mut data_bits) },
2110        data_bits.into()
2111    )
2112}
2113
2114fn change_data_bits(port: uart_port_t, data_bits: config::DataBits) -> Result<(), EspError> {
2115    esp!(unsafe { uart_set_word_length(port, data_bits.into()) })
2116}
2117
2118fn parity(port: uart_port_t) -> Result<config::Parity, EspError> {
2119    let mut parity: uart_parity_t = 0;
2120    esp_result!(unsafe { uart_get_parity(port, &mut parity) }, parity.into())
2121}
2122
2123fn change_parity(port: uart_port_t, parity: config::Parity) -> Result<(), EspError> {
2124    esp!(unsafe { uart_set_parity(port, parity.into()) })
2125}
2126
2127fn baudrate(port: uart_port_t) -> Result<Hertz, EspError> {
2128    let mut baudrate: u32 = 0;
2129    esp_result!(
2130        unsafe { uart_get_baudrate(port, &mut baudrate) },
2131        baudrate.into()
2132    )
2133}
2134
2135fn change_baudrate<T: Into<Hertz> + Copy>(port: uart_port_t, baudrate: T) -> Result<(), EspError> {
2136    esp!(unsafe { uart_set_baudrate(port, baudrate.into().into()) })
2137}
2138
2139fn delete_driver(port: uart_port_t) -> Result<(), EspError> {
2140    esp!(unsafe { uart_driver_delete(port) })
2141}
2142
2143pub fn remaining_unread_bytes(port: uart_port_t) -> Result<usize, EspError> {
2144    let mut size = 0;
2145    esp_result!(unsafe { uart_get_buffered_data_len(port, &mut size) }, size)
2146}
2147
2148#[cfg(any(
2149    not(esp_idf_version_major = "4"),
2150    all(
2151        esp_idf_version_minor = "4",
2152        not(any(esp_idf_version_patch = "0", esp_idf_version_patch = "1")),
2153    ),
2154))]
2155pub fn remaining_write_capacity(port: uart_port_t) -> Result<usize, EspError> {
2156    let mut size = 0;
2157    esp_result!(
2158        unsafe { uart_get_tx_buffer_free_size(port, &mut size) },
2159        size
2160    )
2161}
2162
2163enum Owner {
2164    Owned,
2165    Borrowed,
2166    Shared,
2167}
2168
2169impl Owner {
2170    fn drop_impl(&self, port: uart_port_t) -> Result<(), EspError> {
2171        let needs_drop = match self {
2172            Owner::Owned => true,
2173            Owner::Borrowed => false,
2174            Owner::Shared => REFS[port as usize].fetch_sub(1, Ordering::SeqCst) == 0,
2175        };
2176
2177        if needs_drop {
2178            delete_driver(port)
2179        } else {
2180            Ok(())
2181        }
2182    }
2183}
2184
2185macro_rules! impl_uart {
2186    ($uart:ident: $port:expr) => {
2187        crate::impl_peripheral!($uart);
2188
2189        impl Uart for $uart<'_> {
2190            fn port() -> uart_port_t {
2191                $port
2192            }
2193        }
2194    };
2195}
2196
2197fn check_nb<T>(result: Result<usize, EspError>, value: T) -> nb::Result<T, SerialError> {
2198    match result {
2199        Ok(len) => {
2200            if len > 0 {
2201                Ok(value)
2202            } else {
2203                Err(nb::Error::WouldBlock)
2204            }
2205        }
2206        Err(err) if err.code() == ESP_ERR_TIMEOUT => Err(nb::Error::WouldBlock),
2207        Err(err) => Err(nb::Error::Other(SerialError::new(ErrorKind::Other, err))),
2208    }
2209}
2210
2211fn check_nb_timeout(result: Result<(), EspError>) -> nb::Result<(), SerialError> {
2212    match result {
2213        Ok(()) => Ok(()),
2214        Err(err) if err.code() == ESP_ERR_TIMEOUT => Err(nb::Error::WouldBlock),
2215        Err(err) => Err(nb::Error::Other(SerialError::new(ErrorKind::Other, err))),
2216    }
2217}
2218
2219impl_uart!(UART0: 0);
2220impl_uart!(UART1: 1);
2221#[cfg(any(esp32, esp32s3))]
2222impl_uart!(UART2: 2);
2223
2224#[allow(clippy::declare_interior_mutable_const)]
2225const NO_REFS: AtomicU8 = AtomicU8::new(0);
2226static REFS: [AtomicU8; SOC_UART_NUM as usize] = [NO_REFS; SOC_UART_NUM as usize];
2227
2228#[allow(clippy::declare_interior_mutable_const)]
2229const NOTIF: Notification = Notification::new();
2230static READ_NOTIFS: [Notification; SOC_UART_NUM as usize] = [NOTIF; SOC_UART_NUM as usize];
2231static WRITE_NOTIFS: [Notification; SOC_UART_NUM as usize] = [NOTIF; SOC_UART_NUM as usize];
2232static TX_NOTIFS: [Notification; SOC_UART_NUM as usize] = [NOTIF; SOC_UART_NUM as usize];
2233static mut QUEUES: [*const core::ffi::c_void; SOC_UART_NUM as usize] =
2234    [core::ptr::null(); SOC_UART_NUM as usize];