Rework Uart constructors, add UartTx and UartRx constuctors. (#1592)

* feat: Add with_pins methods for UART

* feat: Remove configure_pin methods

* docs: Update changelog

* fix: Update tests and examples

* style: Fix format

* Add UartTx/Rx constructors

* feat: Add new_with_default_pins methods

* docs: Update changelog

* feat: Remove optional cts/rts arguments

* feat: Add UartTx/Rx::new_async methods

* fix: Attach interrupt handler to new_ascyn UartRx/Tx

* style: Avoid long module paths

* feat: Make flush_tx public

* test: Use Uart async instead of UartTx/Rx async

* test: Add tests for UartTx/UartRx

* feat: Add configuration method to constuctors

* feat: Move set_rx_fifo_full_threshold and set_rx_timeout to UartRx

* docs: Fix changelog

* test: Fix executor

* feat: Configure UartRx threshold and timeout

* docs: Update changelog

* test: Update uart instance

* feat: Add default_uart0_pins macro to simplify examples

* feat: Address feedback pt1

* feat: Address feedback pt2 - Make constructors fallible

* fix: Doctest
This commit is contained in:
Sergio Gasquez Arcos 2024-06-11 15:07:17 +02:00 committed by GitHub
parent 4c5e493b1b
commit a33159a021
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 727 additions and 341 deletions

View File

@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- uart: Added `with_cts`/`with_rts`s methods to configure CTS, and RTS pins (#1592)
- uart: Constructors now require TX and RX pins (#1592)
- uart: Added `Uart::new_with_default_pins` constructor (#1592)
- uart: Added `UartTx` and `UartRx` constructors (#1592)
- Add Flex / AnyFlex GPIO pin driver (#1659)
@ -18,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Refactor `Dac1`/`Dac2` drivers into a single `Dac` driver (#1661)
### Removed
- uart: Removed `configure_pins` methods (#1592)
## [0.18.0] - 2024-06-04

View File

@ -41,5 +41,5 @@ pub use crate::timer::timg::{
#[cfg(any(systimer, timg0, timg1))]
pub use crate::timer::Timer as _esp_hal_timer_Timer;
#[cfg(any(uart0, uart1, uart2))]
pub use crate::uart::{Instance as _esp_hal_uart_Instance, UartPins as _esp_hal_uart_UartPins};
pub use crate::uart::Instance as _esp_hal_uart_Instance;
pub use crate::{entry, macros::*};

View File

@ -32,9 +32,11 @@
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::md5;
//! # use esp_hal::uart::Uart;
//! # use esp_hal::gpio::Io;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut uart0 = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut uart0 = Uart::new(peripherals.UART0, &clocks, io.pins.gpio1, io.pins.gpio2).unwrap();
//! # let data = "Dummy";
//! let d: md5::Digest = md5::compute(&data);
//! writeln!(uart0, "{}", d);
@ -46,9 +48,11 @@
#![doc = crate::before_snippet!()]
//! # use esp_hal::rom::md5;
//! # use esp_hal::uart::Uart;
//! # use esp_hal::gpio::Io;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut uart0 = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut uart0 = Uart::new(peripherals.UART0, &clocks, io.pins.gpio1, io.pins.gpio2).unwrap();
//! # let data0 = "Dummy";
//! # let data1 = "Dummy";
//! let mut ctx = md5::Context::new();

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

View File

@ -22,10 +22,12 @@
//! ```rust, no_run
#![doc = crate::before_snippet!()]
//! # use esp_hal::efuse::Efuse;
//! # use esp_hal::gpio::Io;
//! # use esp_hal::uart::Uart;
//! # use core::writeln;
//! # use core::fmt::Write;
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks);
//! # let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
//! # let mut serial_tx = Uart::new(peripherals.UART0, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
//! let mac_address = Efuse::read_base_mac_address();
//! writeln!(
//! serial_tx,

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ use esp_hal::{
peripherals::Peripherals,
prelude::*,
system::SystemControl,
uart::{config::Config, TxRxPins, Uart},
uart::Uart,
};
use esp_println::println;
use nb::block;
@ -32,15 +32,8 @@ fn main() -> ! {
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let pins = TxRxPins::new_tx_rx(io.pins.gpio4, io.pins.gpio5);
let mut serial1 = Uart::new_with_config(
peripherals.UART1,
Config::default(),
Some(pins),
&clocks,
None,
);
let mut serial1 = Uart::new(peripherals.UART1, &clocks, io.pins.gpio4, io.pins.gpio5).unwrap();
let delay = Delay::new(&clocks);

View File

@ -14,11 +14,18 @@ use embassy_sync::{blocking_mutex::raw::NoopRawMutex, signal::Signal};
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
default_uart0_pins,
gpio::Io,
peripherals::{Peripherals, UART0},
prelude::*,
system::SystemControl,
timer::timg::TimerGroup,
uart::{config::AtCmdConfig, Uart, UartRx, UartTx},
uart::{
config::{AtCmdConfig, Config},
Uart,
UartRx,
UartTx,
},
Async,
};
use static_cell::StaticCell;
@ -82,11 +89,18 @@ async fn main(spawner: Spawner) {
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
esp_hal_embassy::init(&clocks, timg0);
let mut uart0 = Uart::new_async(peripherals.UART0, &clocks);
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
// Default pins for Uart/Serial communication
let (tx_pin, rx_pin) = default_uart0_pins!(io);
let config = Config::default();
config.rx_fifo_full_threshold(READ_BUF_SIZE as u16);
let mut uart0 =
Uart::new_async_with_config(peripherals.UART0, config, &clocks, tx_pin, rx_pin).unwrap();
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None));
uart0
.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16)
.unwrap();
let (tx, rx) = uart0.split();
static SIGNAL: StaticCell<Signal<NoopRawMutex, usize>> = StaticCell::new();

View File

@ -17,7 +17,9 @@ use core::fmt::Write;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
default_uart0_pins,
delay::Delay,
gpio::Io,
peripherals::Peripherals,
prelude::*,
system::SystemControl,
@ -32,7 +34,13 @@ fn main() -> ! {
let delay = Delay::new(&clocks);
let mut uart0 = Uart::new(peripherals.UART0, &clocks);
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
// Default pins for Uart/Serial communication
let (mut tx_pin, mut rx_pin) = default_uart0_pins!(io);
let mut uart0 =
Uart::new_with_default_pins(peripherals.UART0, &clocks, &mut tx_pin, &mut rx_pin).unwrap();
loop {
writeln!(uart0, "Hello world!").unwrap();

View File

@ -10,6 +10,8 @@
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
default_uart0_pins,
gpio::Io,
peripherals::Peripherals,
prelude::*,
reset::software_reset,
@ -25,7 +27,13 @@ fn main() -> ! {
let system = SystemControl::new(peripherals.SYSTEM);
let clocks = ClockControl::max(system.clock_control).freeze();
let mut uart0 = Uart::new(peripherals.UART0, &clocks);
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
// Default pins for Uart/Serial communication
let (mut tx_pin, mut rx_pin) = default_uart0_pins!(io);
let mut uart0 =
Uart::new_with_default_pins(peripherals.UART0, &clocks, &mut tx_pin, &mut rx_pin).unwrap();
// read two characters which get parsed as the channel
let mut cnt = 0;

View File

@ -21,7 +21,7 @@ use esp_hal::{
peripherals::Peripherals,
prelude::*,
system::SystemControl,
uart::{config::Config, lp_uart::LpUart, TxRxPins, Uart},
uart::{config::Config, lp_uart::LpUart, Uart},
};
use esp_println::println;
@ -35,15 +35,15 @@ fn main() -> ! {
// Set up (HP) UART1:
let pins = TxRxPins::new_tx_rx(io.pins.gpio6, io.pins.gpio7);
let mut uart1 = Uart::new_with_config(
peripherals.UART1,
Config::default(),
Some(pins),
&clocks,
None,
);
io.pins.gpio6,
io.pins.gpio7,
)
.unwrap();
// Set up (LP) UART:
let lp_tx = LowPowerOutput::new(io.pins.gpio5);

View File

@ -13,14 +13,14 @@ use critical_section::Mutex;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
default_uart0_pins,
delay::Delay,
gpio,
gpio::Io,
peripherals::{Peripherals, UART0},
prelude::*,
system::SystemControl,
uart::{
config::{AtCmdConfig, Config},
TxRxPins,
Uart,
},
Blocking,
@ -36,17 +36,26 @@ fn main() -> ! {
let delay = Delay::new(&clocks);
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
// Default pins for Uart/Serial communication
let (tx_pin, rx_pin) = default_uart0_pins!(io);
let config = Config::default();
config.rx_fifo_full_threshold(30);
let mut uart0 = Uart::new_with_config(
peripherals.UART0,
Config::default(),
None::<TxRxPins<gpio::NoPinType, gpio::NoPinType>>,
config,
&clocks,
Some(interrupt_handler),
);
tx_pin,
rx_pin,
)
.unwrap();
critical_section::with(|cs| {
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, b'#', None));
uart0.set_rx_fifo_full_threshold(30).unwrap();
uart0.listen_at_cmd();
uart0.listen_rx_fifo_full();

View File

@ -73,6 +73,16 @@ name = "uart_async"
harness = false
required-features = ["async", "embassy"]
[[test]]
name = "uart_tx_rx"
harness = false
[[test]]
name = "uart_tx_rx_async"
harness = false
[dependencies]
cfg-if = "1.0.0"
critical-section = "1.1.2"

View File

@ -17,17 +17,17 @@ use esp_backtrace as _;
use esp_hal::{
clock::{ClockControl, Clocks},
gpio::Io,
peripherals::{Peripherals, UART0},
peripherals::{Peripherals, UART1},
prelude::*,
system::SystemControl,
uart::{config::Config, ClockSource, TxRxPins, Uart},
uart::{ClockSource, Uart},
Blocking,
};
use nb::block;
struct Context {
clocks: Clocks<'static>,
uart: Uart<'static, UART0, Blocking>,
uart: Uart<'static, UART1, Blocking>,
}
impl Context {
@ -37,15 +37,8 @@ impl Context {
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let pins = TxRxPins::new_tx_rx(io.pins.gpio2, io.pins.gpio4);
let uart = Uart::new_with_config(
peripherals.UART0,
Config::default(),
Some(pins),
&clocks,
None,
);
let uart = Uart::new(peripherals.UART1, &clocks, io.pins.gpio2, io.pins.gpio4).unwrap();
Context { clocks, uart }
}

View File

@ -18,13 +18,12 @@ use esp_hal::{
gpio::Io,
peripherals::{Peripherals, UART0},
system::SystemControl,
uart::{config::Config, TxRxPins, Uart, UartRx, UartTx},
uart::Uart,
Async,
};
struct Context {
tx: UartTx<'static, UART0, Async>,
rx: UartRx<'static, UART0, Async>,
uart: Uart<'static, UART0, Async>,
}
impl Context {
@ -33,13 +32,11 @@ impl Context {
let system = SystemControl::new(peripherals.SYSTEM);
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let pins = TxRxPins::new_tx_rx(io.pins.gpio2, io.pins.gpio4);
let uart =
Uart::new_async_with_config(peripherals.UART0, Config::default(), Some(pins), &clocks);
let (tx, rx) = uart.split();
Uart::new_async(peripherals.UART0, &clocks, io.pins.gpio2, io.pins.gpio4).unwrap();
Context { rx, tx }
Context { uart }
}
}
@ -61,14 +58,11 @@ mod tests {
const SEND: &[u8] = &*b"Hello ESP32";
let mut buf = [0u8; SEND.len()];
// Drain the FIFO to clear previous message:
ctx.tx.flush_async().await.unwrap();
while ctx.rx.drain_fifo(&mut buf[..]) > 0 {}
ctx.uart.flush_async().await.unwrap();
ctx.uart.write_async(&SEND).await.unwrap();
ctx.uart.flush_async().await.unwrap();
ctx.tx.write_async(&SEND).await.unwrap();
ctx.tx.flush_async().await.unwrap();
ctx.rx.read_async(&mut buf[..]).await.unwrap();
ctx.uart.read_async(&mut buf[..]).await.unwrap();
assert_eq!(&buf[..], SEND);
}
}

View File

@ -0,0 +1,70 @@
//! UART TX/RX Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO4
//!
//! Connect TX (GPIO2) and RX (GPIO4) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
#![no_std]
#![no_main]
use defmt_rtt as _;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
gpio::Io,
peripherals::{Peripherals, UART0, UART1},
prelude::*,
system::SystemControl,
uart::{UartRx, UartTx},
Blocking,
};
use nb::block;
struct Context {
tx: UartTx<'static, UART0, Blocking>,
rx: UartRx<'static, UART1, Blocking>,
}
impl Context {
pub fn init() -> Self {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let tx = UartTx::new(peripherals.UART0, &clocks, None, io.pins.gpio2).unwrap();
let rx = UartRx::new(peripherals.UART1, &clocks, None, io.pins.gpio4).unwrap();
Context { tx, rx }
}
}
#[cfg(test)]
#[embedded_test::tests]
mod tests {
use defmt::assert_eq;
use super::*;
#[init]
fn init() -> Context {
Context::init()
}
#[test]
#[timeout(3)]
fn test_send_receive(mut ctx: Context) {
let byte = [0x42];
ctx.tx.flush_tx().unwrap();
ctx.tx.write_bytes(&byte).unwrap();
let read = block!(ctx.rx.read_byte());
assert_eq!(read, Ok(0x42));
}
}

View File

@ -0,0 +1,69 @@
//! UART TX/RX Async Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO4
//!
//! Connect TX (GPIO2) and RX (GPIO4) pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
#![no_std]
#![no_main]
use defmt_rtt as _;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
gpio::Io,
peripherals::{Peripherals, UART0, UART1},
system::SystemControl,
uart::{UartRx, UartTx},
Async,
};
struct Context {
tx: UartTx<'static, UART0, Async>,
rx: UartRx<'static, UART1, Async>,
}
impl Context {
pub fn init() -> Self {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let tx = UartTx::new_async(peripherals.UART0, &clocks, io.pins.gpio2).unwrap();
let rx = UartRx::new_async(peripherals.UART1, &clocks, io.pins.gpio4).unwrap();
Context { tx, rx }
}
}
#[cfg(test)]
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
mod tests {
use defmt::assert_eq;
use super::*;
#[init]
async fn init() -> Context {
Context::init()
}
#[test]
#[timeout(3)]
async fn test_send_receive(mut ctx: Context) {
let byte = [0x42];
let mut read = [0u8; 1];
ctx.tx.flush_async().await.unwrap();
ctx.tx.write_async(&byte).await.unwrap();
let _ = ctx.rx.read_async(&mut read).await;
assert_eq!(read, byte);
}
}