Adding I2C HIL test (#2023)

* i2c hil test

* pin

* fmt

* Test

* WIP (gpio test left)

* Finalize the CODE part (to be cleaned up)

fmt

* Smaller cleanup

* cleanup

* rebase

* fix

* getting last chips ready

* Addressing reviews
This commit is contained in:
Kirill Mikhailov 2024-09-04 14:45:58 +02:00 committed by GitHub
parent b7b916f03a
commit 9bec6a1806
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 352 additions and 209 deletions

View File

@ -51,6 +51,10 @@ harness = false
name = "interrupt"
harness = false
[[test]]
name = "i2c"
harness = false
[[test]]
name = "i2s"
harness = false

View File

@ -68,35 +68,39 @@ The [`hil.yml`] workflow builds the test suite for all our available targets and
Our self-hosted runners have the following setup:
- ESP32-C2 (`esp32c2-jtag`):
- Devkit: `ESP8684-DevKitM-1` connected via UART.
- `GPIO18` and `GPIO9` are I2C pins.
- `GPIO2` and `GPIO3` are connected.
- Probe: `ESP-Prog` connected with the [following connections][connection_c2]
- RPi: Raspbian 12 configured with the following [setup]
- ESP32-C3 (`rustboard`):
- Devkit: `ESP32-C3-DevKit-RUST-1` connected via USB-Serial-JTAG.
- `GPIO4` and `GPIO5` are I2C pins.
- `GPIO2` and `GPIO3` are connected.
- `GPIO5` and `GPIO6` are connected.
- RPi: Raspbian 12 configured with the following [setup]
- ESP32-C6 (`esp32c6-usb`):
- Devkit: `ESP32-C6-DevKitC-1 V1.2` connected via USB-Serial-JTAG (`USB` port).
- `GPIO6` and `GPIO7` are I2C pins.
- `GPIO2` and `GPIO3` are connected.
- `GPIO5` and `GPIO6` are connected.
- `GPIO4` and `GPIO5` are connected.
- RPi: Raspbian 12 configured with the following [setup]
- ESP32-H2 (`esp32h2-usb`):
- Devkit: `ESP32-H2-DevKitM-1` connected via USB-Serial-JTAG (`USB` port).
- `GPIO12` and `GPIO22` are I2C pins.
- `GPIO2` and `GPIO3` are connected.
- `GPIO5` and `GPIO8` are connected.
- `GPIO4` and `GPIO5` are connected.
- RPi: Raspbian 12 configured with the following [setup]
- ESP32-S2 (`esp32s2-jtag`):
- Devkit: `ESP32-S2-Saola-1` connected via UART.
- `GPIO2` and `GPIO3` are connected.
- `GPIO5` and `GPIO6` are connected.
- `GPIO2` and `GPIO3` are I2C pins.
- `GPIO9` and `GPIO10` are connected.
- Probe: `ESP-Prog` connected with the [following connections][connection_s2]
- RPi: Raspbian 12 configured with the following [setup]
- ESP32-S3 (`esp32s3-usb`):
- Devkit: `ESP32-S3-DevKitC-1` connected via USB-Serial-JTAG.
- `GPIO2` and `GPIO3` are connected.
- `GPIO5` and `GPIO6` are connected.
- `GPIO2` and `GPIO3` are I2C pins.
- `GPIO4` and `GPIO5` are connected.
- `GPIO1` and `GPIO21` are connected.
- `GPIO9` and `GPIO10` are connected.
- `GPIO43 (TX)` and `GPIO45` are connected.
- RPi: Raspbian 12 configured with the following [setup]

View File

@ -22,3 +22,37 @@ unsafe impl defmt::Logger for Logger {
use defmt_rtt as _;
// Make sure esp_backtrace is not removed.
use esp_backtrace as _;
#[macro_export]
macro_rules! i2c_pins {
($io:expr) => {{
// Order: (SDA, SCL)
cfg_if::cfg_if! {
if #[cfg(any(esp32s2, esp32s3))] {
($io.pins.gpio2, $io.pins.gpio3)
} else if #[cfg(esp32c6)] {
($io.pins.gpio6, $io.pins.gpio7)
} else if #[cfg(esp32h2)] {
($io.pins.gpio12, $io.pins.gpio22)
} else if #[cfg(esp32c2)] {
($io.pins.gpio18, $io.pins.gpio9)
} else {
($io.pins.gpio4, $io.pins.gpio5)
}
}
}};
}
#[macro_export]
macro_rules! common_test_pins {
($io:expr) => {{
cfg_if::cfg_if! {
if #[cfg(any(esp32s2, esp32s3))] {
($io.pins.gpio9, $io.pins.gpio10)
}
else {
($io.pins.gpio2, $io.pins.gpio3)
}
}
}};
}

View File

