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