aboutsummaryrefslogtreecommitdiff
path: root/examples/mcxa/src/bin/dma_interleave_transfer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/mcxa/src/bin/dma_interleave_transfer.rs')
-rw-r--r--examples/mcxa/src/bin/dma_interleave_transfer.rs58
1 files changed, 20 insertions, 38 deletions
diff --git a/examples/mcxa/src/bin/dma_interleave_transfer.rs b/examples/mcxa/src/bin/dma_interleave_transfer.rs
index 98e301a7c..03441fc32 100644
--- a/examples/mcxa/src/bin/dma_interleave_transfer.rs
+++ b/examples/mcxa/src/bin/dma_interleave_transfer.rs
@@ -10,29 +10,25 @@
10#![no_std] 10#![no_std]
11#![no_main] 11#![no_main]
12 12
13use core::fmt::Write as _;
14
13use embassy_executor::Spawner; 15use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 16use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; 17use embassy_mcxa::dma::DmaChannel;
16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 18use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
17use embassy_mcxa::{bind_interrupts, pac}; 19use static_cell::ConstStaticCell;
18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 20use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
19use core::fmt::Write as _;
20
21// Bind DMA channel 0 interrupt using Embassy-style macro
22bind_interrupts!(struct Irqs {
23 DMA_CH0 => DmaCh0InterruptHandler;
24});
25 21
26const BUFFER_LENGTH: usize = 16; 22const BUFFER_LENGTH: usize = 16;
27const HALF_BUFF_LENGTH: usize = BUFFER_LENGTH / 2; 23const HALF_BUFF_LENGTH: usize = BUFFER_LENGTH / 2;
28 24
29// Buffers in RAM 25// Buffers in RAM
30static mut SRC_BUFFER: [u32; HALF_BUFF_LENGTH] = [0; HALF_BUFF_LENGTH]; 26static SRC_BUFFER: ConstStaticCell<[u32; HALF_BUFF_LENGTH]> = ConstStaticCell::new([0; HALF_BUFF_LENGTH]);
31static mut DEST_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; 27static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
32 28
33/// Helper to print a buffer to UART 29/// Helper to print a buffer to UART
34fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) { 30fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf: &[u32]) {
35 write!(tx, "{:?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok(); 31 write!(tx, "{:?}", buf).ok();
36} 32}
37 33
38#[embassy_executor::main] 34#[embassy_executor::main]
@@ -49,11 +45,6 @@ async fn main(_spawner: Spawner) {
49 45
50 defmt::info!("DMA interleave transfer example starting..."); 46 defmt::info!("DMA interleave transfer example starting...");
51 47
52 // Enable DMA interrupt (DMA clock/reset/init is handled automatically by HAL)
53 unsafe {
54 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH0);
55 }
56
57 let config = Config { 48 let config = Config {
58 baudrate_bps: 115_200, 49 baudrate_bps: 115_200,
59 ..Default::default() 50 ..Default::default()
@@ -66,17 +57,16 @@ async fn main(_spawner: Spawner) {
66 .unwrap(); 57 .unwrap();
67 58
68 // Initialize buffers 59 // Initialize buffers
69 unsafe { 60 let src = SRC_BUFFER.take();
70 SRC_BUFFER = [1, 2, 3, 4, 5, 6, 7, 8]; 61 *src = [1, 2, 3, 4, 5, 6, 7, 8];
71 DEST_BUFFER = [0; BUFFER_LENGTH]; 62 let dst = DEST_BUFFER.take();
72 }
73 63
74 tx.blocking_write(b"Source Buffer: ").unwrap(); 64 tx.blocking_write(b"Source Buffer: ").unwrap();
75 print_buffer(&mut tx, core::ptr::addr_of!(SRC_BUFFER) as *const u32, HALF_BUFF_LENGTH); 65 print_buffer(&mut tx, src);
76 tx.blocking_write(b"\r\n").unwrap(); 66 tx.blocking_write(b"\r\n").unwrap();
77 67
78 tx.blocking_write(b"Destination Buffer (before): ").unwrap(); 68 tx.blocking_write(b"Destination Buffer (before): ").unwrap();
79 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH); 69 print_buffer(&mut tx, dst);
80 tx.blocking_write(b"\r\n").unwrap(); 70 tx.blocking_write(b"\r\n").unwrap();
81 71
82 tx.blocking_write(b"Configuring DMA with Embassy-style API...\r\n") 72 tx.blocking_write(b"Configuring DMA with Embassy-style API...\r\n")
@@ -109,10 +99,8 @@ async fn main(_spawner: Spawner) {
109 t.ch_int().write(|w| w.int().clear_bit_by_one()); 99 t.ch_int().write(|w| w.int().clear_bit_by_one());
110 100
111 // Source/destination addresses 101 // Source/destination addresses
112 t.tcd_saddr() 102 t.tcd_saddr().write(|w| w.saddr().bits(src.as_ptr() as u32));
113 .write(|w| w.saddr().bits(core::ptr::addr_of_mut!(SRC_BUFFER) as u32)); 103 t.tcd_daddr().write(|w| w.daddr().bits(dst.as_mut_ptr() as u32));
114 t.tcd_daddr()
115 .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32));
116 104
117 // Custom offsets for interleaving 105 // Custom offsets for interleaving
118 t.tcd_soff().write(|w| w.soff().bits(4)); // src: +4 bytes per read 106 t.tcd_soff().write(|w| w.soff().bits(4)); // src: +4 bytes per read
@@ -156,21 +144,15 @@ async fn main(_spawner: Spawner) {
156 tx.blocking_write(b"\r\nEDMA interleave transfer example finish.\r\n\r\n") 144 tx.blocking_write(b"\r\nEDMA interleave transfer example finish.\r\n\r\n")
157 .unwrap(); 145 .unwrap();
158 tx.blocking_write(b"Destination Buffer (after): ").unwrap(); 146 tx.blocking_write(b"Destination Buffer (after): ").unwrap();
159 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH); 147 print_buffer(&mut tx, dst);
160 tx.blocking_write(b"\r\n\r\n").unwrap(); 148 tx.blocking_write(b"\r\n\r\n").unwrap();
161 149
162 // Verify: Even indices should match SRC_BUFFER[i/2], odd indices should be 0 150 // Verify: Even indices should match SRC_BUFFER[i/2], odd indices should be 0
163 let mut mismatch = false; 151 let mut mismatch = false;
164 unsafe { 152 let diter = dst.chunks_exact(2);
165 for i in 0..BUFFER_LENGTH { 153 let siter = src.iter();
166 if i % 2 == 0 { 154 for (ch, src) in diter.zip(siter) {
167 if DEST_BUFFER[i] != SRC_BUFFER[i / 2] { 155 mismatch |= !matches!(ch, [a, 0] if a == src);
168 mismatch = true;
169 }
170 } else if DEST_BUFFER[i] != 0 {
171 mismatch = true;
172 }
173 }
174 } 156 }
175 157
176 if mismatch { 158 if mismatch {