#![allow(clippy::transmute_ptr_to_ptr)]
#![deny(warnings)]
#![no_main]
#![no_std]
use core::{mem, mem::MaybeUninit};
use cortex_m_rt::entry;
#[macro_use]
mod utilities;
use stm32h7xx_hal::{pac, pac::DWT, prelude::*};
use stm32h7xx_hal::dma::{
mdma::{MdmaConfig, MdmaIncrement, StreamsTuple},
traits::{Direction, MasterStream, Stream},
MemoryToMemory, Transfer,
};
use log::info;
#[link_section = ".axisram.buffers"]
static mut SOURCE_BUFFER: MaybeUninit<[u32; 200]> = MaybeUninit::uninit();
#[link_section = ".axisram.buffers"]
static mut TARGET_BUFFER: MaybeUninit<[u32; 200]> = MaybeUninit::uninit();
#[entry]
fn main() -> ! {
utilities::logger::init();
let cp = unsafe { cortex_m::Peripherals::steal() };
let dp = pac::Peripherals::take().unwrap();
info!("Setup PWR... ");
let pwr = dp.PWR.constrain();
let pwrcfg = example_power!(pwr).freeze();
info!("Setup RCC... ");
let rcc = dp.RCC.constrain();
let ccdr = rcc
.sys_ck(100.MHz())
.hclk(50.MHz())
.freeze(pwrcfg, &dp.SYSCFG);
let mut dwt = cp.DWT;
dwt.enable_cycle_counter();
info!("");
info!("stm32h7xx-hal example - Master DMA with longer bursts");
info!("");
let _source_buffer: &'static mut [u32; 200] = {
let buf: &mut [MaybeUninit<u32>; 200] =
unsafe { mem::transmute(&mut SOURCE_BUFFER) };
for value in buf.iter_mut() {
unsafe {
value.as_mut_ptr().write(0x11223344u32);
}
}
unsafe { mem::transmute(buf) }
};
let streams = StreamsTuple::new(dp.MDMA, ccdr.peripheral.MDMA);
fn run_mdma_mem2mem<STREAM: MasterStream + Stream<Config = MdmaConfig>>(
n: usize,
m: usize,
stream: STREAM,
config: MdmaConfig,
) {
let mut transfer: Transfer<_, _, MemoryToMemory<u32>, _, _> = {
let source: &'static mut [u32; 200] =
unsafe { mem::transmute(&mut SOURCE_BUFFER) };
let target: &'static mut [u32; 200] =
unsafe { mem::transmute(&mut TARGET_BUFFER) };
Transfer::init_master(
stream,
MemoryToMemory::new(),
target, Some(source), config,
)
};
assert_eq!(transfer.get_block_length(), 800);
assert_eq!(transfer.get_source_burst_length(), m);
assert_eq!(transfer.get_destination_burst_length(), m);
let mut cycles = 0;
for _ in 0..10 {
cycles += {
let start = DWT::cycle_count();
transfer.start(|_| {});
while !transfer.get_transfer_complete_flag() {}
DWT::cycle_count() - start
};
}
let (_stream0, _mem2mem, target_buffer, _source_buffer_opt) =
transfer.free();
for a in target_buffer.iter() {
assert_eq!(*a, 0x11223344);
}
info!(
"Example {}: Memory to Memory, {} beat/burst completed successfully",
n, m
);
info!(
"Cycles: {}, {:.2} cycles/B",
cycles / 10,
cycles as f32 / 8_000.
);
info!("");
}
let config_1beat = MdmaConfig::default()
.destination_increment(MdmaIncrement::Increment)
.source_increment(MdmaIncrement::Increment);
run_mdma_mem2mem(1, 1, streams.0, config_1beat);
let config_32beat = config_1beat
.destination_burst_size(32)
.source_burst_size(32);
run_mdma_mem2mem(2, 32, streams.1, config_32beat);
let config_16beat = config_32beat.buffer_length(16);
run_mdma_mem2mem(3, 16, streams.2, config_16beat);
loop {
cortex_m::asm::nop()
}
}