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)]
237 pub enum SourceClock {
238 #[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 #[cfg(esp_idf_soc_uart_support_rtc_clk)]
247 RTC,
248 #[cfg(esp_idf_soc_uart_support_xtal_clk)]
250 Crystal,
251 #[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 #[allow(non_camel_case_types)]
263 #[cfg(any(
264 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 all(esp_idf_version_at_least_6_0_0, any(esp32h2, esp32h4, esp32h21)),
274 ))]
275 PLL_F48M,
276 #[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 #[derive(Debug, Clone)]
452 pub struct EventConfig {
453 pub receive_timeout: Option<u8>,
459 pub rx_fifo_full: Option<u8>,
465 pub tx_fifo_empty: Option<u8>,
472 pub flags: EnumSet<EventFlags>,
474 #[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 #[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 pub intr_flags: EnumSet<InterruptType>,
581 pub event_config: EventConfig,
583 pub rx_fifo_size: usize,
585 pub tx_fifo_size: usize,
589 pub queue_size: usize,
592 #[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 #[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 #[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 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 Data {
778 size: usize,
780 timeout: bool,
785 },
786 Break,
788 RxBufferFull,
789 RxFifoOverflow,
790 FrameError,
791 ParityError,
792 DataBreak,
793 PatternDetected,
794 Unknown,
795}
796
797pub 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
807pub struct UartRxDriver<'d> {
809 port: u8,
810 owner: Owner,
811 queue: Option<Queue<UartEvent>>,
812 _p: PhantomData<&'d mut ()>,
813}
814
815pub 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 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 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 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 pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
865 self.queue.as_ref()
866 }
867
868 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 pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
875 stop_bits(self.port())
876 }
877
878 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 pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
885 data_bits(self.port())
886 }
887
888 pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
890 change_parity(self.port(), parity).map(|_| self)
891 }
892
893 pub fn parity(&self) -> Result<config::Parity, EspError> {
895 parity(self.port())
896 }
897
898 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 pub fn baudrate(&self) -> Result<Hertz, EspError> {
911 baudrate(self.port())
912 }
913
914 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 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 pub fn read(&self, buf: &mut [u8], timeout: TickType_t) -> Result<usize, EspError> {
971 self.rx().read(buf, timeout)
972 }
973
974 pub fn write(&self, bytes: &[u8]) -> Result<usize, EspError> {
976 self.tx().write(bytes)
977 }
978
979 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 pub fn write_nb(&self, bytes: &[u8]) -> Result<usize, EspError> {
994 self.tx().write_nb(bytes)
995 }
996
997 #[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 pub fn clear_rx(&self) -> Result<(), EspError> {
1005 self.rx().clear()
1006 }
1007
1008 #[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 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 pub fn remaining_read(&self) -> Result<usize, EspError> {
1025 remaining_unread_bytes(self.port())
1026 }
1027
1028 #[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 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 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 pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
1180 self.queue.as_ref()
1181 }
1182
1183 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 pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
1190 stop_bits(self.port())
1191 }
1192
1193 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 pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
1200 data_bits(self.port())
1201 }
1202
1203 pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
1205 change_parity(self.port(), parity).map(|_| self)
1206 }
1207
1208 pub fn parity(&self) -> Result<config::Parity, EspError> {
1210 parity(self.port())
1211 }
1212
1213 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 pub fn baudrate(&self) -> Result<Hertz, EspError> {
1226 baudrate(self.port())
1227 }
1228
1229 pub fn read(&self, buf: &mut [u8], delay: TickType_t) -> Result<usize, EspError> {
1235 if buf.is_empty() {
1249 return Ok(0);
1250 }
1251
1252 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 return match len {
1265 -1 | 0 => Err(EspError::from_infallible::<ESP_ERR_TIMEOUT>()),
1266 len => Ok(len as usize),
1267 };
1268 }
1269
1270 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 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 #[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 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 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 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 pub fn event_queue(&self) -> Option<&Queue<UartEvent>> {
1405 self.queue.as_ref()
1406 }
1407
1408 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 pub fn stop_bits(&self) -> Result<config::StopBits, EspError> {
1415 stop_bits(self.port())
1416 }
1417
1418 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 pub fn data_bits(&self) -> Result<config::DataBits, EspError> {
1425 data_bits(self.port())
1426 }
1427
1428 pub fn change_parity(&self, parity: config::Parity) -> Result<&Self, EspError> {
1430 change_parity(self.port(), parity).map(|_| self)
1431 }
1432
1433 pub fn parity(&self) -> Result<config::Parity, EspError> {
1435 parity(self.port())
1436 }
1437
1438 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 pub fn baudrate(&self) -> Result<Hertz, EspError> {
1451 baudrate(self.port())
1452 }
1453
1454 pub fn write(&mut self, bytes: &[u8]) -> Result<usize, EspError> {
1456 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 pub fn write_with_break(&mut self, bytes: &[u8], brk_len: i32) -> Result<usize, EspError> {
1468 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 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 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 #[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 #[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 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 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 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 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 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 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];