1use 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
63pub mod config {
65 use crate::{interrupt::InterruptType, units::*};
66 use enumset::{enum_set, EnumSet, EnumSetType};
67 use esp_idf_sys::*;
68
69 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
71 pub enum Mode {
72 UART,
74 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 #[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 #[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 #[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 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
199 pub enum StopBits {
200 STOP1,
202 STOP1P5,
204 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 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
232 pub enum SourceClock {
233 #[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 #[cfg(esp_idf_soc_uart_support_rtc_clk)]
242 RTC,
243 #[cfg(esp_idf_soc_uart_support_xtal_clk)]
245 Crystal,
246 #[allow(non_camel_case_types)]
248 #[cfg(esp_idf_soc_uart_support_pll_f80m_clk)]
249 PLL_F80M,
250 #[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 #[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 #[derive(Debug, Clone)]
402 pub struct EventConfig {
403 pub receive_timeout: Option<u8>,
409 pub rx_fifo_full: Option<u8>,
415 pub tx_fifo_empty: Option<u8>,
422 pub flags: EnumSet<EventFlags>,
424 #[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 #[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 pub intr_flags: EnumSet<InterruptType>,
531 pub event_config: EventConfig,
533 pub rx_fifo_size: usize,
535 pub tx_fifo_size: usize,
539 pub queue_size: usize,
542 #[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 #[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 #[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 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 Data {
728 size: usize,
730 timeout: bool,
735 },
736 Break,
738 RxBufferFull,
739 RxFifoOverflow,
740 FrameError,
741 ParityError,
742 DataBreak,
743 PatternDetected,
744 Unknown,
745}
746
747pub 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
757pub struct UartRxDriver<'d> {
759 port: u8,
760 owner: Owner,
761 queue: Option<Queue<UartEvent>>,
762 _p: PhantomData<&'d mut ()>,
763}
764
765pub 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 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 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 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 pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
815 self.queue.as_ref()
816 }
817
818 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 pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
825 stop_bits(self.port())
826 }
827
828 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 pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
835 data_bits(self.port())
836 }
837
838 pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
840 change_parity(self.port(), parity).map(|_| self)
841 }
842
843 pub fn parity(&self) -> Result<config::Parity, EspError> {
845 parity(self.port())
846 }
847
848 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 pub fn baudrate(&self) -> Result<Hertz, EspError> {
861 baudrate(self.port())
862 }
863
864 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 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 pub fn read(&self, buf: &mut [u8], timeout: TickType_t) -> Result<usize, EspError> {
921 self.rx().read(buf, timeout)
922 }
923
924 pub fn write(&self, bytes: &[u8]) -> Result<usize, EspError> {
926 self.tx().write(bytes)
927 }
928
929 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 pub fn write_nb(&self, bytes: &[u8]) -> Result<usize, EspError> {
944 self.tx().write_nb(bytes)
945 }
946
947 #[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 pub fn clear_rx(&self) -> Result<(), EspError> {
955 self.rx().clear()
956 }
957
958 #[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 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 pub fn remaining_read(&self) -> Result<usize, EspError> {
975 remaining_unread_bytes(self.port())
976 }
977
978 #[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 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 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 pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
1130 self.queue.as_ref()
1131 }
1132
1133 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 pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
1140 stop_bits(self.port())
1141 }
1142
1143 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 pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
1150 data_bits(self.port())
1151 }
1152
1153 pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
1155 change_parity(self.port(), parity).map(|_| self)
1156 }
1157
1158 pub fn parity(&self) -> Result<config::Parity, EspError> {
1160 parity(self.port())
1161 }
1162
1163 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 pub fn baudrate(&self) -> Result<Hertz, EspError> {
1176 baudrate(self.port())
1177 }
1178
1179 pub fn read(&self, buf: &mut [u8], delay: TickType_t) -> Result<usize, EspError> {
1185 if buf.is_empty() {
1199 return Ok(0);
1200 }
1201
1202 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 return match len {
1215 -1 | 0 => Err(EspError::from_infallible::<ESP_ERR_TIMEOUT>()),
1216 len => Ok(len as usize),
1217 };
1218 }
1219
1220 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 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 #[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 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 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 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 pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
1355 self.queue.as_ref()
1356 }
1357
1358 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 pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
1365 stop_bits(self.port())
1366 }
1367
1368 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 pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
1375 data_bits(self.port())
1376 }
1377
1378 pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
1380 change_parity(self.port(), parity).map(|_| self)
1381 }
1382
1383 pub fn parity(&self) -> Result<config::Parity, EspError> {
1385 parity(self.port())
1386 }
1387
1388 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 pub fn baudrate(&self) -> Result<Hertz, EspError> {
1401 baudrate(self.port())
1402 }
1403
1404 pub fn write(&mut self, bytes: &[u8]) -> Result<usize, EspError> {
1406 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 pub fn write_with_break(&mut self, bytes: &[u8], brk_len: i32) -> Result<usize, EspError> {
1418 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 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 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 #[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 #[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 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 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 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 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 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 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];