esp-hal/hil-test/tests/dma_mem2mem.rs
liebman 1631f22083
support dma chunk sizes other than 4092 (#1758)
* support dma chunk sizes other than 4092

* fmt

* update CHANGELOG

* fix 0 size static assert

* review changes:
- `.div_ceil()`
- return errors for bad chunk size and buffer sizes in Mem2Mem constructors
- correct 0 chunk size check in descripter macros

* dma: clear the mem2mem bit when channel is configured instead of in Drop
2024-07-15 12:00:33 +00:00

204 lines
7.1 KiB
Rust

//! DMA Mem2Mem Tests
//% CHIPS: esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
#![no_std]
#![no_main]
use defmt_rtt as _;
use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
dma::{Dma, DmaError, DmaPriority, Mem2Mem},
dma_buffers,
dma_buffers_chunk_size,
dma_descriptors,
peripherals::Peripherals,
system::SystemControl,
};
const DATA_SIZE: usize = 1024 * 10;
#[cfg(test)]
#[embedded_test::tests]
mod tests {
use defmt::assert_eq;
use super::*;
#[init]
fn init() {}
#[test]
fn test_internal_mem2mem() {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let (tx_buffer, tx_descriptors, mut rx_buffer, rx_descriptors) = dma_buffers!(DATA_SIZE);
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;
let mut mem2mem =
Mem2Mem::new(channel, dma_peripheral, tx_descriptors, rx_descriptors).unwrap();
for i in 0..core::mem::size_of_val(tx_buffer) {
tx_buffer[i] = (i % 256) as u8;
}
let dma_wait = mem2mem.start_transfer(&tx_buffer, &mut rx_buffer).unwrap();
dma_wait.wait().unwrap();
for i in 0..core::mem::size_of_val(tx_buffer) {
assert_eq!(rx_buffer[i], tx_buffer[i]);
}
}
#[test]
fn test_internal_mem2mem_chunk_size() {
const CHUNK_SIZE: usize = 2048;
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let (tx_buffer, tx_descriptors, mut rx_buffer, rx_descriptors) =
dma_buffers_chunk_size!(DATA_SIZE, CHUNK_SIZE);
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;
let mut mem2mem = Mem2Mem::new_with_chunk_size(
channel,
dma_peripheral,
tx_descriptors,
rx_descriptors,
CHUNK_SIZE,
)
.unwrap();
for i in 0..core::mem::size_of_val(tx_buffer) {
tx_buffer[i] = (i % 256) as u8;
}
let dma_wait = mem2mem.start_transfer(&tx_buffer, &mut rx_buffer).unwrap();
dma_wait.wait().unwrap();
for i in 0..core::mem::size_of_val(tx_buffer) {
assert_eq!(rx_buffer[i], tx_buffer[i]);
}
}
#[test]
fn test_mem2mem_errors_zero_tx() {
use esp_hal::dma::CHUNK_SIZE;
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;
let (tx_descriptors, rx_descriptors) = dma_descriptors!(0, 1024);
match Mem2Mem::new_with_chunk_size(
channel,
dma_peripheral,
tx_descriptors,
rx_descriptors,
CHUNK_SIZE,
) {
Err(DmaError::OutOfDescriptors) => (),
_ => panic!("Expected OutOfDescriptors"),
}
}
#[test]
fn test_mem2mem_errors_zero_rx() {
use esp_hal::dma::CHUNK_SIZE;
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;
let (tx_descriptors, rx_descriptors) = dma_descriptors!(1024, 0);
match Mem2Mem::new_with_chunk_size(
channel,
dma_peripheral,
tx_descriptors,
rx_descriptors,
CHUNK_SIZE,
) {
Err(DmaError::OutOfDescriptors) => (),
_ => panic!("Expected OutOfDescriptors"),
}
}
#[test]
fn test_mem2mem_errors_chunk_size_too_small() {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;
let (tx_descriptors, rx_descriptors) = dma_descriptors!(1024, 1024);
match Mem2Mem::new_with_chunk_size(
channel,
dma_peripheral,
tx_descriptors,
rx_descriptors,
0,
) {
Err(DmaError::InvalidChunkSize) => (),
_ => panic!("Expected InvalidChunkSize"),
}
}
#[test]
fn test_mem2mem_errors_chunk_size_too_big() {
let peripherals = Peripherals::take();
let system = SystemControl::new(peripherals.SYSTEM);
let _clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;
let (tx_descriptors, rx_descriptors) = dma_descriptors!(1024, 1024);
match Mem2Mem::new_with_chunk_size(
channel,
dma_peripheral,
tx_descriptors,
rx_descriptors,
4093,
) {
Err(DmaError::InvalidChunkSize) => (),
_ => panic!("Expected InvalidChunkSize"),
}
}
}