Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ defmt = [
cortex-m = { version = "^0.7.7", features = ["critical-section-single-core"] }
stm32h5 = { package = "stm32h5", version = "0.16.0" }
fugit = "0.3.7"
embedded-dma = "0.2"
embedded-hal = "1.0.0"
defmt = { version = "1.0.0", optional = true }
paste = "1.0.15"
Expand Down
113 changes: 113 additions & 0 deletions examples/dma.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// #![deny(warnings)]
#![no_main]
#![no_std]

mod utilities;

use cortex_m_rt::entry;
use cortex_m_semihosting::debug;
use stm32h5xx_hal::{
gpdma::{config::transform::*, DmaConfig, DmaTransfer},
pac,
prelude::*,
};

#[entry]
fn main() -> ! {
utilities::logger::init();

let dp = pac::Peripherals::take().unwrap();

let pwr = dp.PWR.constrain();
let pwrcfg = pwr.vos0().freeze();

// Constrain and Freeze clock
let rcc = dp.RCC.constrain();
let ccdr = rcc.sys_ck(250.MHz()).freeze(pwrcfg, &dp.SBS);

let channels = dp.GPDMA1.channels(ccdr.peripheral.GPDMA1);

// u8 to u8
log::info!("u8 to u8 transfer");
let src: [u8; 40] = core::array::from_fn(|i| i as u8);
let dest = &mut [0u8; 40];

let channel = channels.0;
let config = DmaConfig::new();
let transfer = DmaTransfer::memory_to_memory(config, &channel, &src, dest);
transfer.start().unwrap();
transfer.wait_for_transfer_complete().unwrap();
assert_eq!(src, *dest, "u8 to u8 transfer failed");

// u32 to u32 with data transform
log::info!("u32 to u32 with data transform");
let src = [0x12345678u32; 10];
let dest = &mut [0u32; 10];
let config = DmaConfig::new().with_data_transform(
DataTransform::builder()
.swap_destination_half_words()
.swap_destination_half_word_byte_order(),
);

let transfer = DmaTransfer::memory_to_memory(config, &channel, &src, dest);

transfer.start().unwrap();
transfer.wait_for_transfer_complete().unwrap();
assert_eq!(
[0x78563412; 10], *dest,
"u32 to u32 with data transform failed"
);

// u32 to u16 with truncate
log::info!("u32 to u16 with truncate");
let src = [0x12345678u32; 10];
let dest = &mut [0u16; 20];
let config = DmaConfig::new().with_data_transform(
DataTransform::builder().left_align_right_truncate(),
);
let transfer = DmaTransfer::memory_to_memory(config, &channel, &src, dest);

transfer.start().unwrap();
transfer.wait_for_transfer_complete().unwrap();
assert_eq!(
[0x1234; 10],
(*dest)[0..10],
"u32 to u16 with truncate failed"
);
assert_eq!([0; 10], (*dest)[10..20], "u32 to u16 with truncate failed");

// u32 to u8 with unpack
log::info!("u32 to u8 with unpack");
let src = [0x12345678u32; 10];
let dest = &mut [0u8; 40];
let config =
DmaConfig::new().with_data_transform(DataTransform::builder().unpack());
let transfer = DmaTransfer::memory_to_memory(config, &channel, &src, dest);

transfer.start().unwrap();
transfer.wait_for_transfer_complete().unwrap();
let expected = [0x78, 0x56, 0x34, 0x12];
assert_eq!(expected, (*dest)[0..4], "u32 to u8 unpack failed");
assert_eq!(expected, (*dest)[36..40], "u32 to u8 unpack failed");

// u8 to u32 with pack
log::info!("u8 to u32 with pack");
let mut src = [0u8; 40];
let dest = &mut [0u32; 10];
for chunk in src.chunks_mut(4) {
chunk.copy_from_slice(&[0x78, 0x56, 0x34, 0x12]);
}
let config =
DmaConfig::new().with_data_transform(DataTransform::builder().pack());
let transfer = DmaTransfer::memory_to_memory(config, &channel, &src, dest);

transfer.start().unwrap();
transfer.wait_for_transfer_complete().unwrap();
assert_eq!([0x12345678; 10], (*dest), "u8 to u32 with pack failed");

log::info!("All tests passed!");

loop {
debug::exit(debug::EXIT_SUCCESS)
}
}
Loading