@ -1,8 +1,8 @@
//! GPIO Test
//!
//! Folowing pins are used:
//! GPIO2
//! GPIO3
//! GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! GPIO3 / GPIO10 (esp32s2 and esp32s3)
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: generic-queue
@ -15,7 +15,7 @@ use core::cell::RefCell;
use critical_section::Mutex;
use esp_hal::{
delay::Delay,
gpio::{AnyPin, Gpio2, Gpio3, GpioPin, Input, Io, Level, Output, Pull},
gpio::{AnyPin, GpioPin, Input, Io, Level, Output, Pull},
macros::handler,
timer::timg::TimerGroup,
InterruptConfigurable,
@ -23,11 +23,22 @@ use esp_hal::{
use hil_test as _;
static COUNTER: Mutex<RefCell<u32>> = Mutex::new(RefCell::new(0));
static INPUT_PIN: Mutex<RefCell<Option<Input<'static, Gpio2>>>> = Mutex::new(RefCell::new(None));
static INPUT_PIN: Mutex<RefCell<Option<Input<'static, TestGpio1>>>> =
Mutex::new(RefCell::new(None));
cfg_if::cfg_if! {
if #[cfg(not(any(esp32s2, esp32s3)))] {
pub type TestGpio1 = GpioPin<2>;
pub type TestGpio2 = GpioPin<3>;
} else if #[cfg(any(esp32s2, esp32s3))] {
pub type TestGpio1 = GpioPin<9>;
pub type TestGpio2 = GpioPin<10>;
}
}
struct Context<'d> {
io2: Input<'d, Gpio2>,
io3: Output<'d, Gpio3>,
test_gpio1: Input<'d, TestGpio1>,
test_gpio2: Output<'d, TestGpio2>,
delay: Delay,
}
@ -61,12 +72,14 @@ mod tests {
let delay = Delay::new(&clocks);
let (gpio1, gpio2) = hil_test::common_test_pins!(io);
let timg0 = TimerGroup::new(peripherals.TIMG0, &clocks);
esp_hal_embassy::init(&clocks, timg0.timer0);
Context {
io2: Input::new(io.pins.gpio2, Pull::Down),
io3: Output::new(io.pins.gpio3, Level::Low),
test_gpio1: Input::new(gpio1, Pull::Down),
test_gpio2: Output::new(gpio2, Level::Low),
delay,
}
}
@ -75,20 +88,22 @@ mod tests {
async fn test_async_edge(ctx: Context<'static>) {
let counter = AtomicUsize::new(0);
let Context {
mut io2, mut io3, ..
mut test_gpio1,
mut test_gpio2,
..
} = ctx;
embassy_futures::select::select(
async {
loop {
io2.wait_for_rising_edge().await;
test_gpio1.wait_for_rising_edge().await;
counter.fetch_add(1, Ordering::SeqCst);
}
},
async {
for _ in 0..5 {
io3.set_high();
test_gpio2.set_high();
Timer::after(Duration::from_millis(25)).await;
io3.set_low();
test_gpio2.set_low();
Timer::after(Duration::from_millis(25)).await;
}
},
@ -113,153 +128,155 @@ mod tests {
#[test]
fn test_gpio_input(ctx: Context<'static>) {
// `InputPin`:
assert_eq!(ctx.io2.is_low(), true);
assert_eq!(ctx.io2.is_high(), false);
assert_eq!(ctx.test_gpio1.is_low(), true);
assert_eq!(ctx.test_gpio1.is_high(), false);
}
#[test]
fn test_gpio_output(mut ctx: Context<'static>) {
// `StatefulOutputPin`:
assert_eq!(ctx.io3.is_set_low(), true);
assert_eq!(ctx.io3.is_set_high(), false);
ctx.io3.set_high();
assert_eq!(ctx.io3.is_set_low(), false);
assert_eq!(ctx.io3.is_set_high(), true);
assert_eq!(ctx.test_gpio2.is_set_low(), true);
assert_eq!(ctx.test_gpio2.is_set_high(), false);
ctx.test_gpio2.set_high();
assert_eq!(ctx.test_gpio2.is_set_low(), false);
assert_eq!(ctx.test_gpio2.is_set_high(), true);
// `ToggleableOutputPin`:
ctx.io3.toggle();
assert_eq!(ctx.io3.is_set_low(), true);
assert_eq!(ctx.io3.is_set_high(), false);
ctx.io3.toggle();
assert_eq!(ctx.io3.is_set_low(), false);
assert_eq!(ctx.io3.is_set_high(), true);
ctx.test_gpio2.toggle();
assert_eq!(ctx.test_gpio2.is_set_low(), true);
assert_eq!(ctx.test_gpio2.is_set_high(), false);
ctx.test_gpio2.toggle();
assert_eq!(ctx.test_gpio2.is_set_low(), false);
assert_eq!(ctx.test_gpio2.is_set_high(), true);
}
#[test]
fn test_gpio_interrupt(mut ctx: Context<'static>) {
critical_section::with(|cs| {
*COUNTER.borrow_ref_mut(cs) = 0;
ctx.io2.listen(Event::AnyEdge);
INPUT_PIN.borrow_ref_mut(cs).replace(ctx.io2);
ctx.test_gpio1.listen(Event::AnyEdge);
INPUT_PIN.borrow_ref_mut(cs).replace(ctx.test_gpio1);
});
ctx.io3.set_high();
ctx.test_gpio2.set_high();
ctx.delay.delay_millis(1);
ctx.io3.set_low();
ctx.test_gpio2.set_low();
ctx.delay.delay_millis(1);
ctx.io3.set_high();
ctx.test_gpio2.set_high();
ctx.delay.delay_millis(1);
ctx.io3.set_low();
ctx.test_gpio2.set_low();
ctx.delay.delay_millis(1);
ctx.io3.set_high();
ctx.test_gpio2.set_high();
ctx.delay.delay_millis(1);
ctx.io3.set_low();
ctx.test_gpio2.set_low();
ctx.delay.delay_millis(1);
ctx.io3.set_high();
ctx.test_gpio2.set_high();
ctx.delay.delay_millis(1);
ctx.io3.set_low();
ctx.test_gpio2.set_low();
ctx.delay.delay_millis(1);
ctx.io3.set_high();
ctx.test_gpio2.set_high();
ctx.delay.delay_millis(1);
let count = critical_section::with(|cs| *COUNTER.borrow_ref(cs));
assert_eq!(count, 9);
ctx.io2 = critical_section::with(|cs| INPUT_PIN.borrow_ref_mut(cs).take().unwrap());
ctx.io2.unlisten();
ctx.test_gpio1 = critical_section::with(|cs| INPUT_PIN.borrow_ref_mut(cs).take().unwrap());
ctx.test_gpio1.unlisten();
}
#[test]
fn test_gpio_od(ctx: Context<'static>) {
let mut io2 = OutputOpenDrain::new(unsafe { GpioPin::<2>::steal() }, Level::High, Pull::Up);
let mut io3 = OutputOpenDrain::new(unsafe { GpioPin::<3>::steal() }, Level::High, Pull::Up);
let mut test_gpio1 =
OutputOpenDrain::new(unsafe { TestGpio1::steal() }, Level::High, Pull::Up);
let mut test_gpio2 =
OutputOpenDrain::new(unsafe { TestGpio2::steal() }, Level::High, Pull::Up);
ctx.delay.delay_millis(1);
assert_eq!(io2.is_high(), true);
assert_eq!(io3.is_high(), true);
assert_eq!(test_gpio1.is_high(), true);
assert_eq!(test_gpio2.is_high(), true);
io2.set_low();
io3.set_high();
test_gpio1.set_low();
test_gpio2.set_high();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_low(), true);
assert_eq!(io3.is_low(), true);
assert_eq!(test_gpio1.is_low(), true);
assert_eq!(test_gpio2.is_low(), true);
io2.set_high();
io3.set_high();
test_gpio1.set_high();
test_gpio2.set_high();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_high(), true);
assert_eq!(io3.is_high(), true);
assert_eq!(test_gpio1.is_high(), true);
assert_eq!(test_gpio2.is_high(), true);
io2.set_high();
io3.set_low();
test_gpio1.set_high();
test_gpio2.set_low();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_low(), true);
assert_eq!(io3.is_low(), true);
assert_eq!(test_gpio1.is_low(), true);
assert_eq!(test_gpio2.is_low(), true);
io2.set_high();
io3.set_high();
test_gpio1.set_high();
test_gpio2.set_high();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_high(), true);
assert_eq!(io3.is_high(), true);
assert_eq!(test_gpio1.is_high(), true);
assert_eq!(test_gpio2.is_high(), true);
io2.set_low();
io3.set_low();
test_gpio1.set_low();
test_gpio2.set_low();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_low(), true);
assert_eq!(io3.is_low(), true);
assert_eq!(test_gpio1.is_low(), true);
assert_eq!(test_gpio2.is_low(), true);
}
#[test]
fn test_gpio_flex(ctx: Context<'static>) {
let mut io2 = Flex::new(unsafe { GpioPin::<2>::steal() });
let mut io3 = Flex::new(unsafe { GpioPin::<3>::steal() });
let mut test_gpio1 = Flex::new(unsafe { TestGpio1::steal() });
let mut test_gpio2 = Flex::new(unsafe { TestGpio2::steal() });
io2.set_high();
io2.set_as_output();
io3.set_as_input(Pull::None);
test_gpio1.set_high();
test_gpio1.set_as_output();
test_gpio2.set_as_input(Pull::None);
ctx.delay.delay_millis(1);
assert_eq!(io2.is_set_high(), true);
assert_eq!(io3.is_high(), true);
assert_eq!(test_gpio1.is_set_high(), true);
assert_eq!(test_gpio2.is_high(), true);
io2.set_low();
test_gpio1.set_low();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_set_high(), false);
assert_eq!(io3.is_high(), false);
assert_eq!(test_gpio1.is_set_high(), false);
assert_eq!(test_gpio2.is_high(), false);
io2.set_as_input(Pull::None);
io3.set_as_output();
test_gpio1.set_as_input(Pull::None);
test_gpio2.set_as_output();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_high(), false);
assert_eq!(io3.is_set_high(), false);
assert_eq!(test_gpio1.is_high(), false);
assert_eq!(test_gpio2.is_set_high(), false);
io3.set_high();
test_gpio2.set_high();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_high(), true);
assert_eq!(io3.is_set_high(), true);
assert_eq!(test_gpio1.is_high(), true);
assert_eq!(test_gpio2.is_set_high(), true);
io3.set_low();
test_gpio2.set_low();
ctx.delay.delay_millis(1);
assert_eq!(io2.is_low(), true);
assert_eq!(io3.is_set_low(), true);
assert_eq!(test_gpio1.is_low(), true);
assert_eq!(test_gpio2.is_set_low(), true);
}
// Tests touch pin (GPIO2) as AnyPin and Output
// https://github.com/esp-rs/esp-hal/issues/1943
#[test]
fn test_gpio_touch_anypin_output() {
let any_pin2 = AnyPin::new(unsafe { GpioPin::<2>::steal() });
let any_pin3 = AnyPin::new(unsafe { GpioPin::<3>::steal() });
let any_pin2 = AnyPin::new(unsafe { TestGpio1::steal() });
let any_pin3 = AnyPin::new(unsafe { TestGpio2::steal() });
let out_pin = Output::new(any_pin2, Level::High);
let in_pin = Input::new(any_pin3, Pull::Down);
@ -272,8 +289,8 @@ mod tests {
// https://github.com/esp-rs/esp-hal/issues/1943
#[test]
fn test_gpio_touch_anypin_input() {
let any_pin2 = AnyPin::new(unsafe { GpioPin::<2>::steal() });
let any_pin3 = AnyPin::new(unsafe { GpioPin::<3>::steal() });
let any_pin2 = AnyPin::new(unsafe { TestGpio1::steal() });
let any_pin3 = AnyPin::new(unsafe { TestGpio2::steal() });
let out_pin = Output::new(any_pin3, Level::Low);
let in_pin = Input::new(any_pin2, Pull::Down);

55
hil-test/tests/i2c.rs Normal file
View File

@ -0,0 +1,55 @@
//! I2C test
//!
//! Folowing pins are used:
//! SDA GPIO2 (esp32s2 and esp32s3)
//! GPIO6 (esp32c6)
//! GPIO18 (esp32c2)
//! GPIO4 (esp32, esp32h2 and esp32c3)
//!
//! SCL GPIO3 (esp32s2 and esp32s3)
//! GPIO7 (esp32c6, esp32 and esp32c3)
//! GPIO22 (esp32h2)
//! GPIO19 (esp32c2)
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
#![no_std]
#![no_main]
use esp_hal::{gpio::Io, i2c::I2C, peripherals::I2C0, prelude::*, Blocking};
use hil_test as _;
struct Context {
i2c: I2C<'static, I2C0, Blocking>,
}
#[cfg(test)]
#[embedded_test::tests]
mod tests {
use defmt::assert_ne;
use super::*;
#[init]
fn init() -> Context {
let (peripherals, clocks) = esp_hal::init(esp_hal::Config::default());
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (sda, scl) = hil_test::i2c_pins!(io);
// Create a new peripheral object with the described wiring and standard
// I2C clock speed:
let i2c = I2C::new(peripherals.I2C0, sda, scl, 100.kHz(), &clocks);
Context { i2c }
}
#[test]
#[timeout(3)]
fn test_read_cali(mut ctx: Context) {
let mut read_data = [0u8; 22];
ctx.i2c.write_read(0x77, &[0xaa], &mut read_data).ok();
assert_ne!(read_data, [0u8; 22])
}
}

View File

@ -1,6 +1,7 @@
//! I2S Loopback Test
//!
//! It's assumed GPIO2 is connected to GPIO3
//! (GPIO9 and GPIO10 for esp32s3)
//!
//! This test uses I2S TX to transmit known data to I2S RX (forced to slave mode
//! with loopback mode enabled). It's using circular DMA mode
@ -78,18 +79,20 @@ mod tests {
&clocks,
);
let (dout, din) = hil_test::common_test_pins!(io);
let mut i2s_tx = i2s
.i2s_tx
.with_bclk(unsafe { io.pins.gpio0.clone_unchecked() })
.with_ws(unsafe { io.pins.gpio1.clone_unchecked() })
.with_dout(unsafe { io.pins.gpio2.clone_unchecked() })
.with_dout(dout)
.build();
let mut i2s_rx = i2s
.i2s_rx
.with_bclk(io.pins.gpio0)
.with_ws(io.pins.gpio1)
.with_din(io.pins.gpio3)
.with_din(din)
.build();
// enable loopback testing

View File

@ -1,6 +1,7 @@
//! I2S Loopback Test (Async)
//!
//! It's assumed GPIO2 is connected to GPIO3
//! (GPIO9 and GPIO10 for esp32s3)
//!
//! This test uses I2S TX to transmit known data to I2S RX (forced to slave mode
//! with loopback mode enabled). It's using circular DMA mode
@ -109,18 +110,20 @@ mod tests {
&clocks,
);
let (dout, din) = hil_test::common_test_pins!(io);
let i2s_tx = i2s
.i2s_tx
.with_bclk(unsafe { io.pins.gpio0.clone_unchecked() })
.with_ws(unsafe { io.pins.gpio1.clone_unchecked() })
.with_dout(io.pins.gpio2)
.with_dout(dout)
.build();
let i2s_rx = i2s
.i2s_rx
.with_bclk(io.pins.gpio0)
.with_ws(io.pins.gpio1)
.with_din(io.pins.gpio3)
.with_din(din)
.build();
// enable loopback testing

View File

@ -1,6 +1,7 @@
//! PCNT tests
//!
//! It's assumed GPIO2 is connected to GPIO3
//! (GPIO9 and GPIO10 for esp32s2 and esp32s3)
//% CHIPS: esp32 esp32c6 esp32h2 esp32s2 esp32s3
@ -9,7 +10,7 @@
use esp_hal::{
delay::Delay,
gpio::{GpioPin, Io, Level, Output, Pull},
gpio::{AnyPin, Io, Level, Output, Pull},
pcnt::{
channel::{EdgeMode, PcntInputConfig, PcntSource},
Pcnt,
@ -19,8 +20,8 @@ use hil_test as _;
struct Context<'d> {
pcnt: Pcnt<'d>,
gpio2: GpioPin<2>,
gpio3: GpioPin<3>,
input: AnyPin<'d>,
output: AnyPin<'d>,
delay: Delay,
}
@ -35,10 +36,15 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (din, dout) = hil_test::common_test_pins!(io);
let din = AnyPin::new(din);
let dout = AnyPin::new(dout);
Context {
pcnt: Pcnt::new(peripherals.PCNT),
gpio2: io.pins.gpio2,
gpio3: io.pins.gpio3,
input: din,
output: dout,
delay: Delay::new(&clocks),
}
}
@ -49,13 +55,13 @@ mod tests {
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
unit.channel0.set_edge_signal(PcntSource::from_pin(
ctx.gpio2,
ctx.input,
PcntInputConfig { pull: Pull::Down },
));
unit.channel0
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
let mut output = Output::new(ctx.gpio3, Level::Low);
let mut output = Output::new(ctx.output, Level::Low);
unit.resume();
@ -88,13 +94,13 @@ mod tests {
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
unit.channel0.set_edge_signal(PcntSource::from_pin(
ctx.gpio2,
ctx.input,
PcntInputConfig { pull: Pull::Up },
));
unit.channel0
.set_input_mode(EdgeMode::Increment, EdgeMode::Hold);
let mut output = Output::new(ctx.gpio3, Level::High);
let mut output = Output::new(ctx.output, Level::High);
unit.resume();
@ -129,13 +135,13 @@ mod tests {
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
unit.channel0.set_edge_signal(PcntSource::from_pin(
ctx.gpio2,
ctx.input,
PcntInputConfig { pull: Pull::Up },
));
unit.channel0
.set_input_mode(EdgeMode::Increment, EdgeMode::Hold);
let mut output = Output::new(ctx.gpio3, Level::High);
let mut output = Output::new(ctx.output, Level::High);
unit.resume();
@ -192,13 +198,13 @@ mod tests {
// Setup channel 0 to increment the count when gpio2 does LOW -> HIGH
unit.channel0.set_edge_signal(PcntSource::from_pin(
ctx.gpio2,
ctx.input,
PcntInputConfig { pull: Pull::Up },
));
unit.channel0
.set_input_mode(EdgeMode::Increment, EdgeMode::Hold);
let mut output = Output::new(ctx.gpio3, Level::High);
let mut output = Output::new(ctx.output, Level::High);
unit.resume();
@ -259,13 +265,13 @@ mod tests {
// Setup channel 0 to decrement the count when gpio2 does LOW -> HIGH
unit.channel0.set_edge_signal(PcntSource::from_pin(
ctx.gpio2,
ctx.input,
PcntInputConfig { pull: Pull::Up },
));
unit.channel0
.set_input_mode(EdgeMode::Decrement, EdgeMode::Hold);
let mut output = Output::new(ctx.gpio3, Level::High);
let mut output = Output::new(ctx.output, Level::High);
unit.resume();
@ -317,13 +323,13 @@ mod tests {
// Setup channel 1 to increment the count when gpio2 does LOW -> HIGH
unit.channel1.set_edge_signal(PcntSource::from_pin(
ctx.gpio2,
ctx.input,
PcntInputConfig { pull: Pull::Up },
));
unit.channel1
.set_input_mode(EdgeMode::Increment, EdgeMode::Hold);
let mut output = Output::new(ctx.gpio3, Level::High);
let mut output = Output::new(ctx.output, Level::High);
unit.resume();

View File

@ -1,11 +1,11 @@
//! QSPI Read Test
//!
//! Following pins are used:
//! MISO GPIO2
//! MISO GPIO2 / GPIO9 (esp32s2 and esp32s3)
//!
//! GPIO GPIO3
//! GPIO GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect MISO (GPIO2) and GPIO (GPIO3) pins.
//! Connect MISO and GPIO pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -16,7 +16,7 @@ use esp_hal::{
clock::Clocks,
dma::{Channel, Dma, DmaPriority, DmaRxBuf},
dma_buffers,
gpio::{GpioPin, Io, Level, Output},
gpio::{AnyOutput, AnyPin, Io, Level},
prelude::*,
spi::{
master::{Address, Command, Spi, SpiDma},
@ -42,14 +42,14 @@ cfg_if::cfg_if! {
struct Context {
spi: esp_hal::peripherals::SPI2,
dma_channel: Channel<'static, DmaChannel0, Blocking>,
miso: esp_hal::gpio::GpioPin<2>,
miso_mirror: Output<'static, GpioPin<3>>,
miso: AnyPin<'static>,
miso_mirror: AnyOutput<'static>,
clocks: Clocks<'static>,
}
fn execute(
mut spi: SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
mut miso_mirror: Output<'static, GpioPin<3>>,
mut miso_mirror: AnyOutput<'static>,
wanted: u8,
) {
const DMA_BUFFER_SIZE: usize = 4;
@ -102,9 +102,11 @@ mod tests {
let (peripherals, clocks) = esp_hal::init(esp_hal::Config::default());
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let miso = io.pins.gpio2;
let miso_mirror = Output::new(io.pins.gpio3, Level::High);
let (miso, miso_mirror) = hil_test::common_test_pins!(io);
let miso = AnyPin::new(miso);
let miso_mirror = AnyOutput::new(miso_mirror, Level::High);
let dma = Dma::new(peripherals.DMA);

View File

@ -3,11 +3,11 @@
//! This uses PCNT to count the edges of the MOSI signal
//!
//! Following pins are used:
//! MOSI GPIO2
//! MOSI GPIO2 / GPIO9 (esp32s2 and esp32s3)
//!
//! PCNT GPIO3
//! PCNT GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect MOSI (GPIO2) and PCNT (GPIO3) pins.
//! Connect MOSI and PCNT pins.
//% CHIPS: esp32 esp32c6 esp32h2 esp32s2 esp32s3
@ -18,7 +18,7 @@ use esp_hal::{
clock::Clocks,
dma::{Channel, Dma, DmaPriority, DmaTxBuf},
dma_buffers,
gpio::{Io, Pull},
gpio::{AnyPin, Io, Pull},
pcnt::{
channel::{EdgeMode, PcntInputConfig, PcntSource},
unit::Unit,
@ -50,8 +50,8 @@ struct Context {
spi: esp_hal::peripherals::SPI2,
pcnt: esp_hal::peripherals::PCNT,
dma_channel: Channel<'static, DmaChannel0, Blocking>,
mosi: esp_hal::gpio::GpioPin<2>,
mosi_mirror: esp_hal::gpio::GpioPin<3>,
mosi: AnyPin<'static>,
mosi_mirror: AnyPin<'static>,
clocks: Clocks<'static>,
}
@ -113,8 +113,11 @@ mod tests {
let (peripherals, clocks) = esp_hal::init(esp_hal::Config::default());
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let mosi = io.pins.gpio2;
let mosi_mirror = io.pins.gpio3;
let (mosi, mosi_mirror) = hil_test::common_test_pins!(io);
let mosi = AnyPin::new(mosi);
let mosi_mirror = AnyPin::new(mosi_mirror);
let dma = Dma::new(peripherals.DMA);

View File

@ -3,11 +3,11 @@
//! Make sure issue #1860 doesn't affect us
//!
//! Following pins are used:
//! MOSI/MISO GPIO2
//! MOSI/MISO GPIO2 / GPIO9 (esp32s2 and esp32s3)
//!
//! GPIO GPIO3
//! GPIO GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect MOSI/MISO (GPIO2) and GPIO (GPIO3) pins.
//! Connect MOSI/MISO and GPIO pins.
//% CHIPS: esp32 esp32c6 esp32h2 esp32s2 esp32s3
@ -18,7 +18,7 @@ use esp_hal::{
clock::Clocks,
dma::{Channel, Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::{GpioPin, Io, Level, Output},
gpio::{AnyOutput, AnyPin, Io, Level},
prelude::*,
spi::{
master::{Address, Command, Spi, SpiDma},
@ -44,14 +44,14 @@ cfg_if::cfg_if! {
struct Context {
spi: esp_hal::peripherals::SPI2,
dma_channel: Channel<'static, DmaChannel0, Blocking>,
mosi: esp_hal::gpio::GpioPin<2>,
mosi_mirror: Output<'static, GpioPin<3>>,
mosi: AnyPin<'static>,
mosi_mirror: AnyOutput<'static>,
clocks: Clocks<'static>,
}
fn execute(
mut spi: SpiDma<'static, esp_hal::peripherals::SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
mut mosi_mirror: Output<'static, GpioPin<3>>,
mut mosi_mirror: AnyOutput<'static>,
wanted: u8,
) {
const DMA_BUFFER_SIZE: usize = 4;
@ -104,8 +104,11 @@ mod tests {
let (peripherals, clocks) = esp_hal::init(esp_hal::Config::default());
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let mosi = io.pins.gpio2;
let mosi_mirror = Output::new(io.pins.gpio3, Level::High);
let (mosi, mosi_mirror) = hil_test::common_test_pins!(io);
let mosi = AnyPin::new(mosi);
let mosi_mirror = AnyOutput::new(mosi_mirror, Level::High);
let dma = Dma::new(peripherals.DMA);

View File

@ -1,6 +1,7 @@
//! RMT Loopback Test
//!
//! It's assumed GPIO2 is connected to GPIO3
//! (GPIO9 and GPIO10 for esp32s2 and esp32s3)
//% CHIPS: esp32 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -39,6 +40,8 @@ mod tests {
let rmt = Rmt::new(peripherals.RMT, freq, &clocks).unwrap();
let (tx, rx) = hil_test::common_test_pins!(io);
let tx_config = TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
@ -46,7 +49,7 @@ mod tests {
let tx_channel = {
use esp_hal::rmt::TxChannelCreator;
rmt.channel0.configure(io.pins.gpio2, tx_config).unwrap()
rmt.channel0.configure(tx, tx_config).unwrap()
};
let rx_config = RxChannelConfig {
@ -59,17 +62,17 @@ mod tests {
if #[cfg(any(feature = "esp32", feature = "esp32s2"))] {
let rx_channel = {
use esp_hal::rmt::RxChannelCreator;
rmt.channel1.configure(io.pins.gpio3, rx_config).unwrap()
rmt.channel1.configure(rx, rx_config).unwrap()
};
} else if #[cfg(feature = "esp32s3")] {
let rx_channel = {
use esp_hal::rmt::RxChannelCreator;
rmt.channel7.configure(io.pins.gpio3, rx_config).unwrap()
rmt.channel7.configure(rx, rx_config).unwrap()
};
} else {
let rx_channel = {
use esp_hal::rmt::RxChannelCreator;
rmt.channel2.configure(io.pins.gpio3, rx_config).unwrap()
rmt.channel2.configure(rx, rx_config).unwrap()
};
}
}

View File

@ -2,11 +2,11 @@
//!
//! Folowing pins are used:
//! SCLK GPIO0
//! MISO GPIO2
//! MOSI GPIO3
//! MISO GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! MOSI GPIO3 / GPIO10 (esp32s2 and esp32s3)
//! CS GPIO8
//!
//! Connect MISO (GPIO2) and MOSI (GPIO3) pins.
//! Connect MISO and MOSI pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -38,8 +38,7 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio0;
let miso = io.pins.gpio2;
let mosi = io.pins.gpio3;
let (miso, mosi) = hil_test::common_test_pins!(io);
let cs = io.pins.gpio8;
let spi = Spi::new(peripherals.SPI2, 1000u32.kHz(), SpiMode::Mode0, &clocks).with_pins(

View File

@ -2,11 +2,11 @@
//!
//! Folowing pins are used:
//! SCLK GPIO0
//! MISO GPIO2
//! MOSI GPIO3
//! MISO GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! MOSI GPIO3 / GPIO10 (esp32s2 and esp32s3)
//! CS GPIO8
//!
//! Connect MISO (GPIO2) and MOSI (GPIO3) pins.
//! Connect MISO and MOSI pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -56,8 +56,7 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio0;
let mosi = io.pins.gpio3;
let miso = io.pins.gpio2;
let (miso, mosi) = hil_test::common_test_pins!(io);
let cs = io.pins.gpio8;
let dma = Dma::new(peripherals.DMA);

View File

@ -2,17 +2,17 @@
//!
//! Following pins are used:
//! SCLK GPIO0
//! MOSI GPIO3
//! MISO GPIO6
//! MOSI GPIO3 / GPIO10 (esp32s3)
//! MISO GPIO4
//! CS GPIO8
//!
//! PCNT GPIO2
//! PCNT GPIO2 / GPIO9 (esp32s3)
//! OUTPUT GPIO5 (helper to keep MISO LOW)
//!
//! The idea of using PCNT (input) here is to connect MOSI to it and count the
//! edges of whatever SPI writes (in this test case 3 pos edges).
//!
//! Connect PCNT (GPIO2) and MOSI (GPIO3) and MISO (GPIO6) and GPIO5 pins.
//! Connect PCNT and MOSI, MISO and GPIO5 pins.
//% CHIPS: esp32 esp32c6 esp32h2 esp32s3
//% FEATURES: generic-queue
@ -24,7 +24,7 @@ use embedded_hal_async::spi::SpiBus;
use esp_hal::{
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::{GpioPin, Io, Level, Output, Pull},
gpio::{AnyPin, GpioPin, Io, Level, Output, Pull},
pcnt::{
channel::{EdgeMode, PcntInputConfig, PcntSource},
unit::Unit,
@ -58,7 +58,7 @@ struct Context {
spi: SpiDmaBus<'static, SPI2, DmaChannel0, FullDuplexMode, Async>,
pcnt_unit: Unit<'static, 0>,
out_pin: Output<'static, GpioPin<5>>,
mosi_mirror: GpioPin<2>,
mosi_mirror: AnyPin<'static>,
}
#[cfg(test)]
@ -75,10 +75,11 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let pcnt = Pcnt::new(peripherals.PCNT);
let sclk = io.pins.gpio0;
let mosi_mirror = io.pins.gpio2;
let mosi = io.pins.gpio3;
let miso = io.pins.gpio6;
let (mosi_mirror, mosi) = hil_test::common_test_pins!(io);
let miso = io.pins.gpio4;
let cs = io.pins.gpio8;
let mosi_mirror = AnyPin::new(mosi_mirror);
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
out_pin.set_low();

View File

@ -2,15 +2,15 @@
//!
//! Folowing pins are used:
//! SCLK GPIO0
//! MOSI GPIO3
//! MOSI GPIO3 / GPIO10 (esp32s3)
//! CS GPIO8
//! PCNT GPIO2
//! PCNT GPIO2 / GPIO9 (esp32s3)
//! OUTPUT GPIO5 (helper to keep MISO LOW)
//!
//! The idea of using PCNT (input) here is to connect MOSI to it and count the
//! edges of whatever SPI writes (in this test case 3 pos edges).
//!
//! Connect MISO (GPIO2) and MOSI (GPIO3) pins.
//! Connect MISO and MOSI pins.
//% CHIPS: esp32 esp32c6 esp32h2 esp32s3
@ -20,7 +20,7 @@
use esp_hal::{
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::{GpioPin, Io, Level, Output, Pull},
gpio::{AnyPin, GpioPin, Io, Level, Output, Pull},
pcnt::{
channel::{EdgeMode, PcntInputConfig, PcntSource},
unit::Unit,
@ -52,7 +52,7 @@ struct Context {
spi: SpiDma<'static, SPI2, DmaChannel0, FullDuplexMode, Blocking>,
pcnt_unit: Unit<'static, 0>,
out_pin: Output<'static, GpioPin<5>>,
mosi_mirror: GpioPin<2>,
mosi_mirror: AnyPin<'static>,
}
#[cfg(test)]
@ -68,8 +68,8 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio0;
let mosi = io.pins.gpio3;
let miso = io.pins.gpio6;
let (mosi_mirror, mosi) = hil_test::common_test_pins!(io);
let miso = io.pins.gpio4;
let cs = io.pins.gpio8;
let dma = Dma::new(peripherals.DMA);
@ -91,7 +91,7 @@ mod tests {
let mut out_pin = Output::new(io.pins.gpio5, Level::Low);
out_pin.set_low();
assert_eq!(out_pin.is_set_low(), true);
let mosi_mirror = io.pins.gpio2;
let mosi_mirror = AnyPin::new(mosi_mirror);
Context {
spi,

View File

@ -2,11 +2,11 @@
//!
//! Folowing pins are used:
//! SCLK GPIO0
//! MISO GPIO2
//! MISO GPIO2 / GPIO9 (esp32s2 and esp32s3)
//!
//! GPIO GPIO3
//! GPIO GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect MISO (GPIO2) and GPIO (GPIO3) pins.
//! Connect MISO and GPIO pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -16,7 +16,7 @@
use esp_hal::{
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::{GpioPin, Io, Level, Output},
gpio::{AnyOutput, Io, Level},
peripherals::SPI2,
prelude::*,
spi::{
@ -42,7 +42,7 @@ cfg_if::cfg_if! {
struct Context {
spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
miso_mirror: Output<'static, GpioPin<3>>,
miso_mirror: AnyOutput<'static>,
}
#[cfg(test)]
@ -58,9 +58,9 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio0;
let miso = io.pins.gpio2;
let (miso, miso_mirror) = hil_test::common_test_pins!(io);
let miso_mirror = Output::new(io.pins.gpio3, Level::High);
let miso_mirror = AnyOutput::new(miso_mirror, Level::High);
let dma = Dma::new(peripherals.DMA);

View File

@ -2,11 +2,11 @@
//!
//! Following pins are used:
//! SCLK GPIO0
//! MOSI GPIO2
//! MOSI GPIO2 / GPIO9 (esp32s2 and esp32s3)
//!
//! PCNT GPIO3
//! PCNT GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect MOSI (GPIO2) and PCNT (GPIO3) pins.
//! Connect MOSI and PCNT pins.
//% CHIPS: esp32 esp32c6 esp32h2 esp32s2 esp32s3
@ -16,7 +16,7 @@
use esp_hal::{
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::{GpioPin, Io, Pull},
gpio::{AnyPin, Io, Pull},
pcnt::{
channel::{EdgeMode, PcntInputConfig, PcntSource},
unit::Unit,
@ -48,7 +48,7 @@ cfg_if::cfg_if! {
struct Context {
spi: SpiDma<'static, SPI2, DmaChannel0, HalfDuplexMode, Blocking>,
pcnt_unit: Unit<'static, 0>,
mosi_mirror: GpioPin<3>,
mosi_mirror: AnyPin<'static>,
}
#[cfg(test)]
@ -67,8 +67,9 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio0;
let mosi = io.pins.gpio2;
let mosi_mirror = io.pins.gpio3;
let (mosi, mosi_mirror) = hil_test::common_test_pins!(io);
let mosi_mirror = AnyPin::new(mosi_mirror);
let pcnt = Pcnt::new(peripherals.PCNT);
let dma = Dma::new(peripherals.DMA);

View File

@ -1,10 +1,10 @@
//! TWAI test
//!
//! Folowing pins are used:
//! TX GPIO2
//! RX GPIO3
//! TX GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! RX GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//! Connect TX and RX pins.
//% CHIPS: esp32c3 esp32c6 esp32s2 esp32s3
@ -39,8 +39,7 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let can_tx_pin = io.pins.gpio2;
let can_rx_pin = io.pins.gpio3;
let (can_tx_pin, can_rx_pin) = hil_test::common_test_pins!(io);
let mut config = twai::TwaiConfiguration::new(
peripherals.TWAI0,

View File

@ -1,10 +1,10 @@
//! UART Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO3
//! TX GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! RX GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//! Connect TX and RX pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -41,7 +41,9 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let uart = Uart::new(peripherals.UART1, &clocks, io.pins.gpio2, io.pins.gpio3).unwrap();
let (tx, rx) = hil_test::common_test_pins!(io);
let uart = Uart::new(peripherals.UART1, &clocks, tx, rx).unwrap();
Context { clocks, uart }
}

View File

@ -1,10 +1,10 @@
//! UART Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO3
//! TX GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! RX GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//! Connect TX and RX pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: generic-queue
@ -32,8 +32,9 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let uart =
Uart::new_async(peripherals.UART0, &clocks, io.pins.gpio2, io.pins.gpio3).unwrap();
let (tx, rx) = hil_test::common_test_pins!(io);
let uart = Uart::new_async(peripherals.UART0, &clocks, tx, rx).unwrap();
Context { uart }
}

View File

@ -1,10 +1,10 @@
//! UART TX/RX Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO3
//! TX GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! RX GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//! Connect TX and RX pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
@ -39,8 +39,10 @@ mod tests {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let tx = UartTx::new(peripherals.UART0, &clocks, io.pins.gpio2).unwrap();
let rx = UartRx::new(peripherals.UART1, &clocks, io.pins.gpio3).unwrap();
let (tx, rx) = hil_test::common_test_pins!(io);
let tx = UartTx::new(peripherals.UART0, &clocks, tx).unwrap();
let rx = UartRx::new(peripherals.UART1, &clocks, rx).unwrap();
Context { tx, rx }
}

View File

@ -1,10 +1,10 @@
//! UART TX/RX Async Test
//!
//! Folowing pins are used:
//! TX GPIP2
//! RX GPIO3
//! TX GPIO2 / GPIO9 (esp32s2 and esp32s3)
//! RX GPIO3 / GPIO10 (esp32s2 and esp32s3)
//!
//! Connect TX (GPIO2) and RX (GPIO3) pins.
//! Connect TX and RX pins.
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% FEATURES: generic-queue
@ -38,8 +38,10 @@ mod tests {
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.gpio3).unwrap();
let (tx, rx) = hil_test::common_test_pins!(io);
let tx = UartTx::new_async(peripherals.UART0, &clocks, tx).unwrap();
let rx = UartRx::new_async(peripherals.UART1, &clocks, rx).unwrap();
Context { tx, rx }
}