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