diff options
Diffstat (limited to 'examples/mcxa/src/bin/dma_interleave_transfer.rs')
| -rw-r--r-- | examples/mcxa/src/bin/dma_interleave_transfer.rs | 58 |
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 | ||
| 13 | use core::fmt::Write as _; | ||
| 14 | |||
| 13 | use embassy_executor::Spawner; | 15 | use embassy_executor::Spawner; |
| 14 | use embassy_mcxa::clocks::config::Div8; | 16 | use embassy_mcxa::clocks::config::Div8; |
| 15 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; | 17 | use embassy_mcxa::dma::DmaChannel; |
| 16 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 18 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 17 | use embassy_mcxa::{bind_interrupts, pac}; | 19 | use static_cell::ConstStaticCell; |
| 18 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 20 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 19 | use core::fmt::Write as _; | ||
| 20 | |||
| 21 | // Bind DMA channel 0 interrupt using Embassy-style macro | ||
| 22 | bind_interrupts!(struct Irqs { | ||
| 23 | DMA_CH0 => DmaCh0InterruptHandler; | ||
| 24 | }); | ||
| 25 | 21 | ||
| 26 | const BUFFER_LENGTH: usize = 16; | 22 | const BUFFER_LENGTH: usize = 16; |
| 27 | const HALF_BUFF_LENGTH: usize = BUFFER_LENGTH / 2; | 23 | const HALF_BUFF_LENGTH: usize = BUFFER_LENGTH / 2; |
| 28 | 24 | ||
| 29 | // Buffers in RAM | 25 | // Buffers in RAM |
| 30 | static mut SRC_BUFFER: [u32; HALF_BUFF_LENGTH] = [0; HALF_BUFF_LENGTH]; | 26 | static SRC_BUFFER: ConstStaticCell<[u32; HALF_BUFF_LENGTH]> = ConstStaticCell::new([0; HALF_BUFF_LENGTH]); |
| 31 | static mut DEST_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; | 27 | static 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 |
| 34 | fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) { | 30 | fn 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 { |
