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:
parent
50d8187e39
commit
3c4b7f0f66
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user