Test more embassy interrupt spi dma (#2490)

* Add C3,C6 and H2 for `embassy_interrupt_spi_dma`

* Test more

* Don't require physically connected pins
This commit is contained in:
Björn Quentin 2024-11-08 14:43:34 +01:00 committed by GitHub
parent 50d8187e39
commit 3c4b7f0f66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,6 +1,6 @@
//! Reproduction and regression test for a sneaky issue. //! Reproduction and regression test for a sneaky issue.
//% CHIPS: esp32 esp32s2 esp32s3 //% CHIPS: esp32 esp32s2 esp32s3 esp32c3 esp32c6 esp32h2
//% FEATURES: integrated-timers //% FEATURES: integrated-timers
//% FEATURES: generic-queue //% FEATURES: generic-queue
@ -11,10 +11,12 @@ use embassy_time::{Duration, Instant, Ticker};
use esp_hal::{ use esp_hal::{
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf}, dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
dma_buffers, dma_buffers,
gpio::Io,
interrupt::{software::SoftwareInterruptControl, Priority}, interrupt::{software::SoftwareInterruptControl, Priority},
peripheral::Peripheral,
prelude::*, prelude::*,
spi::{ spi::{
master::{Config, Spi, SpiDma}, master::{Config, Spi},
SpiMode, SpiMode,
}, },
timer::AnyTimer, timer::AnyTimer,
@ -22,6 +24,7 @@ use esp_hal::{
}; };
use esp_hal_embassy::InterruptExecutor; use esp_hal_embassy::InterruptExecutor;
use hil_test as _; use hil_test as _;
use portable_atomic::AtomicBool;
macro_rules! mk_static { macro_rules! mk_static {
($t:ty,$val:expr) => {{ ($t:ty,$val:expr) => {{
@ -32,8 +35,11 @@ macro_rules! mk_static {
}}; }};
} }
static INTERRUPT_TASK_WORKING: AtomicBool = AtomicBool::new(false);
#[cfg(any(esp32, esp32s2, esp32s3))]
#[embassy_executor::task] #[embassy_executor::task]
async fn interrupt_driven_task(spi: SpiDma<'static, Async>) { async fn interrupt_driven_task(spi: esp_hal::spi::master::SpiDma<'static, Async>) {
let mut ticker = Ticker::every(Duration::from_millis(1)); let mut ticker = Ticker::every(Duration::from_millis(1));
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(128); let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(128);
@ -45,7 +51,25 @@ async fn interrupt_driven_task(spi: SpiDma<'static, Async>) {
loop { loop {
let mut buffer: [u8; 8] = [0; 8]; let mut buffer: [u8; 8] = [0; 8];
INTERRUPT_TASK_WORKING.fetch_not(portable_atomic::Ordering::Release);
spi.transfer_in_place_async(&mut buffer).await.unwrap(); spi.transfer_in_place_async(&mut buffer).await.unwrap();
INTERRUPT_TASK_WORKING.fetch_not(portable_atomic::Ordering::Acquire);
ticker.next().await;
}
}
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
#[embassy_executor::task]
async fn interrupt_driven_task(mut i2s_tx: esp_hal::i2s::master::I2sTx<'static, Async>) {
let mut ticker = Ticker::every(Duration::from_millis(1));
loop {
let mut buffer: [u8; 8] = [0; 8];
INTERRUPT_TASK_WORKING.fetch_not(portable_atomic::Ordering::Release);
i2s_tx.write_dma_async(&mut buffer).await.unwrap();
INTERRUPT_TASK_WORKING.fetch_not(portable_atomic::Ordering::Acquire);
ticker.next().await; ticker.next().await;
} }
@ -94,6 +118,9 @@ mod test {
let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap(); let dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap(); let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (_, mosi) = hil_test::common_test_pins!(io);
let mut spi = Spi::new_with_config( let mut spi = Spi::new_with_config(
peripherals.SPI2, peripherals.SPI2,
Config { Config {
@ -102,11 +129,14 @@ mod test {
..Config::default() ..Config::default()
}, },
) )
.with_miso(unsafe { mosi.clone_unchecked() })
.with_mosi(mosi)
.with_dma(dma_channel1.configure(false, DmaPriority::Priority0)) .with_dma(dma_channel1.configure(false, DmaPriority::Priority0))
.with_buffers(dma_rx_buf, dma_tx_buf) .with_buffers(dma_rx_buf, dma_tx_buf)
.into_async(); .into_async();
let spi2 = Spi::new_with_config( #[cfg(any(esp32, esp32s2, esp32s3))]
let other_peripheral = Spi::new_with_config(
peripherals.SPI3, peripherals.SPI3,
Config { Config {
frequency: 100.kHz(), frequency: 100.kHz(),
@ -117,6 +147,26 @@ mod test {
.with_dma(dma_channel2.configure(false, DmaPriority::Priority0)) .with_dma(dma_channel2.configure(false, DmaPriority::Priority0))
.into_async(); .into_async();
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
let other_peripheral = {
let (_, rx_descriptors, _, tx_descriptors) = dma_buffers!(128);
let other_peripheral = esp_hal::i2s::master::I2s::new(
peripherals.I2S0,
esp_hal::i2s::master::Standard::Philips,
esp_hal::i2s::master::DataFormat::Data8Channel8,
8u32.kHz(),
dma_channel2.configure(false, DmaPriority::Priority0),
rx_descriptors,
tx_descriptors,
)
.into_async()
.i2s_tx
.build();
other_peripheral
};
let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); let sw_ints = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
let interrupt_executor = mk_static!( let interrupt_executor = mk_static!(
@ -126,16 +176,28 @@ mod test {
let spawner = interrupt_executor.start(Priority::Priority3); let spawner = interrupt_executor.start(Priority::Priority3);
spawner.spawn(interrupt_driven_task(spi2)).unwrap(); spawner
.spawn(interrupt_driven_task(other_peripheral))
.unwrap();
let start = Instant::now(); let start = Instant::now();
let mut buffer: [u8; 1024] = [0; 1024]; let mut buffer: [u8; 1024] = [0; 1024];
let mut dst_buffer: [u8; 1024] = [0; 1024];
let mut i = 0;
loop { loop {
spi.transfer_in_place_async(&mut buffer).await.unwrap(); buffer.fill(i);
dst_buffer.fill(i.wrapping_add(1));
spi.transfer_async(&mut dst_buffer, &buffer).await.unwrap();
// make sure the transfer didn't end prematurely
assert!(dst_buffer.iter().all(|&v| v == i));
if start.elapsed() > Duration::from_secs(1) { if start.elapsed() > Duration::from_secs(1) {
// make sure the other peripheral didn't get stuck
while INTERRUPT_TASK_WORKING.load(portable_atomic::Ordering::Acquire) {}
break; break;
} }
i = i.wrapping_add(1);
} }
} }