diff options
| author | James Munns <[email protected]> | 2025-12-05 20:45:59 +0100 |
|---|---|---|
| committer | James Munns <[email protected]> | 2025-12-05 20:45:59 +0100 |
| commit | 5d8f3a3d18eda339e258193295cf332d7e01882e (patch) | |
| tree | cb20b9e64c682a1157896852a1123db38a3cf4e0 /examples/mcxa | |
| parent | 787bf84963ecd32306b6b2993504b2196f71cf72 (diff) | |
Clean up some common PAC operations using helper methods
Diffstat (limited to 'examples/mcxa')
| -rw-r--r-- | examples/mcxa/src/bin/dma_mem_to_mem.rs | 75 |
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; | |||
| 18 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions}; | 18 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions}; |
| 19 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 19 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 20 | use embassy_mcxa::{bind_interrupts, pac}; | 20 | use embassy_mcxa::{bind_interrupts, pac}; |
| 21 | use static_cell::ConstStaticCell; | ||
| 21 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 22 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 22 | use core::fmt::Write as _; | 23 | use core::fmt::Write as _; |
| 23 | 24 | ||
| @@ -29,14 +30,14 @@ bind_interrupts!(struct Irqs { | |||
| 29 | const BUFFER_LENGTH: usize = 4; | 30 | const 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) |
| 32 | static mut SRC_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; | 33 | static SRC_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([1, 2, 3, 4]); |
| 33 | static mut DEST_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; | 34 | static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]); |
| 34 | static mut MEMSET_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; | 35 | static 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 |
| 38 | fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const [u32; BUFFER_LENGTH]) { | 39 | fn 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 | } |
