diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index 6d9407f1e..35bfc4f32 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -397,6 +397,25 @@ pub trait DriverMode: crate::private::Sealed {} /// Drivers are constructed in blocking mode by default. To learn about the /// differences between blocking and async drivers, see the [`Async`] mode /// documentation. +/// +/// [`Async`] drivers can be converted to a [`Blocking`] driver using the +/// `into_blocking` method, for example: +/// +/// ```rust, no_run +#[doc = crate::before_snippet!()] +/// # use esp_hal::uart::{Config, Uart}; +/// let uart = Uart::new( +/// peripherals.UART0, +/// Config::default())? +/// .with_rx(peripherals.GPIO1) +/// .with_tx(peripherals.GPIO2) +/// .into_async(); +/// +/// let blocking_uart = uart.into_blocking(); +/// +/// # Ok(()) +/// # } +/// ``` #[derive(Debug)] #[non_exhaustive] pub struct Blocking; @@ -405,8 +424,24 @@ pub struct Blocking; /// /// Drivers are constructed in blocking mode by default. To set up an async /// driver, a [`Blocking`] driver must be converted to an `Async` driver using -/// the `into_async` method. Drivers can be converted back to blocking mode -/// using the `into_blocking` method. +/// the `into_async` method, for example: +/// +/// ```rust, no_run +#[doc = crate::before_snippet!()] +/// # use esp_hal::uart::{Config, Uart}; +/// let uart = Uart::new( +/// peripherals.UART0, +/// Config::default())? +/// .with_rx(peripherals.GPIO1) +/// .with_tx(peripherals.GPIO2) +/// .into_async(); +/// +/// # Ok(()) +/// # } +/// ``` +/// +/// Drivers can be converted back to blocking mode using the `into_blocking` +/// method, see [`Blocking`] documentation for more details. /// /// Async mode drivers offer most of the same features as blocking drivers, but /// with the addition of async APIs. Interrupt-related functions are not diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 14dcaaf30..39f3c281b 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -473,6 +473,8 @@ where /// UART (Full-duplex) /// +/// ## Example +/// /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::uart::{Config, Uart}; @@ -911,7 +913,7 @@ impl<'d> UartRx<'d, Blocking> { #[doc = crate::before_snippet!()] /// # use esp_hal::uart::{Config, UartRx}; /// let rx = UartRx::new( - /// peripherals.UART1, + /// peripherals.UART0, /// Config::default())? /// .with_rx(peripherals.GPIO2); /// # Ok(()) @@ -1237,8 +1239,8 @@ impl<'d> Uart<'d, Blocking> { /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::uart::{Config, Uart}; - /// let mut uart1 = Uart::new( - /// peripherals.UART1, + /// let mut uart = Uart::new( + /// peripherals.UART0, /// Config::default())? /// .with_rx(peripherals.GPIO1) /// .with_tx(peripherals.GPIO2); @@ -1250,6 +1252,9 @@ impl<'d> Uart<'d, Blocking> { } /// Reconfigures the driver to operate in [`Async`] mode. + /// + /// See the [`Async`] documentation for an example on how to use this + /// method. pub fn into_async(self) -> Uart<'d, Async> { Uart { rx: self.rx.into_async(), @@ -1292,16 +1297,16 @@ impl<'d> Uart<'d, Blocking> { /// # let config = Config::default().with_rx( /// # RxConfig::default().with_fifo_full_threshold(30) /// # ); - /// # let mut uart0 = Uart::new( + /// # let mut uart = Uart::new( /// # peripherals.UART0, /// # config)?; - /// uart0.set_interrupt_handler(interrupt_handler); + /// uart.set_interrupt_handler(interrupt_handler); /// /// critical_section::with(|cs| { - /// uart0.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#')); - /// uart0.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull); + /// uart.set_at_cmd(AtCmdConfig::default().with_cmd_char(b'#')); + /// uart.listen(UartInterrupt::AtCmd | UartInterrupt::RxFifoFull); /// - /// SERIAL.borrow_ref_mut(cs).replace(uart0); + /// SERIAL.borrow_ref_mut(cs).replace(uart); /// }); /// /// loop { @@ -1368,6 +1373,9 @@ impl<'d> Uart<'d, Blocking> { impl<'d> Uart<'d, Async> { /// Reconfigures the driver to operate in [`Blocking`] mode. + /// + /// See the [`Blocking`] documentation for an example on how to use this + /// method. pub fn into_blocking(self) -> Uart<'d, Blocking> { Uart { rx: self.rx.into_blocking(), @@ -1390,6 +1398,24 @@ impl<'d> Uart<'d, Async> { /// ## Cancellation /// /// This function is cancellation safe. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_rx(peripherals.GPIO1) + /// .with_tx(peripherals.GPIO2) + /// .into_async(); + /// + /// const MESSAGE: &[u8] = b"Hello, world!"; + /// uart.write_async(&MESSAGE).await?; + /// # Ok(()) + /// # } + /// ``` pub async fn write_async(&mut self, words: &[u8]) -> Result { self.tx.write_async(words).await } @@ -1403,6 +1429,25 @@ impl<'d> Uart<'d, Async> { /// ## Cancellation /// /// This function is cancellation safe. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_rx(peripherals.GPIO1) + /// .with_tx(peripherals.GPIO2) + /// .into_async(); + /// + /// const MESSAGE: &[u8] = b"Hello, world!"; + /// uart.write_async(&MESSAGE).await?; + /// uart.flush_async().await?; + /// # Ok(()) + /// # } + /// ``` pub async fn flush_async(&mut self) -> Result<(), TxError> { self.tx.flush_async().await } @@ -1425,6 +1470,28 @@ impl<'d> Uart<'d, Async> { /// ## Cancellation /// /// This function is cancellation safe. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_rx(peripherals.GPIO1) + /// .with_tx(peripherals.GPIO2) + /// .into_async(); + /// + /// const MESSAGE: &[u8] = b"Hello, world!"; + /// uart.write_async(&MESSAGE).await?; + /// uart.flush_async().await?; + /// + /// let mut buf = [0u8; MESSAGE.len()]; + /// uart.read_async(&mut buf[..]).await.unwrap(); + /// # Ok(()) + /// # } + /// ``` pub async fn read_async(&mut self, buf: &mut [u8]) -> Result { self.rx.read_async(buf).await } @@ -1483,6 +1550,20 @@ where /// configure the driver side (i.e. the TX pin), or ensure that the line is /// initially high, to avoid receiving a non-data byte caused by an /// initial low signal level. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_rx(peripherals.GPIO1); + /// + /// # Ok(()) + /// # } + /// ``` pub fn with_rx(mut self, rx: impl PeripheralInput<'d>) -> Self { self.rx = self.rx.with_rx(rx); self @@ -1492,18 +1573,62 @@ where /// /// Sets the specified pin to push-pull output and connects it to the UART /// TX signal. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_tx(peripherals.GPIO2); + /// + /// # Ok(()) + /// # } + /// ``` pub fn with_tx(mut self, tx: impl PeripheralOutput<'d>) -> Self { self.tx = self.tx.with_tx(tx); self } /// Configure CTS pin + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_rx(peripherals.GPIO1) + /// .with_cts(peripherals.GPIO3); + /// + /// # Ok(()) + /// # } + /// ``` pub fn with_cts(mut self, cts: impl PeripheralInput<'d>) -> Self { self.rx = self.rx.with_cts(cts); self } /// Configure RTS pin + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_tx(peripherals.GPIO2) + /// .with_rts(peripherals.GPIO3); + /// + /// # Ok(()) + /// # } + /// ``` pub fn with_rts(mut self, rts: impl PeripheralOutput<'d>) -> Self { self.tx = self.tx.with_rts(rts); self @@ -1541,11 +1666,12 @@ where /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::uart::{Config, Uart}; - /// # let mut uart1 = Uart::new( - /// # peripherals.UART1, - /// # Config::default())?; - /// // Write bytes out over the UART: - /// uart1.write(b"Hello, world!")?; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())?; + /// + /// const MESSAGE: &[u8] = b"Hello, world!"; + /// uart.write(&MESSAGE)?; /// # Ok(()) /// # } /// ``` @@ -1554,6 +1680,22 @@ where } /// Flush the transmit buffer of the UART + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())?; + /// + /// const MESSAGE: &[u8] = b"Hello, world!"; + /// uart.write(&MESSAGE)?; + /// uart.flush()?; + /// # Ok(()) + /// # } + /// ``` pub fn flush(&mut self) -> Result<(), TxError> { self.tx.flush() } @@ -1583,6 +1725,26 @@ where /// /// If the error occurred before this function was called, the contents of /// the FIFO are not modified. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())?; + /// + /// const MESSAGE: &[u8] = b"Hello, world!"; + /// uart.write(&MESSAGE)?; + /// uart.flush()?; + /// + /// let mut buf = [0u8; MESSAGE.len()]; + /// uart.read(&mut buf[..])?; + /// + /// # Ok(()) + /// # } + /// ``` pub fn read(&mut self, buf: &mut [u8]) -> Result { self.rx.read(buf) } @@ -1593,6 +1755,20 @@ where /// /// This function returns a [`ConfigError`] if the configuration is not /// supported by the hardware. + /// + /// ## Example + /// + /// ```rust, no_run + #[doc = crate::before_snippet!()] + /// # use esp_hal::uart::{Config, Uart}; + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())?; + /// + /// uart.apply_config(&Config::default().with_baudrate(19_200))?; + /// # Ok(()) + /// # } + /// ``` pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> { // Must apply the common settings first, as `rx.apply_config` reads back symbol // size. @@ -1612,13 +1788,14 @@ where /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::uart::{Config, Uart}; - /// # let mut uart1 = Uart::new( - /// # peripherals.UART1, - /// # Config::default())? - /// # .with_rx(peripherals.GPIO1) - /// # .with_tx(peripherals.GPIO2); + /// let mut uart = Uart::new( + /// peripherals.UART0, + /// Config::default())? + /// .with_rx(peripherals.GPIO1) + /// .with_tx(peripherals.GPIO2); + /// /// // The UART can be split into separate Transmit and Receive components: - /// let (mut rx, mut tx) = uart1.split(); + /// let (mut rx, mut tx) = uart.split(); /// /// // Each component can be used individually to interact with the UART: /// tx.write(&[42u8])?;