esp-hal/examples/src/bin/dma_extmem2mem.rs
Björn Quentin 37fa662fe7
Remove most PSRAM features (#2178)
* Make most of PSRAM features into run-time configs

* Make CI green again

* Make CI green again

* Update esp-hal/MIGRATING-0.20.md

Co-authored-by: Scott Mabin <scott@mabez.dev>

* Use Range

* CI

* Rebase fixes

* Update esp-hal/src/lock.rs

Co-authored-by: Scott Mabin <scott@mabez.dev>

---------

Co-authored-by: Scott Mabin <scott@mabez.dev>
2024-09-20 16:43:25 +00:00

151 lines
4.5 KiB
Rust

//! Uses DMA to copy psram to internal memory.
//% FEATURES: esp-hal/log esp-hal/octal-psram aligned
//% CHIPS: esp32s3
#![no_std]
#![no_main]
use aligned::{Aligned, A64};
use esp_alloc as _;
use esp_backtrace as _;
use esp_hal::{
delay::Delay,
dma::{Dma, DmaPriority, Mem2Mem},
dma_descriptors_chunk_size,
prelude::*,
};
use log::{error, info};
extern crate alloc;
const DATA_SIZE: usize = 1024 * 10;
const CHUNK_SIZE: usize = 4032; // size is aligned to 64 bytes
macro_rules! dma_buffer_aligned {
($size:expr, $align:ty) => {{
static mut BUFFER: Aligned<$align, [u8; $size]> = Aligned([0; $size]);
unsafe { &mut *BUFFER }
}};
}
macro_rules! dma_alloc_buffer {
($size:expr, $align:expr) => {{
let layout = core::alloc::Layout::from_size_align($size, $align).unwrap();
unsafe {
let ptr = alloc::alloc::alloc(layout);
if ptr.is_null() {
error!("make_buffers: alloc failed");
alloc::alloc::handle_alloc_error(layout);
}
core::slice::from_raw_parts_mut(ptr, $size)
}
}};
}
fn init_heap(psram: esp_hal::peripherals::PSRAM) {
let (start, size) = esp_hal::psram::init_psram(psram, esp_hal::psram::PsramConfig::default());
info!("init_heap: start: {:p}", start);
unsafe {
esp_alloc::HEAP.add_region(esp_alloc::HeapRegion::new(
start,
size,
esp_alloc::MemoryCapability::External.into(),
));
}
}
#[entry]
fn main() -> ! {
esp_println::logger::init_logger(log::LevelFilter::Info);
let peripherals = esp_hal::init(esp_hal::Config::default());
init_heap(peripherals.PSRAM);
let delay = Delay::new();
let mut extram_buffer: &mut [u8] = dma_alloc_buffer!(DATA_SIZE, 64);
let mut intram_buffer = dma_buffer_aligned!(DATA_SIZE, A64);
let (rx_descriptors, tx_descriptors) = dma_descriptors_chunk_size!(DATA_SIZE, CHUNK_SIZE);
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
let dma_peripheral = peripherals.SPI2;
let mut mem2mem = Mem2Mem::new_with_chunk_size(
channel,
dma_peripheral,
rx_descriptors,
tx_descriptors,
CHUNK_SIZE,
)
.unwrap();
for i in 0..core::mem::size_of_val(extram_buffer) {
extram_buffer[i] = (i % 256) as u8;
intram_buffer[i] = 255 - extram_buffer[i];
}
info!(" ext2int: Starting transfer of {} bytes", DATA_SIZE);
match mem2mem.start_transfer(&mut intram_buffer, &extram_buffer) {
Ok(dma_wait) => {
info!("Transfer started");
dma_wait.wait().unwrap();
info!("Transfer completed, comparing buffer");
let mut error = false;
for i in 0..core::mem::size_of_val(extram_buffer) {
if intram_buffer[i] != extram_buffer[i] {
error!(
"Error: extram_buffer[{}] = {}, intram_buffer[{}] = {}",
i, extram_buffer[i], i, intram_buffer[i]
);
error = true;
break;
}
}
if !error {
info!("Buffers are equal");
}
info!("Done");
}
Err(e) => {
error!("start_transfer: Error: {:?}", e);
}
}
for i in 0..core::mem::size_of_val(extram_buffer) {
intram_buffer[i] = (i % 256) as u8;
extram_buffer[i] = 255 - intram_buffer[i];
}
info!(" int2ext: Starting transfer of {} bytes", DATA_SIZE);
match mem2mem.start_transfer(&mut extram_buffer, &intram_buffer) {
Ok(dma_wait) => {
info!("Transfer started");
dma_wait.wait().unwrap();
info!("Transfer completed, comparing buffer");
let mut error = false;
for i in 0..core::mem::size_of_val(extram_buffer) {
if intram_buffer[i] != extram_buffer[i] {
error!(
"Error: extram_buffer[{}] = {}, intram_buffer[{}] = {}",
i, extram_buffer[i], i, intram_buffer[i]
);
error = true;
break;
}
}
if !error {
info!("Buffers are equal");
}
info!("Done");
}
Err(e) => {
error!("start_transfer: Error: {:?}", e);
}
}
loop {
delay.delay(2.secs());
}
}