esp_hal/uart/mod.rs
1//! # Universal Asynchronous Receiver/Transmitter (UART)
2//!
3//! ## Overview
4//!
5//! The UART is a hardware peripheral which handles communication using serial
6//! communication interfaces, such as RS232 and RS485. This peripheral provides!
7//! a cheap and ubiquitous method for full- and half-duplex communication
8//! between devices.
9//!
10//! Depending on your device, two or more UART controllers are available for
11//! use, all of which can be configured and used in the same way. All UART
12//! controllers are compatible with UART-enabled devices from various
13//! manufacturers, and can also support Infrared Data Association (IrDA)
14//! protocols.
15//!
16//! ## Configuration
17//!
18//! Each UART controller is individually configurable, and the usual setting
19//! such as baud rate, data bits, parity, and stop bits can easily be
20//! configured. Additionally, the receive (RX) and transmit (TX) pins need to
21//! be specified.
22//!
23//! The UART controller can be configured to invert the polarity of the pins.
24//! This is achieved by inverting the desired pins, and then constructing the
25//! UART instance using the inverted pins.
26//!
27//! ## Usage
28//!
29//! The UART driver implements a number of third-party traits, with the
30//! intention of making the HAL inter-compatible with various device drivers
31//! from the community. This includes, but is not limited to, the [embedded-hal]
32//! and [embedded-io] blocking traits, and the [embedded-hal-async] and
33//! [embedded-io-async] asynchronous traits.
34//!
35//! In addition to the interfaces provided by these traits, native APIs are also
36//! available. See the examples below for more information on how to interact
37//! with this driver.
38//!
39//! [embedded-hal]: embedded_hal
40//! [embedded-io]: embedded_io_07
41//! [embedded-hal-async]: embedded_hal_async
42//! [embedded-io-async]: embedded_io_async_07
43
44crate::unstable_driver! {
45 #[cfg(uhci_driver_supported)]
46 pub mod uhci;
47
48 #[cfg(lp_uart_driver_supported)]
49 pub mod lp_uart;
50}
51
52#[cfg_attr(uart_version = "1", path = "clocks/v1.rs")]
53#[cfg_attr(soc_has_pcr, path = "clocks/v2_pcr.rs")]
54#[cfg_attr(esp32p4, path = "clocks/v2_esp32p4.rs")]
55#[cfg_attr(esp32s31, path = "clocks/v2_esp32s31.rs")]
56mod clocks;
57
58mod compat;
59mod low_level;
60
61use core::{marker::PhantomData, sync::atomic::Ordering};
62
63use embedded_hal_async::delay::DelayNs;
64use enumset::{EnumSet, EnumSetType};
65pub use low_level::Instance;
66use low_level::{
67 Info,
68 RxEvent,
69 State,
70 TxEvent,
71 UartClockGuard,
72 UartRxFuture,
73 UartTxFuture,
74 rx_event_check_for_error,
75 sync_regs,
76};
77
78use crate::{
79 Async,
80 Blocking,
81 DriverMode,
82 gpio::{
83 InputConfig,
84 OutputConfig,
85 PinGuard,
86 Pull,
87 interconnect::{PeripheralInput, PeripheralOutput},
88 },
89 interrupt::InterruptHandler,
90 pac::uart0::RegisterBlock,
91 private::DropGuard,
92 rtc_cntl::WakeLock,
93 system::PeripheralGuard,
94};
95
96crate::any_peripheral! {
97 /// Any UART peripheral.
98 pub peripheral AnyUart<'d> {
99 #[cfg(soc_has_uart0)]
100 Uart0(crate::peripherals::UART0<'d>),
101 #[cfg(soc_has_uart1)]
102 Uart1(crate::peripherals::UART1<'d>),
103 #[cfg(soc_has_uart2)]
104 Uart2(crate::peripherals::UART2<'d>),
105 #[cfg(soc_has_uart3)]
106 Uart3(crate::peripherals::UART3<'d>),
107 #[cfg(soc_has_uart4)]
108 Uart4(crate::peripherals::UART4<'d>),
109 }
110}
111
112impl Instance for AnyUart<'_> {
113 #[inline]
114 fn parts(&self) -> (&'static Info, &'static State) {
115 any::delegate!(self, uart => { uart.parts() })
116 }
117}
118
119impl AnyUart<'_> {
120 pub(super) fn bind_peri_interrupt(&self, handler: InterruptHandler) {
121 any::delegate!(self, uart => { uart.bind_peri_interrupt(handler) })
122 }
123
124 pub(super) fn disable_peri_interrupt_on_all_cores(&self) {
125 any::delegate!(self, uart => { uart.disable_peri_interrupt_on_all_cores() })
126 }
127
128 pub(super) fn set_interrupt_handler(&self, handler: InterruptHandler) {
129 self.disable_peri_interrupt_on_all_cores();
130
131 self.info().enable_listen(EnumSet::all(), false);
132 self.info().clear_interrupts(EnumSet::all());
133
134 self.bind_peri_interrupt(handler);
135 }
136}
137
138/// UART RX Error
139#[derive(Debug, Clone, Copy, PartialEq)]
140#[cfg_attr(feature = "defmt", derive(defmt::Format))]
141#[non_exhaustive]
142pub enum RxError {
143 /// An RX FIFO overflow happened.
144 ///
145 /// This error occurs when RX FIFO is full and a new byte is received. The
146 /// RX FIFO is then automatically reset by the driver.
147 FifoOverflowed,
148
149 /// A glitch was detected on the RX line.
150 ///
151 /// This error occurs when an unexpected or erroneous signal (glitch) is
152 /// detected on the UART RX line, which could lead to incorrect data
153 /// reception.
154 GlitchOccurred,
155
156 /// A framing error was detected on the RX line.
157 ///
158 /// This error occurs when the received data does not conform to the
159 /// expected UART frame format.
160 FrameFormatViolated,
161
162 /// A parity error was detected on the RX line.
163 ///
164 /// This error occurs when the parity bit in the received data does not
165 /// match the expected parity configuration.
166 ParityMismatch,
167}
168
169impl core::error::Error for RxError {}
170
171/// UART RX error conditions that can be reported by read operations.
172///
173/// This enum can be used with [`RxConfig::with_reported_errors`] to choose
174/// which hardware RX error conditions should make read operations return an
175/// [`RxError`].
176#[derive(Debug, EnumSetType)]
177#[cfg_attr(feature = "defmt", derive(defmt::Format))]
178#[instability::unstable]
179#[non_exhaustive]
180pub enum RxErrorKind {
181 /// An RX FIFO overflow happened.
182 FifoOverflowed,
183 /// A glitch was detected on the RX line.
184 GlitchOccurred,
185 /// A framing error was detected on the RX line.
186 FrameFormatViolated,
187 /// A parity error was detected on the RX line.
188 ParityMismatch,
189}
190
191impl From<RxErrorKind> for RxError {
192 fn from(value: RxErrorKind) -> Self {
193 match value {
194 RxErrorKind::FifoOverflowed => RxError::FifoOverflowed,
195 RxErrorKind::GlitchOccurred => RxError::GlitchOccurred,
196 RxErrorKind::FrameFormatViolated => RxError::FrameFormatViolated,
197 RxErrorKind::ParityMismatch => RxError::ParityMismatch,
198 }
199 }
200}
201
202impl core::fmt::Display for RxError {
203 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
204 match self {
205 RxError::FifoOverflowed => write!(f, "The RX FIFO overflowed"),
206 RxError::GlitchOccurred => write!(f, "A glitch was detected on the RX line"),
207 RxError::FrameFormatViolated => {
208 write!(f, "A framing error was detected on the RX line")
209 }
210 RxError::ParityMismatch => write!(f, "A parity error was detected on the RX line"),
211 }
212 }
213}
214
215/// UART TX Error
216#[derive(Debug, Clone, Copy, PartialEq)]
217#[cfg_attr(feature = "defmt", derive(defmt::Format))]
218#[non_exhaustive]
219pub enum TxError {}
220
221impl core::fmt::Display for TxError {
222 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
223 write!(f, "Tx error")
224 }
225}
226
227impl core::error::Error for TxError {}
228
229#[instability::unstable]
230pub use crate::soc::clocks::UartFunctionClockSclk as ClockSource;
231
232/// Number of data bits
233///
234/// This enum represents the various configurations for the number of data
235/// bits used in UART communication. The number of data bits defines the
236/// length of each transmitted or received data frame.
237#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
238#[cfg_attr(feature = "defmt", derive(defmt::Format))]
239pub enum DataBits {
240 /// 5 data bits per frame.
241 _5,
242 /// 6 data bits per frame.
243 _6,
244 /// 7 data bits per frame.
245 _7,
246 /// 8 data bits per frame.
247 #[default]
248 _8,
249}
250
251/// Parity check
252///
253/// Parity is a form of error detection in UART communication, used to
254/// ensure that the data has not been corrupted during transmission. The
255/// parity bit is added to the data bits to make the number of 1-bits
256/// either even or odd.
257#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
258#[cfg_attr(feature = "defmt", derive(defmt::Format))]
259pub enum Parity {
260 /// No parity bit is used.
261 #[default]
262 None,
263 /// Even parity: the parity bit is set to make the total number of
264 /// 1-bits even.
265 Even,
266 /// Odd parity: the parity bit is set to make the total number of 1-bits
267 /// odd.
268 Odd,
269}
270
271/// Number of stop bits
272///
273/// The stop bit(s) signal the end of a data packet in UART communication.
274/// This enum defines the possible configurations for the number of stop
275/// bits.
276#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
277#[cfg_attr(feature = "defmt", derive(defmt::Format))]
278pub enum StopBits {
279 /// 1 stop bit.
280 #[default]
281 _1,
282 /// 1.5 stop bits.
283 _1p5,
284 /// 2 stop bits.
285 _2,
286}
287
288/// Software flow control settings.
289#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
290#[cfg_attr(feature = "defmt", derive(defmt::Format))]
291#[instability::unstable]
292pub enum SwFlowControl {
293 #[default]
294 /// Disables software flow control.
295 Disabled,
296 /// Enables software flow control with configured parameters
297 Enabled {
298 /// Xon flow control byte.
299 xon_char: u8,
300 /// Xoff flow control byte.
301 xoff_char: u8,
302 /// If the software flow control is enabled and the data amount in
303 /// rxfifo is less than xon_thrd, an xon_char will be sent.
304 xon_threshold: u8,
305 /// If the software flow control is enabled and the data amount in
306 /// rxfifo is more than xoff_thrd, an xoff_char will be sent
307 xoff_threshold: u8,
308 },
309}
310
311/// Configuration for CTS (Clear To Send) flow control.
312#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
313#[cfg_attr(feature = "defmt", derive(defmt::Format))]
314#[instability::unstable]
315pub enum CtsConfig {
316 /// Enable CTS flow control (TX).
317 Enabled,
318 #[default]
319 /// Disable CTS flow control (TX).
320 Disabled,
321}
322
323/// Configuration for RTS (Request To Send) flow control.
324#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
325#[cfg_attr(feature = "defmt", derive(defmt::Format))]
326#[instability::unstable]
327pub enum RtsConfig {
328 /// Enable RTS flow control with a FIFO threshold (RX).
329 Enabled(u8),
330 #[default]
331 /// Disable RTS flow control.
332 Disabled,
333}
334
335/// Hardware flow control configuration.
336#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
337#[cfg_attr(feature = "defmt", derive(defmt::Format))]
338#[instability::unstable]
339pub struct HwFlowControl {
340 /// CTS configuration.
341 pub cts: CtsConfig,
342 /// RTS configuration.
343 pub rts: RtsConfig,
344}
345
346/// Defines how strictly the requested baud rate must be met.
347#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
348#[cfg_attr(feature = "defmt", derive(defmt::Format))]
349#[instability::unstable]
350pub enum BaudrateTolerance {
351 /// Accept the closest achievable baud rate without restriction.
352 #[default]
353 Closest,
354 /// In this setting, the deviation of only 1% from the desired baud value is
355 /// tolerated.
356 Exact,
357 /// Allow a certain percentage of deviation.
358 ErrorPercent(u8),
359}
360
361/// UART Configuration
362#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
363#[cfg_attr(feature = "defmt", derive(defmt::Format))]
364#[non_exhaustive]
365pub struct Config {
366 /// The baud rate (speed) of the UART communication in bits per second
367 /// (bps).
368 baudrate: u32,
369 /// Determines how close to the desired baud rate value the driver should
370 /// set the baud rate.
371 #[builder_lite(unstable)]
372 baudrate_tolerance: BaudrateTolerance,
373 /// Number of data bits in each frame (5, 6, 7, or 8 bits).
374 data_bits: DataBits,
375 /// Parity setting (None, Even, or Odd).
376 parity: Parity,
377 /// Number of stop bits in each frame (1, 1.5, or 2 bits).
378 stop_bits: StopBits,
379 /// Software flow control.
380 #[builder_lite(unstable)]
381 sw_flow_ctrl: SwFlowControl,
382 /// Hardware flow control.
383 #[builder_lite(unstable)]
384 hw_flow_ctrl: HwFlowControl,
385 /// Clock source used by the UART peripheral.
386 #[builder_lite(unstable)]
387 clock_source: ClockSource,
388 /// UART Receive part configuration.
389 rx: RxConfig,
390 /// UART Transmit part configuration.
391 tx: TxConfig,
392}
393
394impl Default for Config {
395 fn default() -> Config {
396 Config {
397 rx: RxConfig::default(),
398 tx: TxConfig::default(),
399 baudrate: 115_200,
400 baudrate_tolerance: BaudrateTolerance::default(),
401 data_bits: Default::default(),
402 parity: Default::default(),
403 stop_bits: Default::default(),
404 sw_flow_ctrl: Default::default(),
405 hw_flow_ctrl: Default::default(),
406 clock_source: Default::default(),
407 }
408 }
409}
410
411impl Config {
412 fn validate(&self) -> Result<(), ConfigError> {
413 if let BaudrateTolerance::ErrorPercent(percentage) = self.baudrate_tolerance {
414 assert!(percentage > 0 && percentage <= 100);
415 }
416
417 // Max supported baud rate is 5Mbaud
418 if self.baudrate == 0 || self.baudrate > 5_000_000 {
419 return Err(ConfigError::BaudrateNotSupported);
420 }
421 Ok(())
422 }
423}
424
425/// UART Receive part configuration.
426#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
427#[cfg_attr(feature = "defmt", derive(defmt::Format))]
428#[non_exhaustive]
429pub struct RxConfig {
430 /// Threshold level at which the RX FIFO is considered full.
431 fifo_full_threshold: u16,
432 /// Optional timeout value for RX operations.
433 timeout: Option<u8>,
434 /// RX error conditions that read operations should report.
435 ///
436 /// Error conditions not present in this set are cleared and ignored by
437 /// UART read operations.
438 #[builder_lite(unstable, into)]
439 reported_errors: EnumSet<RxErrorKind>,
440 /// Whether received bytes with UART errors are discarded by the hardware.
441 ///
442 /// When set to `true` (the default), bytes with UART errors (for example
443 /// parity or framing errors) are not stored in the RX FIFO. Set this to
444 /// `false` to keep those bytes in the RX FIFO. Use
445 /// [`Self::with_reported_errors`] to control whether those error
446 /// conditions make read operations fail.
447 #[builder_lite(unstable)]
448 discard_erroneous_bytes: bool,
449}
450
451impl Default for RxConfig {
452 fn default() -> RxConfig {
453 RxConfig {
454 // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L61>
455 fifo_full_threshold: 120,
456 // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L63>
457 timeout: Some(10),
458 reported_errors: EnumSet::all(),
459 discard_erroneous_bytes: true,
460 }
461 }
462}
463
464/// UART Transmit part configuration.
465#[derive(Debug, Clone, Copy, procmacros::BuilderLite)]
466#[cfg_attr(feature = "defmt", derive(defmt::Format))]
467#[non_exhaustive]
468pub struct TxConfig {
469 /// Threshold level at which the TX FIFO is considered empty.
470 fifo_empty_threshold: u16,
471}
472
473impl Default for TxConfig {
474 fn default() -> TxConfig {
475 TxConfig {
476 // see <https://github.com/espressif/esp-idf/blob/8760e6d2a/components/esp_driver_uart/src/uart.c#L59>
477 fifo_empty_threshold: 10,
478 }
479 }
480}
481
482/// Configuration for the AT-CMD detection functionality
483#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
484#[cfg_attr(feature = "defmt", derive(defmt::Format))]
485#[instability::unstable]
486#[non_exhaustive]
487pub struct AtCmdConfig {
488 /// Optional idle time before the AT command detection begins, in clock
489 /// cycles.
490 pre_idle_count: Option<u16>,
491 /// Optional idle time after the AT command detection ends, in clock
492 /// cycles.
493 post_idle_count: Option<u16>,
494 /// Optional timeout between bytes in the AT command, in clock
495 /// cycles.
496 gap_timeout: Option<u16>,
497 /// The byte (character) that triggers the AT command detection.
498 cmd_char: u8,
499 /// Optional number of bytes to detect as part of the AT command.
500 char_num: u8,
501}
502
503impl Default for AtCmdConfig {
504 fn default() -> Self {
505 Self {
506 pre_idle_count: None,
507 post_idle_count: None,
508 gap_timeout: None,
509 cmd_char: b'+',
510 char_num: 1,
511 }
512 }
513}
514
515/// The number of edges that the hardware counts before the threshold register starts.
516#[cfg(sleep_driver_supported)]
517const WAKEUP_EDGE_OFFSET: u16 = cfg_select! {
518 esp32 => 2,
519 esp32p4 => 6,
520 _ => 3,
521};
522
523/// The smallest number of rising edges that the hardware can wake on.
524#[cfg(sleep_driver_supported)]
525const MIN_WAKEUP_EDGES: u16 = cfg_select! {
526 // With a threshold of zero, esp32 wakes again and again.
527 esp32 => WAKEUP_EDGE_OFFSET + 1,
528 _ => WAKEUP_EDGE_OFFSET,
529};
530
531/// The largest number of rising edges that the hardware can count in its 10-bit field.
532#[cfg(sleep_driver_supported)]
533const MAX_WAKEUP_EDGES: u16 = WAKEUP_EDGE_OFFSET + 0x3FF;
534
535/// Configures how the UART wakes the chip from light sleep.
536///
537/// See [`UartRx::enable_wakeup`].
538#[cfg(sleep_driver_supported)]
539#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, procmacros::BuilderLite)]
540#[cfg_attr(feature = "defmt", derive(defmt::Format))]
541#[instability::unstable]
542#[non_exhaustive]
543pub struct WakeupConfig {
544 /// The number of rising edges on the RX line that wakes the chip.
545 ///
546 /// The hardware counts edges, and not bytes, so the number of bytes that the chip needs
547 /// depends on the data of the sender. Each byte gives one rising edge at its stop bit, and
548 /// one more edge for each change from 0 to 1 in the data. The number of edges is therefore
549 /// the smallest possible number of bytes. The default is the smallest value that the
550 /// hardware accepts.
551 ///
552 /// The permitted range on this chip is
553 #[cfg_attr(esp32, doc = "`3..=1025`.")]
554 #[cfg_attr(esp32p4, doc = "`6..=1029`.")]
555 #[cfg_attr(not(any(esp32, esp32p4)), doc = "`3..=1026`.")]
556 rising_edges: u16,
557}
558
559#[cfg(sleep_driver_supported)]
560impl Default for WakeupConfig {
561 fn default() -> Self {
562 Self {
563 rising_edges: MIN_WAKEUP_EDGES,
564 }
565 }
566}
567
568/// A wakeup configuration error.
569#[cfg(sleep_driver_supported)]
570#[derive(Debug, Clone, Copy, PartialEq, Eq)]
571#[cfg_attr(feature = "defmt", derive(defmt::Format))]
572#[instability::unstable]
573#[non_exhaustive]
574pub enum WakeConfigError {
575 /// This UART instance cannot wake the chip.
576 NotAWakeupSource,
577
578 /// The hardware cannot count the requested number of rising edges.
579 EdgeCountUnsupported,
580}
581
582#[cfg(sleep_driver_supported)]
583#[instability::unstable]
584impl core::error::Error for WakeConfigError {}
585
586#[cfg(sleep_driver_supported)]
587#[instability::unstable]
588impl core::fmt::Display for WakeConfigError {
589 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
590 match self {
591 WakeConfigError::NotAWakeupSource => {
592 write!(f, "This UART instance cannot wake the chip")
593 }
594 WakeConfigError::EdgeCountUnsupported => {
595 write!(
596 f,
597 "The requested number of rising edges is not supported, it must be {MIN_WAKEUP_EDGES}..={MAX_WAKEUP_EDGES}"
598 )
599 }
600 }
601 }
602}
603
604struct UartBuilder<'d, Dm: DriverMode> {
605 uart: AnyUart<'d>,
606 phantom: PhantomData<Dm>,
607}
608
609impl<'d, Dm> UartBuilder<'d, Dm>
610where
611 Dm: DriverMode,
612{
613 fn new(uart: impl Instance + 'd) -> Self {
614 let uart = uart.degrade();
615
616 // Make sure inputs are well-defined.
617 // Connect RX to an idle high level.
618 uart.info().rx_signal.connect_to(&crate::gpio::Level::High);
619 uart.info().cts_signal.connect_to(&crate::gpio::Level::Low);
620
621 Self {
622 uart,
623 phantom: PhantomData,
624 }
625 }
626
627 fn init(self, config: Config) -> Result<Uart<'d, Dm>, ConfigError> {
628 let rx_guard = PeripheralGuard::new(self.uart.info().peripheral);
629 let tx_guard = PeripheralGuard::new(self.uart.info().peripheral);
630
631 let peri_clock_guard = UartClockGuard::new(unsafe { self.uart.clone_unchecked() });
632
633 let rts_pin = PinGuard::new_unconnected();
634 let tx_pin = PinGuard::new_unconnected();
635
636 let mut serial = Uart {
637 rx: UartRx {
638 uart: unsafe { self.uart.clone_unchecked() },
639 phantom: PhantomData,
640 guard: rx_guard,
641 peri_clock_guard: peri_clock_guard.clone(),
642 // Receiving data continuously, the peripheral can't let the system sleep.
643 _wake_lock: WakeLock::new(),
644 reported_errors: config.rx.reported_errors,
645 },
646 tx: UartTx {
647 uart: self.uart,
648 phantom: PhantomData,
649 guard: tx_guard,
650 peri_clock_guard,
651 rts_pin,
652 tx_pin,
653 baudrate: config.baudrate,
654 },
655 };
656 serial.init(config)?;
657
658 Ok(serial)
659 }
660}
661
662#[procmacros::doc_replace]
663/// UART (Full-duplex)
664///
665/// ## Example
666///
667/// ```rust, no_run
668/// # {before_snippet}
669/// use esp_hal::uart::{Config, Uart};
670/// let mut uart = Uart::new(peripherals.UART0, Config::default())?
671/// .with_rx(peripherals.GPIO1)
672/// .with_tx(peripherals.GPIO2);
673///
674/// uart.write(b"Hello world!")?;
675/// # {after_snippet}
676/// ```
677pub struct Uart<'d, Dm: DriverMode> {
678 rx: UartRx<'d, Dm>,
679 tx: UartTx<'d, Dm>,
680}
681
682/// UART (Transmit)
683#[instability::unstable]
684pub struct UartTx<'d, Dm: DriverMode> {
685 uart: AnyUart<'d>,
686 phantom: PhantomData<Dm>,
687 guard: PeripheralGuard,
688 peri_clock_guard: UartClockGuard<'d>,
689 rts_pin: PinGuard,
690 tx_pin: PinGuard,
691 baudrate: u32,
692}
693
694/// UART (Receive)
695#[instability::unstable]
696pub struct UartRx<'d, Dm: DriverMode> {
697 uart: AnyUart<'d>,
698 phantom: PhantomData<Dm>,
699 guard: PeripheralGuard,
700 peri_clock_guard: UartClockGuard<'d>,
701 // Receiving data continuously, the peripheral can't let the system sleep.
702 _wake_lock: WakeLock,
703 reported_errors: EnumSet<RxErrorKind>,
704}
705
706/// A configuration error.
707#[derive(Debug, Clone, Copy, PartialEq, Eq)]
708#[cfg_attr(feature = "defmt", derive(defmt::Format))]
709#[non_exhaustive]
710pub enum ConfigError {
711 /// The requested baud rate is not achievable.
712 #[cfg(feature = "unstable")]
713 #[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
714 BaudrateNotAchievable,
715
716 /// The requested baud rate is not supported.
717 ///
718 /// This error is returned if:
719 /// * the baud rate exceeds 5MBaud or is equal to zero.
720 /// * the user has specified an exact baud rate or with some percentage of deviation to the
721 /// desired value, and the driver cannot reach this speed.
722 BaudrateNotSupported,
723
724 /// The requested timeout exceeds the maximum value (
725 #[cfg_attr(esp32, doc = "127")]
726 #[cfg_attr(not(esp32), doc = "1023")]
727 /// ).
728 TimeoutTooLong,
729
730 /// The requested RX FIFO threshold exceeds the maximum value (127 bytes).
731 RxFifoThresholdNotSupported,
732
733 /// The requested TX FIFO threshold exceeds the maximum value (127 bytes).
734 TxFifoThresholdNotSupported,
735}
736
737impl core::error::Error for ConfigError {}
738
739impl core::fmt::Display for ConfigError {
740 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
741 match self {
742 #[cfg(feature = "unstable")]
743 ConfigError::BaudrateNotAchievable => {
744 write!(f, "The requested baud rate is not achievable")
745 }
746 ConfigError::BaudrateNotSupported => {
747 write!(f, "The requested baud rate is not supported")
748 }
749 ConfigError::TimeoutTooLong => write!(f, "The requested timeout is not supported"),
750 ConfigError::RxFifoThresholdNotSupported => {
751 write!(f, "The requested RX FIFO threshold is not supported")
752 }
753 ConfigError::TxFifoThresholdNotSupported => {
754 write!(f, "The requested TX FIFO threshold is not supported")
755 }
756 }
757 }
758}
759
760impl<'d> UartTx<'d, Blocking> {
761 #[procmacros::doc_replace(
762 "note" => {
763 cfg(esp32) => "**esp32-specific ⚠️**: `UART2` is not recommended for use.",
764 _ => ""
765 }
766 )]
767 /// Create a new UART TX instance in [`Blocking`] mode.
768 ///
769 /// __note__
770 ///
771 /// ## Errors
772 ///
773 /// This function returns a [`ConfigError`] if the configuration is not
774 /// supported by the hardware.
775 ///
776 /// ## Example
777 ///
778 /// ```rust, no_run
779 /// # {before_snippet}
780 /// use esp_hal::uart::{Config, UartTx};
781 /// let tx = UartTx::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO1);
782 /// # {after_snippet}
783 /// ```
784 #[instability::unstable]
785 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
786 let (_, uart_tx) = UartBuilder::new(uart).init(config)?.split();
787
788 Ok(uart_tx)
789 }
790
791 /// Reconfigures the driver to operate in [`Async`] mode.
792 #[instability::unstable]
793 pub fn into_async(self) -> UartTx<'d, Async> {
794 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
795 self.uart
796 .set_interrupt_handler(self.uart.info().async_handler);
797 }
798 self.uart.state().is_tx_async.store(true, Ordering::Release);
799
800 UartTx {
801 uart: self.uart,
802 phantom: PhantomData,
803 guard: self.guard,
804 peri_clock_guard: self.peri_clock_guard,
805 rts_pin: self.rts_pin,
806 tx_pin: self.tx_pin,
807 baudrate: self.baudrate,
808 }
809 }
810}
811
812impl<'d> UartTx<'d, Async> {
813 /// Reconfigures the driver to operate in [`Blocking`] mode.
814 #[instability::unstable]
815 pub fn into_blocking(self) -> UartTx<'d, Blocking> {
816 self.uart
817 .state()
818 .is_tx_async
819 .store(false, Ordering::Release);
820 if !self.uart.state().is_rx_async.load(Ordering::Acquire) {
821 self.uart.disable_peri_interrupt_on_all_cores();
822 }
823
824 UartTx {
825 uart: self.uart,
826 phantom: PhantomData,
827 guard: self.guard,
828 peri_clock_guard: self.peri_clock_guard,
829 rts_pin: self.rts_pin,
830 tx_pin: self.tx_pin,
831 baudrate: self.baudrate,
832 }
833 }
834
835 /// Write data into the TX buffer.
836 ///
837 /// This function writes the provided buffer `bytes` into the UART transmit
838 /// buffer. If the buffer is full, the function waits asynchronously for
839 /// space in the buffer to become available.
840 ///
841 /// The function returns the number of bytes written into the buffer. This
842 /// may be less than the length of the buffer.
843 ///
844 /// Upon an error, the function returns immediately and the contents of the
845 /// internal FIFO are not modified.
846 ///
847 /// ## Cancellation
848 ///
849 /// This function is cancellation safe.
850 pub async fn write_async(&mut self, bytes: &[u8]) -> Result<usize, TxError> {
851 // We need to loop in case the TX empty interrupt was fired but not cleared
852 // before, but the FIFO itself was filled up by a previous write.
853 let space = loop {
854 let tx_fifo_count = self.uart.info().tx_fifo_count();
855 let space = Info::UART_FIFO_SIZE - tx_fifo_count;
856 if space != 0 {
857 break space;
858 }
859 UartTxFuture::new(self.uart.reborrow(), TxEvent::FiFoEmpty).await;
860 };
861
862 let free = (space as usize).min(bytes.len());
863
864 for &byte in &bytes[..free] {
865 self.uart
866 .info()
867 .regs()
868 .fifo()
869 .write(|w| unsafe { w.rxfifo_rd_byte().bits(byte) });
870 }
871
872 Ok(free)
873 }
874
875 /// Asynchronously flushes the UART transmit buffer.
876 ///
877 /// This function ensures that all pending data in the transmit FIFO has
878 /// been sent over the UART. If the FIFO contains data, it waits for the
879 /// transmission to complete before returning.
880 ///
881 /// ## Cancellation
882 ///
883 /// This function is cancellation safe.
884 pub async fn flush_async(&mut self) -> Result<(), TxError> {
885 // Nothing is guaranteed to clear the Done status, so let's loop here in case Tx
886 // was Done before the last write operation that pushed data into the
887 // FIFO.
888 while self.uart.info().tx_fifo_count() > 0 {
889 UartTxFuture::new(self.uart.reborrow(), TxEvent::Done).await;
890 }
891
892 self.flush_last_byte();
893
894 Ok(())
895 }
896
897 /// Sends a break signal for a specified duration in bit time.
898 ///
899 /// Duration is in bits, the time it takes to transfer one bit at the
900 /// current baud rate.
901 ///
902 /// This function restores the original TX line state after the break signal is sent, even if
903 /// the future is cancelled.
904 #[instability::unstable]
905 pub async fn send_break_async<D: DelayNs>(&mut self, delay: &mut D, bits: u32) {
906 // Calculate total delay in microseconds
907 let total_delay_us = (bits as u64 * 1_000_000) / self.baudrate as u64;
908 let delay_us = (total_delay_us as u32).max(1);
909
910 let break_guard = self.start_break();
911
912 delay.delay_us(delay_us).await;
913
914 core::mem::drop(break_guard);
915 }
916}
917
918impl<'d, Dm> UartTx<'d, Dm>
919where
920 Dm: DriverMode,
921{
922 /// Configure RTS pin
923 #[instability::unstable]
924 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
925 let rts = rts.into();
926
927 rts.apply_output_config(&OutputConfig::default());
928 rts.set_output_enable(true);
929
930 self.rts_pin = rts.connect_with_guard(self.uart.info().rts_signal);
931
932 self
933 }
934
935 /// Assign the TX pin for UART instance.
936 ///
937 /// Sets the specified pin to push-pull output and connects it to the UART
938 /// TX signal.
939 ///
940 /// Disconnects the previous pin that was assigned with `with_tx`.
941 #[instability::unstable]
942 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
943 let tx = tx.into();
944
945 // Make sure we don't cause an unexpected low pulse on the pin.
946 tx.set_output_high(true);
947 tx.apply_output_config(&OutputConfig::default());
948 tx.set_output_enable(true);
949
950 self.tx_pin = tx.connect_with_guard(self.uart.info().tx_signal);
951
952 self
953 }
954
955 /// Change the configuration.
956 ///
957 /// ## Errors
958 ///
959 /// This function returns a [`ConfigError`] if the configuration is not
960 /// supported by the hardware.
961 #[instability::unstable]
962 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
963 self.uart
964 .info()
965 .set_tx_fifo_empty_threshold(config.tx.fifo_empty_threshold)?;
966 self.uart.info().txfifo_reset();
967 Ok(())
968 }
969
970 /// Returns whether the UART buffer is ready to accept more data.
971 ///
972 /// If this function returns `true`, [`Self::write`] will not block.
973 #[instability::unstable]
974 pub fn write_ready(&self) -> bool {
975 self.uart.info().tx_fifo_count() < Info::UART_FIFO_SIZE
976 }
977
978 /// Write bytes.
979 ///
980 /// This function writes data to the internal TX FIFO of the UART
981 /// peripheral. The data is then transmitted over the UART TX line.
982 ///
983 /// The function returns the number of bytes written to the FIFO. This may
984 /// be less than the length of the provided data. The function may only
985 /// return 0 if the provided data is empty.
986 ///
987 /// ## Errors
988 ///
989 /// This function returns a [`TxError`] if an error occurred during the
990 /// write operation.
991 #[instability::unstable]
992 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
993 self.uart.info().write(data)
994 }
995
996 fn write_all(&mut self, mut data: &[u8]) -> Result<(), TxError> {
997 while !data.is_empty() {
998 let bytes_written = self.write(data)?;
999 data = &data[bytes_written..];
1000 }
1001 Ok(())
1002 }
1003
1004 /// Flush the transmit buffer.
1005 ///
1006 /// This function blocks until all data in the TX FIFO has been
1007 /// transmitted.
1008 #[instability::unstable]
1009 pub fn flush(&mut self) -> Result<(), TxError> {
1010 while self.uart.info().tx_fifo_count() > 0 {}
1011 self.flush_last_byte();
1012 Ok(())
1013 }
1014
1015 fn flush_last_byte(&mut self) {
1016 // This function handles an edge case that happens when the TX FIFO count
1017 // changes to 0. The FSM is in the Idle state for a short while after
1018 // the last byte is moved out of the FIFO. It is unclear how long this
1019 // takes, but 10us seems to be a good enough duration to wait, for both
1020 // fast and slow baud rates.
1021 crate::rom::ets_delay_us(10);
1022 while !self.is_tx_idle() {}
1023 }
1024
1025 /// Sends a break signal for a specified duration in bit time.
1026 ///
1027 /// Duration is in bits, the time it takes to transfer one bit at the
1028 /// current baud rate. The delay during the break is just busy-waiting.
1029 #[instability::unstable]
1030 pub fn send_break(&mut self, bits: u32) {
1031 // Calculate total delay in microseconds
1032 let total_delay_us = (bits as u64 * 1_000_000) / self.baudrate as u64;
1033 let delay_us = (total_delay_us as u32).max(1);
1034
1035 let break_guard = self.start_break();
1036
1037 crate::rom::ets_delay_us(delay_us);
1038
1039 core::mem::drop(break_guard);
1040 }
1041
1042 fn start_break(&mut self) -> impl Drop + '_ {
1043 // Read the current TX inversion state
1044 let original_conf0 = self.uart.info().regs().conf0().read();
1045 let original_txd_inv = original_conf0.txd_inv().bit();
1046
1047 // Invert the TX line (toggle the current state)
1048 self.uart
1049 .info()
1050 .regs()
1051 .conf0()
1052 .modify(|_, w| w.txd_inv().bit(!original_txd_inv));
1053
1054 sync_regs(self.uart.info().regs());
1055
1056 // Restore the original register state when dropped.
1057 DropGuard::new(self, move |this| {
1058 this.uart
1059 .info()
1060 .regs()
1061 .conf0()
1062 .write(|w| unsafe { w.bits(original_conf0.bits()) });
1063 sync_regs(this.uart.info().regs());
1064 })
1065 }
1066
1067 /// Checks if the TX line is idle for this UART instance.
1068 ///
1069 /// Returns `true` if the transmit line is idle, meaning no data is
1070 /// currently being transmitted.
1071 fn is_tx_idle(&self) -> bool {
1072 self.uart.info().is_tx_idle()
1073 }
1074
1075 /// Disables all TX-related interrupts for this UART instance.
1076 ///
1077 /// This function clears and disables the `transmit FIFO empty` interrupt,
1078 /// `transmit break done`, `transmit break idle done`, and `transmit done`
1079 /// interrupts.
1080 fn disable_tx_interrupts(&self) {
1081 self.regs().int_clr().write(|w| {
1082 w.txfifo_empty().clear_bit_by_one();
1083 w.tx_brk_done().clear_bit_by_one();
1084 w.tx_brk_idle_done().clear_bit_by_one();
1085 w.tx_done().clear_bit_by_one()
1086 });
1087
1088 self.regs().int_ena().write(|w| {
1089 w.txfifo_empty().clear_bit();
1090 w.tx_brk_done().clear_bit();
1091 w.tx_brk_idle_done().clear_bit();
1092 w.tx_done().clear_bit()
1093 });
1094 }
1095
1096 fn regs(&self) -> &RegisterBlock {
1097 self.uart.info().regs()
1098 }
1099}
1100
1101impl<'d> UartRx<'d, Blocking> {
1102 #[procmacros::doc_replace(
1103 "note" => {
1104 cfg(esp32) => "**esp32-specific ⚠️**: `UART2` is not recommended for use.",
1105 _ => ""
1106 }
1107 )]
1108 /// Create a new UART RX instance in [`Blocking`] mode.
1109 ///
1110 /// __note__
1111 ///
1112 /// ## Errors
1113 ///
1114 /// This function returns a [`ConfigError`] if the configuration is not
1115 /// supported by the hardware.
1116 ///
1117 /// ```rust, no_run
1118 /// # {before_snippet}
1119 /// use esp_hal::uart::{Config, UartRx};
1120 /// let rx = UartRx::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO2);
1121 /// # {after_snippet}
1122 /// ```
1123 #[instability::unstable]
1124 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1125 let (uart_rx, _) = UartBuilder::new(uart).init(config)?.split();
1126
1127 Ok(uart_rx)
1128 }
1129
1130 /// Waits for a break condition to be detected.
1131 ///
1132 /// This function polls the break-detection interrupt status and returns once
1133 /// the receiver has detected a break condition. After detection, the break
1134 /// status is automatically cleared.
1135 #[instability::unstable]
1136 pub fn wait_for_break(&mut self) {
1137 while !self.is_break_detected() {
1138 // wait
1139 }
1140
1141 self.clear_break_detected();
1142 }
1143
1144 /// Waits for a break condition to be detected with a timeout.
1145 ///
1146 /// This function polls the break-detection interrupt status until a break is
1147 /// detected or the specified timeout expires. Returns `true` if a break was
1148 /// detected, `false` if the timeout elapsed. After successful detection, the
1149 /// break status is automatically cleared.
1150 ///
1151 /// ## Arguments
1152 /// * `timeout` - Maximum time to wait for a break condition
1153 #[instability::unstable]
1154 pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1155 let start = crate::time::Instant::now();
1156
1157 while !self.is_break_detected() {
1158 if crate::time::Instant::now() - start >= timeout {
1159 return false;
1160 }
1161 }
1162
1163 self.clear_break_detected();
1164 true
1165 }
1166
1167 /// Reconfigures the driver to operate in [`Async`] mode.
1168 #[instability::unstable]
1169 pub fn into_async(self) -> UartRx<'d, Async> {
1170 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1171 self.uart
1172 .set_interrupt_handler(self.uart.info().async_handler);
1173 }
1174 self.uart.state().is_rx_async.store(true, Ordering::Release);
1175
1176 UartRx {
1177 uart: self.uart,
1178 phantom: PhantomData,
1179 guard: self.guard,
1180 peri_clock_guard: self.peri_clock_guard,
1181 _wake_lock: self._wake_lock,
1182 reported_errors: self.reported_errors,
1183 }
1184 }
1185}
1186
1187impl<'d> UartRx<'d, Async> {
1188 /// Reconfigures the driver to operate in [`Blocking`] mode.
1189 #[instability::unstable]
1190 pub fn into_blocking(self) -> UartRx<'d, Blocking> {
1191 self.uart
1192 .state()
1193 .is_rx_async
1194 .store(false, Ordering::Release);
1195 if !self.uart.state().is_tx_async.load(Ordering::Acquire) {
1196 self.uart.disable_peri_interrupt_on_all_cores();
1197 }
1198
1199 UartRx {
1200 uart: self.uart,
1201 phantom: PhantomData,
1202 guard: self.guard,
1203 peri_clock_guard: self.peri_clock_guard,
1204 _wake_lock: self._wake_lock,
1205 reported_errors: self.reported_errors,
1206 }
1207 }
1208
1209 async fn wait_for_buffered_data(
1210 &mut self,
1211 minimum: usize,
1212 max_threshold: usize,
1213 listen_for_timeout: bool,
1214 ) -> Result<(), RxError> {
1215 let current_threshold = self.uart.info().rx_fifo_full_threshold();
1216
1217 // User preference takes priority.
1218 let max_threshold = max_threshold.min(current_threshold as usize) as u16;
1219 let minimum = minimum.min(Info::RX_FIFO_MAX_THRHD as usize) as u16;
1220
1221 // The effective threshold must be >= minimum. We ensure this by lowering the minimum number
1222 // of returnable bytes.
1223 let minimum = minimum.min(max_threshold);
1224
1225 // loop to prevent returning 0 bytes
1226 while self.uart.info().rx_fifo_count() < minimum {
1227 // We're ignoring the user configuration here to ensure that this is not waiting
1228 // for more data than the buffer. We'll restore the original value after the
1229 // future resolved.
1230 let info = self.uart.info();
1231 unwrap!(info.set_rx_fifo_full_threshold(max_threshold));
1232 let _guard = DropGuard::new((), |_| {
1233 unwrap!(info.set_rx_fifo_full_threshold(current_threshold));
1234 });
1235
1236 // Wait for space or event
1237 let mut events = RxEvent::FifoFull
1238 | RxEvent::FifoOvf
1239 | RxEvent::FrameError
1240 | RxEvent::GlitchDetected
1241 | RxEvent::ParityError;
1242
1243 if self.regs().at_cmd_char().read().char_num().bits() > 0 {
1244 events |= RxEvent::CmdCharDetected;
1245 }
1246
1247 if listen_for_timeout && self.uart.info().rx_timeout_enabled() {
1248 events |= RxEvent::FifoTout;
1249 }
1250
1251 let events = UartRxFuture::new(self.uart.reborrow(), events).await;
1252
1253 if events.contains(RxEvent::FifoOvf) {
1254 self.uart.info().rxfifo_reset();
1255 }
1256 rx_event_check_for_error(events, self.reported_errors)?;
1257 }
1258
1259 Ok(())
1260 }
1261
1262 /// Read data asynchronously.
1263 ///
1264 /// This function reads data from the UART receive buffer into the
1265 /// provided buffer. If the buffer is empty, the function waits
1266 /// asynchronously for data to become available, or for an error to occur.
1267 ///
1268 /// The function returns the number of bytes read into the buffer. This may
1269 /// be less than the length of the buffer.
1270 ///
1271 /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1272 /// to ensure that it does not wait for more data than the buffer can hold.
1273 ///
1274 /// Upon an error, the function returns immediately and the contents of the
1275 /// internal FIFO are not modified.
1276 ///
1277 /// ## Cancellation
1278 ///
1279 /// This function is cancellation safe.
1280 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1281 if buf.is_empty() {
1282 return Ok(0);
1283 }
1284
1285 self.wait_for_buffered_data(1, buf.len(), true).await?;
1286
1287 self.read_buffered(buf)
1288 }
1289
1290 /// Fill buffer asynchronously.
1291 ///
1292 /// This function reads data into the provided buffer. If the internal FIFO
1293 /// does not contain enough data, the function waits asynchronously for data
1294 /// to become available, or for an error to occur.
1295 ///
1296 /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1297 /// to ensure that it does not wait for more data than the buffer can hold.
1298 ///
1299 /// ## Cancellation
1300 ///
1301 /// This function is **not** cancellation safe. If the future is dropped
1302 /// before it resolves, or if an error occurs during the read operation,
1303 /// previously read data may be lost.
1304 pub async fn read_exact_async(&mut self, mut buf: &mut [u8]) -> Result<(), RxError> {
1305 if buf.is_empty() {
1306 return Ok(());
1307 }
1308
1309 // Drain the buffer first, there's no point in waiting for data we've already received.
1310 let read = self.read_buffered(buf)?;
1311 buf = &mut buf[read..];
1312
1313 while !buf.is_empty() {
1314 // No point in listening for timeouts, as we're waiting for an exact amount of
1315 // data. On ESP32 and S2, the timeout interrupt can't be cleared unless the FIFO
1316 // is empty, so listening could cause an infinite loop here.
1317 self.wait_for_buffered_data(buf.len(), buf.len(), false)
1318 .await?;
1319
1320 let read = self.read_buffered(buf)?;
1321 buf = &mut buf[read..];
1322 }
1323
1324 Ok(())
1325 }
1326
1327 /// Waits for a break condition to be detected asynchronously.
1328 ///
1329 /// This is an async function that will await until a break condition is
1330 /// detected on the RX line. After detection, the break interrupt flag is
1331 /// automatically cleared.
1332 #[instability::unstable]
1333 pub async fn wait_for_break_async(&mut self) {
1334 UartRxFuture::new(self.uart.reborrow(), RxEvent::BreakDetected).await;
1335 }
1336}
1337
1338impl<'d, Dm> UartRx<'d, Dm>
1339where
1340 Dm: DriverMode,
1341{
1342 fn regs(&self) -> &RegisterBlock {
1343 self.uart.info().regs()
1344 }
1345
1346 /// Assign the CTS pin for UART instance.
1347 ///
1348 /// Sets the specified pin to input and connects it to the UART CTS signal.
1349 #[instability::unstable]
1350 pub fn with_cts(self, cts: impl PeripheralInput<'d>) -> Self {
1351 let cts = cts.into();
1352
1353 cts.apply_input_config(&InputConfig::default());
1354 cts.set_input_enable(true);
1355
1356 self.uart.info().cts_signal.connect_to(&cts);
1357
1358 self
1359 }
1360
1361 /// Assign the RX pin for UART instance.
1362 ///
1363 /// Sets the specified pin to input and connects it to the UART RX signal.
1364 ///
1365 /// Note: when you listen for the output of the UART peripheral, you should
1366 /// configure the driver side (i.e. the TX pin), or ensure that the line is
1367 /// initially high, to avoid receiving a non-data byte caused by an
1368 /// initial low signal level.
1369 #[instability::unstable]
1370 pub fn with_rx(self, rx: impl PeripheralInput<'d>) -> Self {
1371 let rx = rx.into();
1372
1373 rx.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
1374 rx.set_input_enable(true);
1375
1376 self.uart.info().rx_signal.connect_to(&rx);
1377
1378 self
1379 }
1380
1381 /// Returns whether a break condition has been detected.
1382 ///
1383 /// The returned status is sticky and remains set until
1384 /// [`Self::clear_break_detected`] is called, or until one of the
1385 /// `wait_for_break` methods observes and clears it.
1386 #[instability::unstable]
1387 pub fn is_break_detected(&self) -> bool {
1388 self.uart.info().check_rx_break_detected()
1389 }
1390
1391 /// Clears the break-detection status.
1392 #[instability::unstable]
1393 pub fn clear_break_detected(&mut self) {
1394 self.uart.info().clear_rx_break_detected();
1395 }
1396
1397 /// Change the configuration.
1398 ///
1399 /// ## Errors
1400 ///
1401 /// This function returns a [`ConfigError`] if the configuration is not
1402 /// supported by the hardware.
1403 #[instability::unstable]
1404 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
1405 self.uart
1406 .info()
1407 .set_rx_fifo_full_threshold(config.rx.fifo_full_threshold)?;
1408 self.uart
1409 .info()
1410 .set_rx_timeout(config.rx.timeout, self.uart.info().current_symbol_length())?;
1411 self.uart
1412 .info()
1413 .set_discard_erroneous_bytes(config.rx.discard_erroneous_bytes);
1414 self.reported_errors = config.rx.reported_errors;
1415
1416 self.uart.info().rxfifo_reset();
1417 Ok(())
1418 }
1419
1420 /// Lets activity on the RX line wake the chip from light sleep.
1421 ///
1422 /// The chip wakes when it counts the number of rising edges that
1423 /// [`WakeupConfig::with_rising_edges`] gives. Deep sleep powers the UART down, so this source
1424 /// ends a light sleep only.
1425 ///
1426 /// The chip loses the bytes that cause the wake. It also loses the bytes that arrive during the
1427 /// wake, and at a typical baud rate that wake is long enough to lose several bytes. A sender
1428 /// must therefore first send data that the receiver can lose, and then send the data again.
1429 /// The first data after the wake also clears the internal wakeup indication. Without that
1430 /// write, the next wake occurs two edges early.
1431 ///
1432 /// The peripheral counts the edges itself, so a light sleep keeps the high-performance
1433 /// peripherals powered instead of powering them down. This increases the sleep current.
1434 ///
1435 /// The configuration stays after the driver is dropped, so that the UART continues to wake the
1436 /// chip while no driver owns it. Call [`Self::disable_wakeup`] to remove it.
1437 ///
1438 /// # Errors
1439 ///
1440 /// Returns [`WakeConfigError::NotAWakeupSource`] if this UART instance cannot wake the chip,
1441 /// and [`WakeConfigError::EdgeCountUnsupported`] if the hardware cannot count the requested
1442 /// number of edges.
1443 #[cfg(sleep_driver_supported)]
1444 #[instability::unstable]
1445 pub fn enable_wakeup(&mut self, config: &WakeupConfig) -> Result<(), WakeConfigError> {
1446 self.uart.info().enable_wakeup(config)
1447 }
1448
1449 /// Stops the UART from waking the chip.
1450 #[cfg(sleep_driver_supported)]
1451 #[instability::unstable]
1452 pub fn disable_wakeup(&mut self) {
1453 self.uart.info().disable_wakeup();
1454 }
1455
1456 /// Reads and clears RX error conditions set by received data.
1457 ///
1458 /// Only errors enabled in [`RxConfig::with_reported_errors`] are returned;
1459 /// disabled errors are cleared and ignored.
1460 ///
1461 /// If a FIFO overflow is detected, the RX FIFO is reset.
1462 #[instability::unstable]
1463 pub fn check_for_errors(&mut self) -> Result<(), RxError> {
1464 self.uart.info().check_for_errors(self.reported_errors)
1465 }
1466
1467 /// Returns whether the UART buffer has data.
1468 ///
1469 /// If this function returns `true`, [`Self::read`] will not block.
1470 #[instability::unstable]
1471 pub fn read_ready(&self) -> bool {
1472 self.uart.info().rx_fifo_count() > 0
1473 }
1474
1475 /// Read bytes.
1476 ///
1477 /// The UART hardware continuously receives bytes and stores them in the RX
1478 /// FIFO. This function reads the bytes from the RX FIFO and returns
1479 /// them in the provided buffer. If the hardware buffer is empty, this
1480 /// function will block until data is available. The [`Self::read_ready`]
1481 /// function can be used to check if data is available without blocking.
1482 ///
1483 /// The function returns the number of bytes read into the buffer. This may
1484 /// be less than the length of the buffer. This function only returns 0
1485 /// if the provided buffer is empty.
1486 ///
1487 /// ## Errors
1488 ///
1489 /// This function returns an [`RxError`] if a reported error occurred since
1490 /// the last call to [`Self::check_for_errors`], [`Self::read_buffered`], or
1491 /// this function.
1492 ///
1493 /// If the error occurred before this function was called, the contents of
1494 /// the FIFO are not modified.
1495 #[instability::unstable]
1496 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1497 self.uart.info().read(buf, self.reported_errors)
1498 }
1499
1500 /// Read already received bytes.
1501 ///
1502 /// This function reads the already received bytes from the FIFO into the
1503 /// provided buffer. The function does not wait for the FIFO to actually
1504 /// contain any bytes.
1505 ///
1506 /// The function returns the number of bytes read into the buffer. This may
1507 /// be less than the length of the buffer, and it may also be 0.
1508 ///
1509 /// ## Errors
1510 ///
1511 /// This function returns an [`RxError`] if a reported error occurred since
1512 /// the last call to [`Self::check_for_errors`], [`Self::read`], or this
1513 /// function.
1514 ///
1515 /// If the error occurred before this function was called, the contents of
1516 /// the FIFO are not modified.
1517 #[instability::unstable]
1518 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1519 self.uart.info().read_buffered(buf, self.reported_errors)
1520 }
1521
1522 /// Disables all RX-related interrupts for this UART instance.
1523 ///
1524 /// This function clears and disables the `receive FIFO full` interrupt,
1525 /// `receive FIFO overflow`, `receive FIFO timeout`, and `AT command
1526 /// byte detection` interrupts.
1527 fn disable_rx_interrupts(&self) {
1528 self.regs().int_clr().write(|w| {
1529 w.rxfifo_full().clear_bit_by_one();
1530 w.rxfifo_ovf().clear_bit_by_one();
1531 w.rxfifo_tout().clear_bit_by_one();
1532 w.at_cmd_char_det().clear_bit_by_one()
1533 });
1534
1535 self.regs().int_ena().write(|w| {
1536 w.rxfifo_full().clear_bit();
1537 w.rxfifo_ovf().clear_bit();
1538 w.rxfifo_tout().clear_bit();
1539 w.at_cmd_char_det().clear_bit()
1540 });
1541 }
1542}
1543
1544impl<'d> Uart<'d, Blocking> {
1545 #[procmacros::doc_replace(
1546 "note" => {
1547 cfg(esp32) => "**esp32-specific ⚠️**: `UART2` is not recommended for use.",
1548 _ => ""
1549 }
1550 )]
1551 /// Create a new UART instance in [`Blocking`] mode.
1552 ///
1553 /// __note__
1554 ///
1555 /// ## Errors
1556 ///
1557 /// This function returns a [`ConfigError`] if the configuration is not
1558 /// supported by the hardware.
1559 ///
1560 /// ## Example
1561 ///
1562 /// ```rust, no_run
1563 /// # {before_snippet}
1564 /// use esp_hal::uart::{Config, Uart};
1565 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1566 /// .with_rx(peripherals.GPIO1)
1567 /// .with_tx(peripherals.GPIO2);
1568 /// # {after_snippet}
1569 /// ```
1570 pub fn new(uart: impl Instance + 'd, config: Config) -> Result<Self, ConfigError> {
1571 UartBuilder::new(uart).init(config)
1572 }
1573
1574 /// Reconfigures the driver to operate in [`Async`] mode.
1575 ///
1576 /// See the [`Async`] documentation for an example on how to use this
1577 /// method.
1578 pub fn into_async(self) -> Uart<'d, Async> {
1579 Uart {
1580 rx: self.rx.into_async(),
1581 tx: self.tx.into_async(),
1582 }
1583 }
1584
1585 #[cfg_attr(
1586 not(multi_core),
1587 doc = "Registers an interrupt handler for the peripheral."
1588 )]
1589 #[cfg_attr(
1590 multi_core,
1591 doc = "Registers an interrupt handler for the peripheral on the current core."
1592 )]
1593 #[doc = ""]
1594 /// Note that this will replace any previously registered interrupt
1595 /// handlers.
1596 ///
1597 /// You can restore the default/unhandled interrupt handler by using
1598 /// [crate::interrupt::DEFAULT_INTERRUPT_HANDLER]
1599 #[instability::unstable]
1600 pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
1601 // `self.tx.uart` and `self.rx.uart` are the same
1602 self.tx.uart.set_interrupt_handler(handler);
1603 }
1604
1605 #[procmacros::doc_replace]
1606 /// Listen for the given interrupts
1607 ///
1608 /// ## Example
1609 ///
1610 /// **Note**: In practice a proper serial terminal should be used
1611 /// to connect to the board (espflash won't work)
1612 ///
1613 /// ```rust, no_run
1614 /// # {before_snippet}
1615 /// use esp_hal::{
1616 /// delay::Delay,
1617 /// uart::{AtCmdConfig, Config, RxConfig, Uart, UartInterrupt},
1618 /// };
1619 /// # let delay = Delay::new();
1620 /// # let config = Config::default().with_rx(
1621 /// # RxConfig::default().with_fifo_full_threshold(30)
1622 /// # );
1623 /// # let mut uart = Uart::new(
1624 /// # peripherals.UART0,
1625 /// # config)?;
1626 /// uart.set_interrupt_handler(interrupt_handler);
1627 ///
1628 /// critical_section::with(|cs| {
1629 /// uart.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#'));
1630 /// uart.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1631 ///
1632 /// SERIAL.borrow_ref_mut(cs).replace(uart);
1633 /// });
1634 ///
1635 /// loop {
1636 /// println!("Send `#` character or >=30 characters");
1637 /// delay.delay(Duration::from_secs(1));
1638 /// }
1639 /// # }
1640 ///
1641 /// use core::cell::RefCell;
1642 ///
1643 /// use critical_section::Mutex;
1644 /// use esp_hal::uart::Uart;
1645 /// static SERIAL: Mutex<RefCell<Option<Uart<esp_hal::Blocking>>>> = Mutex::new(RefCell::new(None));
1646 ///
1647 /// use core::fmt::Write;
1648 ///
1649 /// use esp_hal::uart::UartInterrupt;
1650 /// #[esp_hal::handler]
1651 /// fn interrupt_handler() {
1652 /// critical_section::with(|cs| {
1653 /// let mut serial = SERIAL.borrow_ref_mut(cs);
1654 /// if let Some(serial) = serial.as_mut() {
1655 /// let mut buf = [0u8; 64];
1656 /// if let Ok(cnt) = serial.read_buffered(&mut buf) {
1657 /// println!("Read {} bytes", cnt);
1658 /// }
1659 ///
1660 /// let pending_interrupts = serial.interrupts();
1661 /// println!(
1662 /// "Interrupt AT-CMD: {} RX-FIFO-FULL: {}",
1663 /// pending_interrupts.contains(UartInterrupt::AtCmd),
1664 /// pending_interrupts.contains(UartInterrupt::RxFifoFull),
1665 /// );
1666 ///
1667 /// serial.clear_interrupts(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull);
1668 /// }
1669 /// });
1670 /// }
1671 /// ```
1672 #[instability::unstable]
1673 pub fn listen(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1674 self.tx.uart.info().enable_listen(interrupts.into(), true)
1675 }
1676
1677 /// Unlisten the given interrupts
1678 #[instability::unstable]
1679 pub fn unlisten(&mut self, interrupts: impl Into<EnumSet<UartInterrupt>>) {
1680 self.tx.uart.info().enable_listen(interrupts.into(), false)
1681 }
1682
1683 /// Gets asserted interrupts
1684 #[instability::unstable]
1685 pub fn interrupts(&mut self) -> EnumSet<UartInterrupt> {
1686 self.tx.uart.info().interrupts()
1687 }
1688
1689 /// Resets asserted interrupts
1690 #[instability::unstable]
1691 pub fn clear_interrupts(&mut self, interrupts: EnumSet<UartInterrupt>) {
1692 self.tx.uart.info().clear_interrupts(interrupts)
1693 }
1694
1695 /// Waits for a break condition to be detected.
1696 ///
1697 /// This is a blocking function that will continuously check for a break condition.
1698 /// After detection, the break interrupt flag is automatically cleared.
1699 #[instability::unstable]
1700 pub fn wait_for_break(&mut self) {
1701 self.rx.wait_for_break()
1702 }
1703
1704 /// Waits for a break condition to be detected with a timeout.
1705 ///
1706 /// This is a blocking function that will check for a break condition up to
1707 /// the specified timeout. Returns `true` if a break was detected, `false` if
1708 /// the timeout elapsed. After successful detection, the break interrupt flag
1709 /// is automatically cleared.
1710 ///
1711 /// ## Arguments
1712 /// * `timeout` - Maximum time to wait for a break condition
1713 #[instability::unstable]
1714 pub fn wait_for_break_with_timeout(&mut self, timeout: crate::time::Duration) -> bool {
1715 self.rx.wait_for_break_with_timeout(timeout)
1716 }
1717}
1718
1719impl<'d> Uart<'d, Async> {
1720 /// Reconfigures the driver to operate in [`Blocking`] mode.
1721 ///
1722 /// See the [`Blocking`] documentation for an example on how to use this
1723 /// method.
1724 pub fn into_blocking(self) -> Uart<'d, Blocking> {
1725 Uart {
1726 rx: self.rx.into_blocking(),
1727 tx: self.tx.into_blocking(),
1728 }
1729 }
1730
1731 #[procmacros::doc_replace]
1732 /// Write data into the TX buffer.
1733 ///
1734 /// This function writes the provided buffer `bytes` into the UART transmit
1735 /// buffer. If the buffer is full, the function waits asynchronously for
1736 /// space in the buffer to become available.
1737 ///
1738 /// The function returns the number of bytes written into the buffer. This
1739 /// may be less than the length of the buffer.
1740 ///
1741 /// Upon an error, the function returns immediately and the contents of the
1742 /// internal FIFO are not modified.
1743 ///
1744 /// ## Cancellation
1745 ///
1746 /// This function is cancellation safe.
1747 ///
1748 /// ## Example
1749 ///
1750 /// ```rust, no_run
1751 /// # {before_snippet}
1752 /// use esp_hal::uart::{Config, Uart};
1753 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1754 /// .with_rx(peripherals.GPIO1)
1755 /// .with_tx(peripherals.GPIO2)
1756 /// .into_async();
1757 ///
1758 /// const MESSAGE: &[u8] = b"Hello, world!";
1759 /// uart.write_async(&MESSAGE).await?;
1760 /// # {after_snippet}
1761 /// ```
1762 pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, TxError> {
1763 self.tx.write_async(words).await
1764 }
1765
1766 #[procmacros::doc_replace]
1767 /// Asynchronously flushes the UART transmit buffer.
1768 ///
1769 /// This function ensures that all pending data in the transmit FIFO has
1770 /// been sent over the UART. If the FIFO contains data, it waits for the
1771 /// transmission to complete before returning.
1772 ///
1773 /// ## Cancellation
1774 ///
1775 /// This function is cancellation safe.
1776 ///
1777 /// ## Example
1778 ///
1779 /// ```rust, no_run
1780 /// # {before_snippet}
1781 /// use esp_hal::uart::{Config, Uart};
1782 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1783 /// .with_rx(peripherals.GPIO1)
1784 /// .with_tx(peripherals.GPIO2)
1785 /// .into_async();
1786 ///
1787 /// const MESSAGE: &[u8] = b"Hello, world!";
1788 /// uart.write_async(&MESSAGE).await?;
1789 /// uart.flush_async().await?;
1790 /// # {after_snippet}
1791 /// ```
1792 pub async fn flush_async(&mut self) -> Result<(), TxError> {
1793 self.tx.flush_async().await
1794 }
1795
1796 #[procmacros::doc_replace]
1797 /// Read data asynchronously.
1798 ///
1799 /// This function reads data from the UART receive buffer into the
1800 /// provided buffer. If the buffer is empty, the function waits
1801 /// asynchronously for data to become available, or for an error to occur.
1802 ///
1803 /// The function returns the number of bytes read into the buffer. This may
1804 /// be less than the length of the buffer.
1805 ///
1806 /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1807 /// to ensure that it does not wait for more data than the buffer can hold.
1808 ///
1809 /// Upon an error, the function returns immediately and the contents of the
1810 /// internal FIFO are not modified.
1811 ///
1812 /// ## Cancellation
1813 ///
1814 /// This function is cancellation safe.
1815 ///
1816 /// ## Example
1817 ///
1818 /// ```rust, no_run
1819 /// # {before_snippet}
1820 /// use esp_hal::uart::{Config, Uart};
1821 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
1822 /// .with_rx(peripherals.GPIO1)
1823 /// .with_tx(peripherals.GPIO2)
1824 /// .into_async();
1825 ///
1826 /// const MESSAGE: &[u8] = b"Hello, world!";
1827 /// uart.write_async(&MESSAGE).await?;
1828 /// uart.flush_async().await?;
1829 ///
1830 /// let mut buf = [0u8; MESSAGE.len()];
1831 /// uart.read_async(&mut buf[..]).await?;
1832 /// # {after_snippet}
1833 /// ```
1834 pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
1835 self.rx.read_async(buf).await
1836 }
1837
1838 /// Fill buffer asynchronously.
1839 ///
1840 /// This function reads data from the UART receive buffer into the
1841 /// provided buffer. If the buffer is empty, the function waits
1842 /// asynchronously for data to become available, or for an error to occur.
1843 ///
1844 /// Note that this function may ignore the `rx_fifo_full_threshold` setting
1845 /// to ensure that it does not wait for more data than the buffer can hold.
1846 ///
1847 /// ## Cancellation
1848 ///
1849 /// This function is **not** cancellation safe. If the future is dropped
1850 /// before it resolves, or if an error occurs during the read operation,
1851 /// previously read data may be lost.
1852 #[instability::unstable]
1853 pub async fn read_exact_async(&mut self, buf: &mut [u8]) -> Result<(), RxError> {
1854 self.rx.read_exact_async(buf).await
1855 }
1856
1857 /// Waits for a break condition to be detected asynchronously.
1858 ///
1859 /// This is an async function that will await until a break condition is
1860 /// detected on the RX line. After detection, the break interrupt flag is
1861 /// automatically cleared.
1862 #[instability::unstable]
1863 pub async fn wait_for_break_async(&mut self) {
1864 self.rx.wait_for_break_async().await
1865 }
1866
1867 /// Sends a break signal for a specified duration in bit time.
1868 ///
1869 /// Duration is in bits, the time it takes to transfer one bit at the
1870 /// current baud rate.
1871 ///
1872 /// This function restores the original TX line state after the break signal is sent, even if
1873 /// the future is cancelled.
1874 #[instability::unstable]
1875 pub async fn send_break_async<D: DelayNs>(&mut self, delay: &mut D, bits: u32) {
1876 self.tx.send_break_async(delay, bits).await
1877 }
1878}
1879
1880/// List of exposed UART events.
1881#[derive(Debug, EnumSetType)]
1882#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1883#[non_exhaustive]
1884#[instability::unstable]
1885pub enum UartInterrupt {
1886 /// Indicates that the receiver has detected the configured
1887 /// [`Uart::set_at_cmd`] byte.
1888 AtCmd,
1889
1890 /// The transmitter has finished sending out all data from the FIFO.
1891 TxDone,
1892
1893 /// Break condition has been detected.
1894 /// Triggered when the receiver detects a NULL character (i.e. logic 0 for
1895 /// one NULL character transmission) after stop bits.
1896 RxBreakDetected,
1897
1898 /// The receiver has received more data than what
1899 /// [`RxConfig::fifo_full_threshold`] specifies.
1900 RxFifoFull,
1901
1902 /// The receiver has not received any data for the time
1903 /// [`RxConfig::with_timeout`] specifies.
1904 RxTimeout,
1905}
1906
1907impl<'d, Dm> Uart<'d, Dm>
1908where
1909 Dm: DriverMode,
1910{
1911 #[procmacros::doc_replace]
1912 /// Assign the RX pin for UART instance.
1913 ///
1914 /// Sets the specified pin to input and connects it to the UART RX signal.
1915 ///
1916 /// Note: when you listen for the output of the UART peripheral, you should
1917 /// configure the driver side (i.e. the TX pin), or ensure that the line is
1918 /// initially high, to avoid receiving a non-data byte caused by an
1919 /// initial low signal level.
1920 ///
1921 /// ## Example
1922 ///
1923 /// ```rust, no_run
1924 /// # {before_snippet}
1925 /// use esp_hal::uart::{Config, Uart};
1926 /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_rx(peripherals.GPIO1);
1927 ///
1928 /// # {after_snippet}
1929 /// ```
1930 pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self {
1931 self.rx = self.rx.with_rx(rx);
1932 self
1933 }
1934
1935 #[procmacros::doc_replace]
1936 /// Assign the TX pin for UART instance.
1937 ///
1938 /// Sets the specified pin to push-pull output and connects it to the UART
1939 /// TX signal.
1940 ///
1941 /// ## Example
1942 ///
1943 /// ```rust, no_run
1944 /// # {before_snippet}
1945 /// use esp_hal::uart::{Config, Uart};
1946 /// let uart = Uart::new(peripherals.UART0, Config::default())?.with_tx(peripherals.GPIO2);
1947 ///
1948 /// # {after_snippet}
1949 /// ```
1950 pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self {
1951 self.tx = self.tx.with_tx(tx);
1952 self
1953 }
1954
1955 #[procmacros::doc_replace]
1956 /// Configure CTS pin
1957 ///
1958 /// ## Example
1959 ///
1960 /// ```rust, no_run
1961 /// # {before_snippet}
1962 /// use esp_hal::uart::{Config, Uart};
1963 /// let uart = Uart::new(peripherals.UART0, Config::default())?
1964 /// .with_rx(peripherals.GPIO1)
1965 /// .with_cts(peripherals.GPIO3);
1966 ///
1967 /// # {after_snippet}
1968 /// ```
1969 pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self {
1970 self.rx = self.rx.with_cts(cts);
1971 self
1972 }
1973
1974 #[procmacros::doc_replace]
1975 /// Configure RTS pin
1976 ///
1977 /// ## Example
1978 ///
1979 /// ```rust, no_run
1980 /// # {before_snippet}
1981 /// use esp_hal::uart::{Config, Uart};
1982 /// let uart = Uart::new(peripherals.UART0, Config::default())?
1983 /// .with_tx(peripherals.GPIO2)
1984 /// .with_rts(peripherals.GPIO3);
1985 ///
1986 /// # {after_snippet}
1987 /// ```
1988 pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self {
1989 self.tx = self.tx.with_rts(rts);
1990 self
1991 }
1992
1993 fn regs(&self) -> &RegisterBlock {
1994 // `self.tx.uart` and `self.rx.uart` are the same
1995 self.tx.uart.info().regs()
1996 }
1997
1998 #[procmacros::doc_replace]
1999 /// Returns whether the UART TX buffer is ready to accept more data.
2000 ///
2001 /// If this function returns `true`, [`Self::write`] and [`Self::write_async`]
2002 /// will not block. Otherwise, the functions will not return until the buffer is
2003 /// ready.
2004 ///
2005 /// ## Example
2006 ///
2007 /// ```rust, no_run
2008 /// # {before_snippet}
2009 /// use esp_hal::uart::{Config, Uart};
2010 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2011 ///
2012 /// if uart.write_ready() {
2013 /// // Because write_ready has returned true, the following call will immediately
2014 /// // copy some bytes into the FIFO and return a non-zero value.
2015 /// let written = uart.write(b"Hello")?;
2016 /// // ... handle written bytes
2017 /// } else {
2018 /// // Calling write would have blocked, but here we can do something useful
2019 /// // instead of waiting for the buffer to become ready.
2020 /// }
2021 /// # {after_snippet}
2022 /// ```
2023 pub fn write_ready(&self) -> bool {
2024 self.tx.write_ready()
2025 }
2026
2027 #[procmacros::doc_replace]
2028 /// Writes bytes.
2029 ///
2030 /// This function writes data to the internal TX FIFO of the UART
2031 /// peripheral. The data is then transmitted over the UART TX line.
2032 ///
2033 /// The function returns the number of bytes written to the FIFO. This may
2034 /// be less than the length of the provided data. The function may only
2035 /// return 0 if the provided data is empty.
2036 ///
2037 /// ## Errors
2038 ///
2039 /// This function returns a [`TxError`] if an error occurred during the
2040 /// write operation.
2041 ///
2042 /// ## Example
2043 ///
2044 /// ```rust, no_run
2045 /// # {before_snippet}
2046 /// use esp_hal::uart::{Config, Uart};
2047 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2048 ///
2049 /// const MESSAGE: &[u8] = b"Hello, world!";
2050 /// uart.write(&MESSAGE)?;
2051 /// # {after_snippet}
2052 /// ```
2053 pub fn write(&mut self, data: &[u8]) -> Result<usize, TxError> {
2054 self.tx.write(data)
2055 }
2056
2057 #[procmacros::doc_replace]
2058 /// Flush the transmit buffer of the UART
2059 ///
2060 /// ## Example
2061 ///
2062 /// ```rust, no_run
2063 /// # {before_snippet}
2064 /// use esp_hal::uart::{Config, Uart};
2065 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2066 ///
2067 /// const MESSAGE: &[u8] = b"Hello, world!";
2068 /// uart.write(&MESSAGE)?;
2069 /// uart.flush()?;
2070 /// # {after_snippet}
2071 /// ```
2072 pub fn flush(&mut self) -> Result<(), TxError> {
2073 self.tx.flush()
2074 }
2075
2076 /// Sends a break signal for a specified duration
2077 #[instability::unstable]
2078 pub fn send_break(&mut self, bits: u32) {
2079 self.tx.send_break(bits)
2080 }
2081
2082 #[procmacros::doc_replace]
2083 /// Returns whether the UART receive buffer has at least one byte of data.
2084 ///
2085 /// If this function returns `true`, [`Self::read`] and [`Self::read_async`]
2086 /// will not block. Otherwise, they will not return until data is available.
2087 ///
2088 /// Data that does not get stored due to an error will be lost and does not count
2089 /// towards the number of bytes in the receive buffer.
2090 // TODO: once we add support for UART_ERR_WR_MASK it needs to be documented here.
2091 /// ## Example
2092 ///
2093 /// ```rust, no_run
2094 /// # {before_snippet}
2095 /// use esp_hal::uart::{Config, Uart};
2096 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2097 ///
2098 /// while !uart.read_ready() {
2099 /// // Do something else while waiting for data to be available.
2100 /// }
2101 ///
2102 /// let mut buf = [0u8; 32];
2103 /// uart.read(&mut buf[..])?;
2104 ///
2105 /// # {after_snippet}
2106 /// ```
2107 pub fn read_ready(&self) -> bool {
2108 self.rx.read_ready()
2109 }
2110
2111 /// Returns whether a break condition has been detected.
2112 ///
2113 /// The returned status is sticky and remains set until
2114 /// [`Self::clear_break_detected`] is called, or until one of the
2115 /// `wait_for_break` methods observes and clears it.
2116 #[instability::unstable]
2117 pub fn is_break_detected(&self) -> bool {
2118 self.rx.is_break_detected()
2119 }
2120
2121 /// Clears the break-detection status.
2122 #[instability::unstable]
2123 pub fn clear_break_detected(&mut self) {
2124 self.rx.clear_break_detected();
2125 }
2126
2127 #[procmacros::doc_replace]
2128 /// Read received bytes.
2129 ///
2130 /// The UART hardware continuously receives bytes and stores them in the RX
2131 /// FIFO. This function reads the bytes from the RX FIFO and returns
2132 /// them in the provided buffer. If the hardware buffer is empty, this
2133 /// function will block until data is available. The [`Self::read_ready`]
2134 /// function can be used to check if data is available without blocking.
2135 ///
2136 /// The function returns the number of bytes read into the buffer. This may
2137 /// be less than the length of the buffer. This function only returns 0
2138 /// if the provided buffer is empty.
2139 ///
2140 /// ## Errors
2141 ///
2142 /// This function returns an [`RxError`] if a reported error occurred since
2143 /// the last check for errors.
2144 ///
2145 /// If the error occurred before this function was called, the contents of
2146 /// the FIFO are not modified.
2147 ///
2148 /// ## Example
2149 ///
2150 /// ```rust, no_run
2151 /// # {before_snippet}
2152 /// use esp_hal::uart::{Config, Uart};
2153 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2154 ///
2155 /// const MESSAGE: &[u8] = b"Hello, world!";
2156 /// uart.write(&MESSAGE)?;
2157 /// uart.flush()?;
2158 ///
2159 /// let mut buf = [0u8; MESSAGE.len()];
2160 /// uart.read(&mut buf[..])?;
2161 ///
2162 /// # {after_snippet}
2163 /// ```
2164 pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2165 self.rx.read(buf)
2166 }
2167
2168 #[procmacros::doc_replace]
2169 /// Change the configuration.
2170 ///
2171 /// ## Errors
2172 ///
2173 /// This function returns a [`ConfigError`] if the configuration is not
2174 /// supported by the hardware.
2175 ///
2176 /// ## Example
2177 ///
2178 /// ```rust, no_run
2179 /// # {before_snippet}
2180 /// use esp_hal::uart::{Config, Uart};
2181 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?;
2182 ///
2183 /// uart.apply_config(&Config::default().with_baudrate(19_200))?;
2184 /// # {after_snippet}
2185 /// ```
2186 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
2187 // Must apply the common settings first, as `rx.apply_config` reads back symbol
2188 // size.
2189 self.rx.uart.info().apply_config(config)?;
2190
2191 self.rx.apply_config(config)?;
2192 self.tx.apply_config(config)?;
2193 Ok(())
2194 }
2195
2196 /// Lets activity on the RX line wake the chip from light sleep.
2197 ///
2198 /// See [`UartRx::enable_wakeup`].
2199 ///
2200 /// # Errors
2201 ///
2202 /// Returns [`WakeConfigError::NotAWakeupSource`] if this UART instance cannot wake the chip,
2203 /// and [`WakeConfigError::EdgeCountUnsupported`] if the hardware cannot count the requested
2204 /// number of edges.
2205 #[cfg(sleep_driver_supported)]
2206 #[instability::unstable]
2207 pub fn enable_wakeup(&mut self, config: &WakeupConfig) -> Result<(), WakeConfigError> {
2208 self.rx.enable_wakeup(config)
2209 }
2210
2211 /// Stops the UART from waking the chip.
2212 #[cfg(sleep_driver_supported)]
2213 #[instability::unstable]
2214 pub fn disable_wakeup(&mut self) {
2215 self.rx.disable_wakeup();
2216 }
2217
2218 #[procmacros::doc_replace]
2219 /// Split the UART into a transmitter and receiver
2220 ///
2221 /// This is particularly useful when having two tasks correlating to
2222 /// transmitting and receiving.
2223 ///
2224 /// ## Example
2225 ///
2226 /// ```rust, no_run
2227 /// # {before_snippet}
2228 /// use esp_hal::uart::{Config, Uart};
2229 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
2230 /// .with_rx(peripherals.GPIO1)
2231 /// .with_tx(peripherals.GPIO2);
2232 ///
2233 /// // The UART can be split into separate Transmit and Receive components:
2234 /// let (mut rx, mut tx) = uart.split();
2235 ///
2236 /// // Each component can be used individually to interact with the UART:
2237 /// tx.write(&[42u8])?;
2238 /// let mut byte = [0u8; 1];
2239 /// rx.read(&mut byte);
2240 /// # {after_snippet}
2241 /// ```
2242 #[instability::unstable]
2243 pub fn split(self) -> (UartRx<'d, Dm>, UartTx<'d, Dm>) {
2244 (self.rx, self.tx)
2245 }
2246
2247 #[procmacros::doc_replace]
2248 /// Borrows the UART as separate transmitter and receiver halves.
2249 ///
2250 /// Unlike [`split`], this method does not consume the UART. The returned
2251 /// transmitter and receiver are borrowed from the original UART, which can
2252 /// be used again after those borrows end.
2253 ///
2254 /// This is particularly useful when running separate transmit and receive
2255 /// futures concurrently.
2256 ///
2257 /// ## Example
2258 ///
2259 /// ```rust, no_run
2260 /// # {before_snippet}
2261 /// use esp_hal::uart::{Config, Uart};
2262 /// let mut uart = Uart::new(peripherals.UART0, Config::default())?
2263 /// .with_rx(peripherals.GPIO1)
2264 /// .with_tx(peripherals.GPIO2);
2265 ///
2266 /// loop {
2267 /// // The UART can be split into separate Transmit and Receive components:
2268 /// let (rx, tx) = uart.split_mut();
2269 ///
2270 /// // Each component can be used individually to interact with the UART:
2271 /// tx.write(&[42u8])?;
2272 /// let mut byte = [0u8; 1];
2273 /// rx.read(&mut byte);
2274 /// }
2275 /// # {after_snippet}
2276 /// ```
2277 #[instability::unstable]
2278 pub fn split_mut(&mut self) -> (&mut UartRx<'d, Dm>, &mut UartTx<'d, Dm>) {
2279 (&mut self.rx, &mut self.tx)
2280 }
2281
2282 /// Reads and clears RX error conditions set by received data.
2283 ///
2284 /// Only errors enabled in [`RxConfig::with_reported_errors`] are returned;
2285 /// disabled errors are cleared and ignored.
2286 #[instability::unstable]
2287 pub fn check_for_rx_errors(&mut self) -> Result<(), RxError> {
2288 self.rx.check_for_errors()
2289 }
2290
2291 /// Read already received bytes.
2292 ///
2293 /// This function reads the already received bytes from the FIFO into the
2294 /// provided buffer. The function does not wait for the FIFO to actually
2295 /// contain any bytes.
2296 ///
2297 /// The function returns the number of bytes read into the buffer. This may
2298 /// be less than the length of the buffer, and it may also be 0.
2299 ///
2300 /// ## Errors
2301 ///
2302 /// This function returns an [`RxError`] if a reported error occurred since
2303 /// the last check for errors.
2304 ///
2305 /// If the error occurred before this function was called, the contents of
2306 /// the FIFO are not modified.
2307 #[instability::unstable]
2308 pub fn read_buffered(&mut self, buf: &mut [u8]) -> Result<usize, RxError> {
2309 self.rx.read_buffered(buf)
2310 }
2311
2312 /// Configures the AT-CMD detection settings
2313 #[instability::unstable]
2314 pub fn set_at_cmd(&mut self, config: AtCmdConfig) {
2315 #[cfg(uart_has_sclk_enable)]
2316 self.rx.uart.info().set_at_cmd_clock_enabled(false);
2317
2318 self.regs().at_cmd_char().write(|w| unsafe {
2319 w.at_cmd_char().bits(config.cmd_char);
2320 w.char_num().bits(config.char_num)
2321 });
2322
2323 if let Some(pre_idle_count) = config.pre_idle_count {
2324 self.regs()
2325 .at_cmd_precnt()
2326 .write(|w| unsafe { w.pre_idle_num().bits(pre_idle_count as _) });
2327 }
2328
2329 if let Some(post_idle_count) = config.post_idle_count {
2330 self.regs()
2331 .at_cmd_postcnt()
2332 .write(|w| unsafe { w.post_idle_num().bits(post_idle_count as _) });
2333 }
2334
2335 if let Some(gap_timeout) = config.gap_timeout {
2336 self.regs()
2337 .at_cmd_gaptout()
2338 .write(|w| unsafe { w.rx_gap_tout().bits(gap_timeout as _) });
2339 }
2340
2341 #[cfg(uart_has_sclk_enable)]
2342 self.rx.uart.info().set_at_cmd_clock_enabled(true);
2343
2344 sync_regs(self.regs());
2345 }
2346
2347 #[inline(always)]
2348 fn init(&mut self, config: Config) -> Result<(), ConfigError> {
2349 self.rx.disable_rx_interrupts();
2350 self.tx.disable_tx_interrupts();
2351
2352 // Applying config also resets Tx/Rx FIFOs
2353 self.apply_config(&config)?;
2354
2355 // Don't wait after transmissions by default,
2356 // so that bytes written to TX FIFO are always immediately transmitted.
2357 self.regs()
2358 .idle_conf()
2359 .modify(|_, w| unsafe { w.tx_idle_num().bits(0) });
2360 // `idle_conf` is a sync register.
2361 sync_regs(self.regs());
2362
2363 crate::rom::ets_delay_us(15);
2364
2365 // Make sure we are starting in a "clean state" - previous operations might have
2366 // run into error conditions
2367 self.regs().int_clr().write(|w| unsafe { w.bits(u32::MAX) });
2368
2369 Ok(())
2370 }
2371}
2372
2373/// UART Tx or Rx Error
2374#[instability::unstable]
2375#[derive(Debug, Clone, Copy, PartialEq)]
2376#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2377#[non_exhaustive]
2378pub enum IoError {
2379 /// UART TX error
2380 Tx(TxError),
2381 /// UART RX error
2382 Rx(RxError),
2383}
2384
2385#[instability::unstable]
2386impl core::error::Error for IoError {}
2387
2388#[instability::unstable]
2389impl core::fmt::Display for IoError {
2390 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2391 match self {
2392 IoError::Tx(e) => e.fmt(f),
2393 IoError::Rx(e) => e.fmt(f),
2394 }
2395 }
2396}
2397
2398#[instability::unstable]
2399impl From<RxError> for IoError {
2400 fn from(e: RxError) -> Self {
2401 IoError::Rx(e)
2402 }
2403}
2404
2405#[instability::unstable]
2406impl From<TxError> for IoError {
2407 fn from(e: TxError) -> Self {
2408 IoError::Tx(e)
2409 }
2410}