aboutsummaryrefslogtreecommitdiff
path: root/examples/mcxa
diff options
context:
space:
mode:
Diffstat (limited to 'examples/mcxa')
-rw-r--r--examples/mcxa/src/bin/dma_mem_to_mem.rs75
1 files changed, 22 insertions, 53 deletions
diff --git a/examples/mcxa/src/bin/dma_mem_to_mem.rs b/examples/mcxa/src/bin/dma_mem_to_mem.rs
index 149e37326..b78745464 100644
--- a/examples/mcxa/src/bin/dma_mem_to_mem.rs
+++ b/examples/mcxa/src/bin/dma_mem_to_mem.rs
@@ -18,6 +18,7 @@ use embassy_mcxa::clocks::config::Div8;
18use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions}; 18use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions};
19use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 19use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
20use embassy_mcxa::{bind_interrupts, pac}; 20use embassy_mcxa::{bind_interrupts, pac};
21use static_cell::ConstStaticCell;
21use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 22use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
22use core::fmt::Write as _; 23use core::fmt::Write as _;
23 24
@@ -29,14 +30,14 @@ bind_interrupts!(struct Irqs {
29const BUFFER_LENGTH: usize = 4; 30const BUFFER_LENGTH: usize = 4;
30 31
31// Buffers in RAM (static mut is automatically placed in .bss/.data) 32// Buffers in RAM (static mut is automatically placed in .bss/.data)
32static mut SRC_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; 33static SRC_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([1, 2, 3, 4]);
33static mut DEST_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; 34static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
34static mut MEMSET_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; 35static MEMSET_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
35 36
36/// Helper to print a buffer as [v1, v2, v3, v4] to UART 37/// Helper to print a buffer as [v1, v2, v3, v4] to UART
37/// Takes a raw pointer to avoid warnings about shared references to mutable statics 38/// Takes a raw pointer to avoid warnings about shared references to mutable statics
38fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const [u32; BUFFER_LENGTH]) { 39fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: &[u32; BUFFER_LENGTH]) {
39 write!(tx, "{:?}", unsafe { &*buf_ptr }).ok(); 40 write!(tx, "{:?}", buf_ptr).ok();
40} 41}
41 42
42#[embassy_executor::main] 43#[embassy_executor::main]
@@ -70,18 +71,16 @@ async fn main(_spawner: Spawner) {
70 tx.blocking_write(b"EDMA memory to memory example begin.\r\n\r\n") 71 tx.blocking_write(b"EDMA memory to memory example begin.\r\n\r\n")
71 .unwrap(); 72 .unwrap();
72 73
73 // Initialize buffers 74 let src = SRC_BUFFER.take();
74 unsafe { 75 let dst = DEST_BUFFER.take();
75 SRC_BUFFER = [1, 2, 3, 4]; 76 let mst = MEMSET_BUFFER.take();
76 DEST_BUFFER = [0; BUFFER_LENGTH];
77 }
78 77
79 tx.blocking_write(b"Source Buffer: ").unwrap(); 78 tx.blocking_write(b"Source Buffer: ").unwrap();
80 print_buffer(&mut tx, &raw const SRC_BUFFER); 79 print_buffer(&mut tx, src);
81 tx.blocking_write(b"\r\n").unwrap(); 80 tx.blocking_write(b"\r\n").unwrap();
82 81
83 tx.blocking_write(b"Destination Buffer (before): ").unwrap(); 82 tx.blocking_write(b"Destination Buffer (before): ").unwrap();
84 print_buffer(&mut tx, &raw const DEST_BUFFER); 83 print_buffer(&mut tx, dst);
85 tx.blocking_write(b"\r\n").unwrap(); 84 tx.blocking_write(b"\r\n").unwrap();
86 85
87 tx.blocking_write(b"Configuring DMA with Embassy-style API...\r\n") 86 tx.blocking_write(b"Configuring DMA with Embassy-style API...\r\n")
@@ -106,30 +105,17 @@ async fn main(_spawner: Spawner) {
106 // Using async `.await` - the executor can run other tasks while waiting! 105 // Using async `.await` - the executor can run other tasks while waiting!
107 106
108 // Perform type-safe memory-to-memory transfer using Embassy-style async API 107 // Perform type-safe memory-to-memory transfer using Embassy-style async API
109 unsafe { 108 // Using async `.await` - the executor can run other tasks while waiting!
110 let src = &*core::ptr::addr_of!(SRC_BUFFER); 109 let transfer = dma_ch0.mem_to_mem(src, dst, options);
111 let dst = &mut *core::ptr::addr_of_mut!(DEST_BUFFER); 110 transfer.await;
112
113 // Using async `.await` - the executor can run other tasks while waiting!
114 let transfer = dma_ch0.mem_to_mem(src, dst, options);
115 transfer.await;
116 }
117 111
118 tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n").unwrap(); 112 tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n").unwrap();
119 tx.blocking_write(b"Destination Buffer (after): ").unwrap(); 113 tx.blocking_write(b"Destination Buffer (after): ").unwrap();
120 print_buffer(&mut tx, &raw const DEST_BUFFER); 114 print_buffer(&mut tx, dst);
121 tx.blocking_write(b"\r\n").unwrap(); 115 tx.blocking_write(b"\r\n").unwrap();
122 116
123 // Verify data 117 // Verify data
124 let mut mismatch = false; 118 let mut mismatch = src != dst;
125 unsafe {
126 for i in 0..BUFFER_LENGTH {
127 if SRC_BUFFER[i] != DEST_BUFFER[i] {
128 mismatch = true;
129 break;
130 }
131 }
132 }
133 119
134 if mismatch { 120 if mismatch {
135 tx.blocking_write(b"FAIL: mem_to_mem mismatch!\r\n").unwrap(); 121 tx.blocking_write(b"FAIL: mem_to_mem mismatch!\r\n").unwrap();
@@ -152,37 +138,24 @@ async fn main(_spawner: Spawner) {
152 .unwrap(); 138 .unwrap();
153 139
154 tx.blocking_write(b"Memset Buffer (before): ").unwrap(); 140 tx.blocking_write(b"Memset Buffer (before): ").unwrap();
155 print_buffer(&mut tx, &raw const MEMSET_BUFFER); 141 print_buffer(&mut tx, mst);
156 tx.blocking_write(b"\r\n").unwrap(); 142 tx.blocking_write(b"\r\n").unwrap();
157 143
158 // Fill buffer with a pattern value using DMA memset 144 // Fill buffer with a pattern value using DMA memset
159 let pattern: u32 = 0xDEADBEEF; 145 let pattern: u32 = 0xDEADBEEF;
160 tx.blocking_write(b"Filling with pattern 0xDEADBEEF...\r\n").unwrap(); 146 tx.blocking_write(b"Filling with pattern 0xDEADBEEF...\r\n").unwrap();
161 147
162 unsafe { 148 // Using blocking_wait() for demonstration - also shows non-async usage
163 let dst = &mut *core::ptr::addr_of_mut!(MEMSET_BUFFER); 149 let transfer = dma_ch0.memset(&pattern, mst, options);
164 150 transfer.blocking_wait();
165 // Using blocking_wait() for demonstration - also shows non-async usage
166 let transfer = dma_ch0.memset(&pattern, dst, options);
167 transfer.blocking_wait();
168 }
169 151
170 tx.blocking_write(b"DMA memset complete!\r\n\r\n").unwrap(); 152 tx.blocking_write(b"DMA memset complete!\r\n\r\n").unwrap();
171 tx.blocking_write(b"Memset Buffer (after): ").unwrap(); 153 tx.blocking_write(b"Memset Buffer (after): ").unwrap();
172 print_buffer(&mut tx, &raw const MEMSET_BUFFER); 154 print_buffer(&mut tx, mst);
173 tx.blocking_write(b"\r\n").unwrap(); 155 tx.blocking_write(b"\r\n").unwrap();
174 156
175 // Verify memset result 157 // Verify memset result
176 let mut memset_ok = true; 158 let memset_ok = mst.iter().all(|&v| v == pattern);
177 unsafe {
178 #[allow(clippy::needless_range_loop)]
179 for i in 0..BUFFER_LENGTH {
180 if MEMSET_BUFFER[i] != pattern {
181 memset_ok = false;
182 break;
183 }
184 }
185 }
186 159
187 if !memset_ok { 160 if !memset_ok {
188 tx.blocking_write(b"FAIL: memset mismatch!\r\n").unwrap(); 161 tx.blocking_write(b"FAIL: memset mismatch!\r\n").unwrap();
@@ -193,8 +166,4 @@ async fn main(_spawner: Spawner) {
193 } 166 }
194 167
195 tx.blocking_write(b"=== All DMA tests complete ===\r\n").unwrap(); 168 tx.blocking_write(b"=== All DMA tests complete ===\r\n").unwrap();
196
197 loop {
198 cortex_m::asm::wfe();
199 }
200} 169}