Add async UART HIL test (#1345)

* wip

* Clean up Cargo config/manifest, update dependencies

* Remove TODO comment from test

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
This commit is contained in:
Jesse Braham 2024-03-26 10:10:17 +00:00 committed by GitHub
parent 7792d67b47
commit 9b64e648e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 113 additions and 23 deletions

View File

@ -1763,15 +1763,15 @@ mod asynch {
T: Instance,
{
/// See [`UartRx::read_async`]
async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
self.rx.read_async(buf).await
}
async fn write_async(&mut self, words: &[u8]) -> Result<usize, Error> {
pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, Error> {
self.tx.write_async(words).await
}
async fn flush_async(&mut self) -> Result<(), Error> {
pub async fn flush_async(&mut self) -> Result<(), Error> {
self.tx.flush_async().await
}
}
@ -1780,7 +1780,7 @@ mod asynch {
where
T: Instance,
{
async fn write_async(&mut self, words: &[u8]) -> Result<usize, Error> {
pub async fn write_async(&mut self, words: &[u8]) -> Result<usize, Error> {
let mut count = 0;
let mut offset: usize = 0;
loop {
@ -1805,7 +1805,7 @@ mod asynch {
Ok(count)
}
async fn flush_async(&mut self) -> Result<(), Error> {
pub async fn flush_async(&mut self) -> Result<(), Error> {
let count = T::get_tx_fifo_count();
if count > 0 {
UartTxFuture::<T>::new(TxEvent::TxDone.into()).await;
@ -1839,7 +1839,7 @@ mod asynch {
/// # Ok
/// When successful, returns the number of bytes written to buf.
/// This method will never return Ok(0), unless buf.len() == 0.
async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
if buf.len() == 0 {
return Ok(0);
}

View File

@ -20,22 +20,30 @@ harness = false
name = "uart"
harness = false
[[test]]
name = "uart_async"
harness = false
required-features = ["async", "embassy"]
[dependencies]
defmt = { version = "0.3.5" }
defmt-rtt = { version = "0.4.0" }
esp-hal = { path = "../esp-hal", features = ["embedded-hal", "embedded-hal-02", "defmt"], optional = true }
embedded-hal-02 = { version = "0.2.7", package = "embedded-hal", features = ["unproven"] }
defmt = { version = "0.3.6" }
defmt-rtt = { version = "0.4.0" }
embassy-time = { version = "0.3.0", features = ["generic-queue-8"] }
embedded-hal = { version = "1.0.0" }
embedded-hal-02 = { version = "0.2.7", package = "embedded-hal", features = ["unproven"] }
embedded-hal-async = { version = "1.0.0", optional = true }
embedded-hal = { version = "1.0.0" }
embedded-hal-nb = { version = "1.0.0", optional = true }
embassy-executor = { default-features = false, version = "0.5.0", features = ["executor-thread", "arch-riscv32"], optional = true }
semihosting = "0.1.6"
embedded-hal-nb = { version = "1.0.0", optional = true }
esp-hal = { path = "../esp-hal", features = ["defmt", "embedded-hal", "embedded-hal-02"], optional = true }
semihosting = { git = "https://github.com/taiki-e/semihosting", rev = "c829c19" }
[dev-dependencies]
embassy-executor = { version = "0.5.0", default-features = false, features = ["executor-thread", "arch-riscv32"] }
# Add the `embedded-test/defmt` feature for more verbose testing
embedded-test = {git = "https://github.com/probe-rs/embedded-test", rev = "8e3f925"}
embedded-test = {git = "https://github.com/probe-rs/embedded-test", rev = "8e3f925" }
[features]
default = ["async", "embassy", "embassy-time-timg0"]
# Device support (required!):
esp32 = ["esp-hal/esp32"]
esp32c2 = ["esp-hal/esp32c2"]
@ -45,13 +53,13 @@ esp32h2 = ["esp-hal/esp32h2"]
esp32s2 = ["esp-hal/esp32s2"]
esp32s3 = ["esp-hal/esp32s3"]
# Async & Embassy:
async = ["dep:embedded-hal-async", "esp-hal?/async"]
embassy = ["esp-hal?/embassy", "embedded-test/embassy", "dep:embassy-executor"]
async = ["dep:embedded-hal-async", "esp-hal?/async"]
embassy = ["esp-hal?/embassy", "embedded-test/embassy"]
embassy-executor-interrupt = ["esp-hal?/embassy-executor-interrupt"]
embassy-executor-thread = ["esp-hal?/embassy-executor-thread"]
embassy-time-systick-16mhz = ["esp-hal?/embassy-time-systick-16mhz"]
embassy-time-systick-80mhz = ["esp-hal?/embassy-time-systick-80mhz"]
embassy-time-timg0 = ["esp-hal?/embassy-time-timg0"]
embassy-time-timg0 = ["esp-hal?/embassy-time-timg0"]
# https://doc.rust-lang.org/cargo/reference/profiles.html#test
# Test and bench profiles inherit from dev and release respectively.
@ -61,7 +69,7 @@ codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
opt-level = 'z'
opt-level = "z"
overflow-checks = true
[profile.release]
@ -70,8 +78,5 @@ debug = 2
debug-assertions = false
incremental = false
opt-level = 3
lto = 'fat'
lto = "fat"
overflow-checks = false
[patch.crates-io]
semihosting = { git = "https://github.com/taiki-e/semihosting", rev = "c829c19" }

View File

@ -0,0 +1,85 @@
//! UART Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO4
//!
//! Connect TX (GPIO2) and RX (GPIO4) pins.
#![no_std]
#![no_main]
use defmt_rtt as _;
use esp_hal::{
clock::ClockControl,
gpio::IO,
peripherals::{Peripherals, UART0},
prelude::*,
uart::{
config::{Config, DataBits, Parity, StopBits},
TxRxPins,
Uart,
UartRx,
UartTx,
},
Async,
};
struct Context {
tx: UartTx<'static, UART0, Async>,
rx: UartRx<'static, UART0, Async>,
}
impl Context {
pub fn init() -> Self {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
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.into_push_pull_output(),
io.pins.gpio4.into_floating_input(),
);
let config = Config {
baudrate: 115200,
data_bits: DataBits::DataBits8,
parity: Parity::ParityNone,
stop_bits: StopBits::STOP1,
};
let uart = Uart::new_async_with_config(peripherals.UART0, config, Some(pins), &clocks);
let (tx, rx) = uart.split();
Context { rx, tx }
}
}
#[cfg(test)]
#[embedded_test::tests]
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) {
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.tx.write_async(&SEND).await.unwrap();
ctx.tx.flush_async().await.unwrap();
ctx.rx.read_async(&mut buf[..]).await.unwrap();
assert_eq!(&buf[..], SEND);
}
}