diff options
| author | Bogdan Petru Chircu Mare <[email protected]> | 2025-12-01 09:08:03 -0800 |
|---|---|---|
| committer | Bogdan Petru Chircu Mare <[email protected]> | 2025-12-01 09:08:03 -0800 |
| commit | 230237b73cbe6f31780ea407ed13bee1adf8eaa2 (patch) | |
| tree | 0f40b5ad7ced34055aabb91446ca759e67041115 | |
| parent | 5a6394666e23555e4f329f7b1bd470d0728434a1 (diff) | |
Apply rustfmt formatting fixes
| -rw-r--r-- | examples/src/bin/dma_channel_link.rs | 88 | ||||
| -rw-r--r-- | examples/src/bin/dma_interleave_transfer.rs | 38 | ||||
| -rw-r--r-- | examples/src/bin/dma_mem_to_mem.rs | 12 | ||||
| -rw-r--r-- | examples/src/bin/dma_memset.rs | 37 | ||||
| -rw-r--r-- | examples/src/bin/dma_ping_pong_transfer.rs | 52 | ||||
| -rw-r--r-- | examples/src/bin/dma_scatter_gather.rs | 42 | ||||
| -rw-r--r-- | examples/src/bin/dma_scatter_gather_builder.rs | 17 | ||||
| -rw-r--r-- | examples/src/bin/dma_wrap_transfer.rs | 46 | ||||
| -rw-r--r-- | examples/src/bin/lpuart_dma.rs | 4 | ||||
| -rw-r--r-- | examples/src/bin/lpuart_ring_buffer.rs | 12 | ||||
| -rw-r--r-- | src/dma.rs | 5 |
11 files changed, 204 insertions, 149 deletions
diff --git a/examples/src/bin/dma_channel_link.rs b/examples/src/bin/dma_channel_link.rs index d541dc7f4..34162d931 100644 --- a/examples/src/bin/dma_channel_link.rs +++ b/examples/src/bin/dma_channel_link.rs | |||
| @@ -18,10 +18,9 @@ | |||
| 18 | 18 | ||
| 19 | use embassy_executor::Spawner; | 19 | use embassy_executor::Spawner; |
| 20 | use embassy_mcxa::clocks::config::Div8; | 20 | use embassy_mcxa::clocks::config::Div8; |
| 21 | use embassy_mcxa::dma::{self, DmaChannel, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler}; | 21 | use embassy_mcxa::dma::{self, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler, DmaChannel}; |
| 22 | use embassy_mcxa::bind_interrupts; | ||
| 23 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 22 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 24 | use embassy_mcxa::pac; | 23 | use embassy_mcxa::{bind_interrupts, pac}; |
| 25 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 24 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 26 | 25 | ||
| 27 | // Buffers | 26 | // Buffers |
| @@ -104,10 +103,14 @@ async fn main(_spawner: Spawner) { | |||
| 104 | 103 | ||
| 105 | // Clear Global Halt/Error state | 104 | // Clear Global Halt/Error state |
| 106 | dma0.mp_csr().modify(|_, w| { | 105 | dma0.mp_csr().modify(|_, w| { |
| 107 | w.halt().normal_operation() | 106 | w.halt() |
| 108 | .hae().normal_operation() | 107 | .normal_operation() |
| 109 | .ecx().normal_operation() | 108 | .hae() |
| 110 | .cx().normal_operation() | 109 | .normal_operation() |
| 110 | .ecx() | ||
| 111 | .normal_operation() | ||
| 112 | .cx() | ||
| 113 | .normal_operation() | ||
| 111 | }); | 114 | }); |
| 112 | 115 | ||
| 113 | unsafe { | 116 | unsafe { |
| @@ -126,8 +129,7 @@ async fn main(_spawner: Spawner) { | |||
| 126 | let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); | 129 | let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); |
| 127 | let (mut tx, _rx) = lpuart.split(); | 130 | let (mut tx, _rx) = lpuart.split(); |
| 128 | 131 | ||
| 129 | tx.blocking_write(b"EDMA channel link example begin.\r\n\r\n") | 132 | tx.blocking_write(b"EDMA channel link example begin.\r\n\r\n").unwrap(); |
| 130 | .unwrap(); | ||
| 131 | 133 | ||
| 132 | // Initialize buffers | 134 | // Initialize buffers |
| 133 | unsafe { | 135 | unsafe { |
| @@ -180,11 +182,16 @@ async fn main(_spawner: Spawner) { | |||
| 180 | 182 | ||
| 181 | // Reset channel state | 183 | // Reset channel state |
| 182 | t.ch_csr().write(|w| { | 184 | t.ch_csr().write(|w| { |
| 183 | w.erq().disable() | 185 | w.erq() |
| 184 | .earq().disable() | 186 | .disable() |
| 185 | .eei().no_error() | 187 | .earq() |
| 186 | .ebw().disable() | 188 | .disable() |
| 187 | .done().clear_bit_by_one() | 189 | .eei() |
| 190 | .no_error() | ||
| 191 | .ebw() | ||
| 192 | .disable() | ||
| 193 | .done() | ||
| 194 | .clear_bit_by_one() | ||
| 188 | }); | 195 | }); |
| 189 | t.ch_es().write(|w| w.bits(0)); | 196 | t.ch_es().write(|w| w.bits(0)); |
| 190 | t.ch_int().write(|w| w.int().clear_bit_by_one()); | 197 | t.ch_int().write(|w| w.int().clear_bit_by_one()); |
| @@ -211,8 +218,10 @@ async fn main(_spawner: Spawner) { | |||
| 211 | 218 | ||
| 212 | // Major loop: reset source address after major loop | 219 | // Major loop: reset source address after major loop |
| 213 | let total_bytes = nbytes * count as u32; | 220 | let total_bytes = nbytes * count as u32; |
| 214 | t.tcd_slast_sda().write(|w| w.slast_sda().bits(-(total_bytes as i32) as u32)); | 221 | t.tcd_slast_sda() |
| 215 | t.tcd_dlast_sga().write(|w| w.dlast_sga().bits(-(total_bytes as i32) as u32)); | 222 | .write(|w| w.slast_sda().bits(-(total_bytes as i32) as u32)); |
| 223 | t.tcd_dlast_sga() | ||
| 224 | .write(|w| w.dlast_sga().bits(-(total_bytes as i32) as u32)); | ||
| 216 | 225 | ||
| 217 | // Major loop count | 226 | // Major loop count |
| 218 | t.tcd_biter_elinkno().write(|w| w.biter().bits(count)); | 227 | t.tcd_biter_elinkno().write(|w| w.biter().bits(count)); |
| @@ -229,7 +238,6 @@ async fn main(_spawner: Spawner) { | |||
| 229 | } | 238 | } |
| 230 | 239 | ||
| 231 | unsafe { | 240 | unsafe { |
| 232 | |||
| 233 | // Channel 0: Transfer 16 bytes total (8 bytes per minor loop, 2 major iterations) | 241 | // Channel 0: Transfer 16 bytes total (8 bytes per minor loop, 2 major iterations) |
| 234 | // Minor Link -> Channel 1 | 242 | // Minor Link -> Channel 1 |
| 235 | // Major Link -> Channel 2 | 243 | // Major Link -> Channel 2 |
| @@ -265,34 +273,44 @@ async fn main(_spawner: Spawner) { | |||
| 265 | core::ptr::addr_of!(SRC_BUFFER) as u32, | 273 | core::ptr::addr_of!(SRC_BUFFER) as u32, |
| 266 | core::ptr::addr_of_mut!(DEST_BUFFER2) as u32, | 274 | core::ptr::addr_of_mut!(DEST_BUFFER2) as u32, |
| 267 | 4, | 275 | 4, |
| 268 | 16, // full buffer in one minor loop | 276 | 16, // full buffer in one minor loop |
| 269 | 1, // 1 major iteration | 277 | 1, // 1 major iteration |
| 270 | true, // enable interrupt | 278 | true, // enable interrupt |
| 271 | ); | 279 | ); |
| 272 | } | 280 | } |
| 273 | 281 | ||
| 274 | tx.blocking_write(b"Triggering Channel 0 (1st minor loop)...\r\n").unwrap(); | 282 | tx.blocking_write(b"Triggering Channel 0 (1st minor loop)...\r\n") |
| 283 | .unwrap(); | ||
| 275 | 284 | ||
| 276 | // Trigger first minor loop of CH0 | 285 | // Trigger first minor loop of CH0 |
| 277 | unsafe { ch0.trigger_start(); } | 286 | unsafe { |
| 287 | ch0.trigger_start(); | ||
| 288 | } | ||
| 278 | 289 | ||
| 279 | // Wait for CH1 to complete (triggered by CH0 minor link) | 290 | // Wait for CH1 to complete (triggered by CH0 minor link) |
| 280 | while !ch1.is_done() { | 291 | while !ch1.is_done() { |
| 281 | cortex_m::asm::nop(); | 292 | cortex_m::asm::nop(); |
| 282 | } | 293 | } |
| 283 | unsafe { ch1.clear_done(); } | 294 | unsafe { |
| 295 | ch1.clear_done(); | ||
| 296 | } | ||
| 284 | 297 | ||
| 285 | tx.blocking_write(b"CH1 done (via minor link).\r\n").unwrap(); | 298 | tx.blocking_write(b"CH1 done (via minor link).\r\n").unwrap(); |
| 286 | tx.blocking_write(b"Triggering Channel 0 (2nd minor loop)...\r\n").unwrap(); | 299 | tx.blocking_write(b"Triggering Channel 0 (2nd minor loop)...\r\n") |
| 300 | .unwrap(); | ||
| 287 | 301 | ||
| 288 | // Trigger second minor loop of CH0 | 302 | // Trigger second minor loop of CH0 |
| 289 | unsafe { ch0.trigger_start(); } | 303 | unsafe { |
| 304 | ch0.trigger_start(); | ||
| 305 | } | ||
| 290 | 306 | ||
| 291 | // Wait for CH0 major loop to complete | 307 | // Wait for CH0 major loop to complete |
| 292 | while !ch0.is_done() { | 308 | while !ch0.is_done() { |
| 293 | cortex_m::asm::nop(); | 309 | cortex_m::asm::nop(); |
| 294 | } | 310 | } |
| 295 | unsafe { ch0.clear_done(); } | 311 | unsafe { |
| 312 | ch0.clear_done(); | ||
| 313 | } | ||
| 296 | 314 | ||
| 297 | tx.blocking_write(b"CH0 major loop done.\r\n").unwrap(); | 315 | tx.blocking_write(b"CH0 major loop done.\r\n").unwrap(); |
| 298 | 316 | ||
| @@ -302,12 +320,13 @@ async fn main(_spawner: Spawner) { | |||
| 302 | while !ch2.is_done() { | 320 | while !ch2.is_done() { |
| 303 | cortex_m::asm::nop(); | 321 | cortex_m::asm::nop(); |
| 304 | } | 322 | } |
| 305 | unsafe { ch2.clear_done(); } | 323 | unsafe { |
| 324 | ch2.clear_done(); | ||
| 325 | } | ||
| 306 | 326 | ||
| 307 | tx.blocking_write(b"CH2 done (via major link).\r\n\r\n").unwrap(); | 327 | tx.blocking_write(b"CH2 done (via major link).\r\n\r\n").unwrap(); |
| 308 | 328 | ||
| 309 | tx.blocking_write(b"EDMA channel link example finish.\r\n\r\n") | 329 | tx.blocking_write(b"EDMA channel link example finish.\r\n\r\n").unwrap(); |
| 310 | .unwrap(); | ||
| 311 | 330 | ||
| 312 | tx.blocking_write(b"DEST0 (after): ").unwrap(); | 331 | tx.blocking_write(b"DEST0 (after): ").unwrap(); |
| 313 | print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER0) as *const u32, 4); | 332 | print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER0) as *const u32, 4); |
| @@ -330,9 +349,15 @@ async fn main(_spawner: Spawner) { | |||
| 330 | let dst2_ptr = core::ptr::addr_of!(DEST_BUFFER2) as *const u32; | 349 | let dst2_ptr = core::ptr::addr_of!(DEST_BUFFER2) as *const u32; |
| 331 | 350 | ||
| 332 | for i in 0..4 { | 351 | for i in 0..4 { |
| 333 | if *dst0_ptr.add(i) != *src_ptr.add(i) { success = false; } | 352 | if *dst0_ptr.add(i) != *src_ptr.add(i) { |
| 334 | if *dst1_ptr.add(i) != *src_ptr.add(i) { success = false; } | 353 | success = false; |
| 335 | if *dst2_ptr.add(i) != *src_ptr.add(i) { success = false; } | 354 | } |
| 355 | if *dst1_ptr.add(i) != *src_ptr.add(i) { | ||
| 356 | success = false; | ||
| 357 | } | ||
| 358 | if *dst2_ptr.add(i) != *src_ptr.add(i) { | ||
| 359 | success = false; | ||
| 360 | } | ||
| 336 | } | 361 | } |
| 337 | } | 362 | } |
| 338 | 363 | ||
| @@ -348,4 +373,3 @@ async fn main(_spawner: Spawner) { | |||
| 348 | cortex_m::asm::wfe(); | 373 | cortex_m::asm::wfe(); |
| 349 | } | 374 | } |
| 350 | } | 375 | } |
| 351 | |||
diff --git a/examples/src/bin/dma_interleave_transfer.rs b/examples/src/bin/dma_interleave_transfer.rs index 949ea0605..c0ebb0a46 100644 --- a/examples/src/bin/dma_interleave_transfer.rs +++ b/examples/src/bin/dma_interleave_transfer.rs | |||
| @@ -12,10 +12,9 @@ | |||
| 12 | 12 | ||
| 13 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| 14 | use embassy_mcxa::clocks::config::Div8; | 14 | use embassy_mcxa::clocks::config::Div8; |
| 15 | use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler}; | 15 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; |
| 16 | use embassy_mcxa::bind_interrupts; | ||
| 17 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 16 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 18 | use embassy_mcxa::pac; | 17 | use embassy_mcxa::{bind_interrupts, pac}; |
| 19 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 18 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 20 | 19 | ||
| 21 | // Bind DMA channel 0 interrupt using Embassy-style macro | 20 | // Bind DMA channel 0 interrupt using Embassy-style macro |
| @@ -125,22 +124,29 @@ async fn main(_spawner: Spawner) { | |||
| 125 | 124 | ||
| 126 | // Reset channel state | 125 | // Reset channel state |
| 127 | t.ch_csr().write(|w| { | 126 | t.ch_csr().write(|w| { |
| 128 | w.erq().disable() | 127 | w.erq() |
| 129 | .earq().disable() | 128 | .disable() |
| 130 | .eei().no_error() | 129 | .earq() |
| 131 | .ebw().disable() | 130 | .disable() |
| 132 | .done().clear_bit_by_one() | 131 | .eei() |
| 132 | .no_error() | ||
| 133 | .ebw() | ||
| 134 | .disable() | ||
| 135 | .done() | ||
| 136 | .clear_bit_by_one() | ||
| 133 | }); | 137 | }); |
| 134 | t.ch_es().write(|w| w.bits(0)); | 138 | t.ch_es().write(|w| w.bits(0)); |
| 135 | t.ch_int().write(|w| w.int().clear_bit_by_one()); | 139 | t.ch_int().write(|w| w.int().clear_bit_by_one()); |
| 136 | 140 | ||
| 137 | // Source/destination addresses | 141 | // Source/destination addresses |
| 138 | t.tcd_saddr().write(|w| w.saddr().bits(core::ptr::addr_of_mut!(SRC_BUFFER) as u32)); | 142 | t.tcd_saddr() |
| 139 | t.tcd_daddr().write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32)); | 143 | .write(|w| w.saddr().bits(core::ptr::addr_of_mut!(SRC_BUFFER) as u32)); |
| 144 | t.tcd_daddr() | ||
| 145 | .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32)); | ||
| 140 | 146 | ||
| 141 | // Custom offsets for interleaving | 147 | // Custom offsets for interleaving |
| 142 | t.tcd_soff().write(|w| w.soff().bits(4)); // src: +4 bytes per read | 148 | t.tcd_soff().write(|w| w.soff().bits(4)); // src: +4 bytes per read |
| 143 | t.tcd_doff().write(|w| w.doff().bits(8)); // dst: +8 bytes per write | 149 | t.tcd_doff().write(|w| w.doff().bits(8)); // dst: +8 bytes per write |
| 144 | 150 | ||
| 145 | // Attributes: 32-bit transfers (size = 2) | 151 | // Attributes: 32-bit transfers (size = 2) |
| 146 | t.tcd_attr().write(|w| w.ssize().bits(2).dsize().bits(2)); | 152 | t.tcd_attr().write(|w| w.ssize().bits(2).dsize().bits(2)); |
| @@ -153,7 +159,8 @@ async fn main(_spawner: Spawner) { | |||
| 153 | t.tcd_slast_sda().write(|w| w.slast_sda().bits(-(nbytes as i32) as u32)); | 159 | t.tcd_slast_sda().write(|w| w.slast_sda().bits(-(nbytes as i32) as u32)); |
| 154 | // Destination uses 2x offset, so adjust accordingly | 160 | // Destination uses 2x offset, so adjust accordingly |
| 155 | let dst_total = (HALF_BUFF_LENGTH * 8) as u32; | 161 | let dst_total = (HALF_BUFF_LENGTH * 8) as u32; |
| 156 | t.tcd_dlast_sga().write(|w| w.dlast_sga().bits(-(dst_total as i32) as u32)); | 162 | t.tcd_dlast_sga() |
| 163 | .write(|w| w.dlast_sga().bits(-(dst_total as i32) as u32)); | ||
| 157 | 164 | ||
| 158 | // Major loop count = 1 | 165 | // Major loop count = 1 |
| 159 | t.tcd_biter_elinkno().write(|w| w.biter().bits(1)); | 166 | t.tcd_biter_elinkno().write(|w| w.biter().bits(1)); |
| @@ -172,7 +179,9 @@ async fn main(_spawner: Spawner) { | |||
| 172 | while !dma_ch0.is_done() { | 179 | while !dma_ch0.is_done() { |
| 173 | cortex_m::asm::nop(); | 180 | cortex_m::asm::nop(); |
| 174 | } | 181 | } |
| 175 | unsafe { dma_ch0.clear_done(); } | 182 | unsafe { |
| 183 | dma_ch0.clear_done(); | ||
| 184 | } | ||
| 176 | 185 | ||
| 177 | tx.blocking_write(b"\r\nEDMA interleave transfer example finish.\r\n\r\n") | 186 | tx.blocking_write(b"\r\nEDMA interleave transfer example finish.\r\n\r\n") |
| 178 | .unwrap(); | 187 | .unwrap(); |
| @@ -206,4 +215,3 @@ async fn main(_spawner: Spawner) { | |||
| 206 | cortex_m::asm::wfe(); | 215 | cortex_m::asm::wfe(); |
| 207 | } | 216 | } |
| 208 | } | 217 | } |
| 209 | |||
diff --git a/examples/src/bin/dma_mem_to_mem.rs b/examples/src/bin/dma_mem_to_mem.rs index 01e5edb1e..72916384f 100644 --- a/examples/src/bin/dma_mem_to_mem.rs +++ b/examples/src/bin/dma_mem_to_mem.rs | |||
| @@ -15,10 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | use embassy_executor::Spawner; | 16 | use embassy_executor::Spawner; |
| 17 | use embassy_mcxa::clocks::config::Div8; | 17 | use embassy_mcxa::clocks::config::Div8; |
| 18 | use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler, TransferOptions}; | 18 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions}; |
| 19 | use embassy_mcxa::bind_interrupts; | ||
| 20 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 19 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 21 | use embassy_mcxa::pac; | 20 | use embassy_mcxa::{bind_interrupts, pac}; |
| 22 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 21 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 23 | 22 | ||
| 24 | // Bind DMA channel 0 interrupt using Embassy-style macro | 23 | // Bind DMA channel 0 interrupt using Embassy-style macro |
| @@ -147,8 +146,7 @@ async fn main(_spawner: Spawner) { | |||
| 147 | transfer.await; | 146 | transfer.await; |
| 148 | } | 147 | } |
| 149 | 148 | ||
| 150 | tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n") | 149 | tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n").unwrap(); |
| 151 | .unwrap(); | ||
| 152 | tx.blocking_write(b"Destination Buffer (after): ").unwrap(); | 150 | tx.blocking_write(b"Destination Buffer (after): ").unwrap(); |
| 153 | print_buffer(&mut tx, &raw const DEST_BUFFER); | 151 | print_buffer(&mut tx, &raw const DEST_BUFFER); |
| 154 | tx.blocking_write(b"\r\n").unwrap(); | 152 | tx.blocking_write(b"\r\n").unwrap(); |
| @@ -181,7 +179,8 @@ async fn main(_spawner: Spawner) { | |||
| 181 | // - Incrementing destination address | 179 | // - Incrementing destination address |
| 182 | // - Uses the same Transfer future pattern | 180 | // - Uses the same Transfer future pattern |
| 183 | 181 | ||
| 184 | tx.blocking_write(b"--- Demonstrating memset() feature ---\r\n\r\n").unwrap(); | 182 | tx.blocking_write(b"--- Demonstrating memset() feature ---\r\n\r\n") |
| 183 | .unwrap(); | ||
| 185 | 184 | ||
| 186 | tx.blocking_write(b"Memset Buffer (before): ").unwrap(); | 185 | tx.blocking_write(b"Memset Buffer (before): ").unwrap(); |
| 187 | print_buffer(&mut tx, &raw const MEMSET_BUFFER); | 186 | print_buffer(&mut tx, &raw const MEMSET_BUFFER); |
| @@ -230,4 +229,3 @@ async fn main(_spawner: Spawner) { | |||
| 230 | cortex_m::asm::wfe(); | 229 | cortex_m::asm::wfe(); |
| 231 | } | 230 | } |
| 232 | } | 231 | } |
| 233 | |||
diff --git a/examples/src/bin/dma_memset.rs b/examples/src/bin/dma_memset.rs index 8a1636e57..9fbba85e9 100644 --- a/examples/src/bin/dma_memset.rs +++ b/examples/src/bin/dma_memset.rs | |||
| @@ -12,10 +12,9 @@ | |||
| 12 | 12 | ||
| 13 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| 14 | use embassy_mcxa::clocks::config::Div8; | 14 | use embassy_mcxa::clocks::config::Div8; |
| 15 | use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler}; | 15 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; |
| 16 | use embassy_mcxa::bind_interrupts; | ||
| 17 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 16 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 18 | use embassy_mcxa::pac; | 17 | use embassy_mcxa::{bind_interrupts, pac}; |
| 19 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 18 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 20 | 19 | ||
| 21 | // Bind DMA channel 0 interrupt using Embassy-style macro | 20 | // Bind DMA channel 0 interrupt using Embassy-style macro |
| @@ -92,8 +91,7 @@ async fn main(_spawner: Spawner) { | |||
| 92 | let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); | 91 | let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); |
| 93 | let (mut tx, _rx) = lpuart.split(); | 92 | let (mut tx, _rx) = lpuart.split(); |
| 94 | 93 | ||
| 95 | tx.blocking_write(b"EDMA memset example begin.\r\n\r\n") | 94 | tx.blocking_write(b"EDMA memset example begin.\r\n\r\n").unwrap(); |
| 96 | .unwrap(); | ||
| 97 | 95 | ||
| 98 | // Initialize buffers | 96 | // Initialize buffers |
| 99 | unsafe { | 97 | unsafe { |
| @@ -133,19 +131,26 @@ async fn main(_spawner: Spawner) { | |||
| 133 | 131 | ||
| 134 | // Reset channel state | 132 | // Reset channel state |
| 135 | t.ch_csr().write(|w| { | 133 | t.ch_csr().write(|w| { |
| 136 | w.erq().disable() | 134 | w.erq() |
| 137 | .earq().disable() | 135 | .disable() |
| 138 | .eei().no_error() | 136 | .earq() |
| 139 | .ebw().disable() | 137 | .disable() |
| 140 | .done().clear_bit_by_one() | 138 | .eei() |
| 139 | .no_error() | ||
| 140 | .ebw() | ||
| 141 | .disable() | ||
| 142 | .done() | ||
| 143 | .clear_bit_by_one() | ||
| 141 | }); | 144 | }); |
| 142 | t.ch_es().write(|w| w.bits(0)); | 145 | t.ch_es().write(|w| w.bits(0)); |
| 143 | t.ch_int().write(|w| w.int().clear_bit_by_one()); | 146 | t.ch_int().write(|w| w.int().clear_bit_by_one()); |
| 144 | 147 | ||
| 145 | // Source address (pattern) - fixed | 148 | // Source address (pattern) - fixed |
| 146 | t.tcd_saddr().write(|w| w.saddr().bits(core::ptr::addr_of_mut!(PATTERN) as u32)); | 149 | t.tcd_saddr() |
| 150 | .write(|w| w.saddr().bits(core::ptr::addr_of_mut!(PATTERN) as u32)); | ||
| 147 | // Destination address - increments | 151 | // Destination address - increments |
| 148 | t.tcd_daddr().write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32)); | 152 | t.tcd_daddr() |
| 153 | .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32)); | ||
| 149 | 154 | ||
| 150 | // Source offset = 0 (stays fixed), Dest offset = 4 (increments) | 155 | // Source offset = 0 (stays fixed), Dest offset = 4 (increments) |
| 151 | t.tcd_soff().write(|w| w.soff().bits(0)); | 156 | t.tcd_soff().write(|w| w.soff().bits(0)); |
| @@ -180,10 +185,11 @@ async fn main(_spawner: Spawner) { | |||
| 180 | while !dma_ch0.is_done() { | 185 | while !dma_ch0.is_done() { |
| 181 | cortex_m::asm::nop(); | 186 | cortex_m::asm::nop(); |
| 182 | } | 187 | } |
| 183 | unsafe { dma_ch0.clear_done(); } | 188 | unsafe { |
| 189 | dma_ch0.clear_done(); | ||
| 190 | } | ||
| 184 | 191 | ||
| 185 | tx.blocking_write(b"\r\nEDMA memset example finish.\r\n\r\n") | 192 | tx.blocking_write(b"\r\nEDMA memset example finish.\r\n\r\n").unwrap(); |
| 186 | .unwrap(); | ||
| 187 | tx.blocking_write(b"Destination Buffer (after): ").unwrap(); | 193 | tx.blocking_write(b"Destination Buffer (after): ").unwrap(); |
| 188 | print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH); | 194 | print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH); |
| 189 | tx.blocking_write(b"\r\n\r\n").unwrap(); | 195 | tx.blocking_write(b"\r\n\r\n").unwrap(); |
| @@ -212,4 +218,3 @@ async fn main(_spawner: Spawner) { | |||
| 212 | cortex_m::asm::wfe(); | 218 | cortex_m::asm::wfe(); |
| 213 | } | 219 | } |
| 214 | } | 220 | } |
| 215 | |||
diff --git a/examples/src/bin/dma_ping_pong_transfer.rs b/examples/src/bin/dma_ping_pong_transfer.rs index d765ea575..692515441 100644 --- a/examples/src/bin/dma_ping_pong_transfer.rs +++ b/examples/src/bin/dma_ping_pong_transfer.rs | |||
| @@ -24,12 +24,12 @@ | |||
| 24 | #![no_main] | 24 | #![no_main] |
| 25 | 25 | ||
| 26 | use core::sync::atomic::{AtomicBool, Ordering}; | 26 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 27 | |||
| 27 | use embassy_executor::Spawner; | 28 | use embassy_executor::Spawner; |
| 28 | use embassy_mcxa::clocks::config::Div8; | 29 | use embassy_mcxa::clocks::config::Div8; |
| 29 | use embassy_mcxa::dma::{self, DmaChannel, DmaCh1InterruptHandler, Tcd, TransferOptions}; | 30 | use embassy_mcxa::dma::{self, DmaCh1InterruptHandler, DmaChannel, Tcd, TransferOptions}; |
| 30 | use embassy_mcxa::bind_interrupts; | ||
| 31 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 31 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 32 | use embassy_mcxa::pac; | 32 | use embassy_mcxa::{bind_interrupts, pac}; |
| 33 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 33 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 34 | 34 | ||
| 35 | // Source and destination buffers for Approach 1 (scatter/gather) | 35 | // Source and destination buffers for Approach 1 (scatter/gather) |
| @@ -44,19 +44,21 @@ static mut DST2: [u32; 8] = [0; 8]; | |||
| 44 | #[repr(C, align(32))] | 44 | #[repr(C, align(32))] |
| 45 | struct TcdPool([Tcd; 2]); | 45 | struct TcdPool([Tcd; 2]); |
| 46 | 46 | ||
| 47 | static mut TCD_POOL: TcdPool = TcdPool([Tcd { | 47 | static mut TCD_POOL: TcdPool = TcdPool( |
| 48 | saddr: 0, | 48 | [Tcd { |
| 49 | soff: 0, | 49 | saddr: 0, |
| 50 | attr: 0, | 50 | soff: 0, |
| 51 | nbytes: 0, | 51 | attr: 0, |
| 52 | slast: 0, | 52 | nbytes: 0, |
| 53 | daddr: 0, | 53 | slast: 0, |
| 54 | doff: 0, | 54 | daddr: 0, |
| 55 | citer: 0, | 55 | doff: 0, |
| 56 | dlast_sga: 0, | 56 | citer: 0, |
| 57 | csr: 0, | 57 | dlast_sga: 0, |
| 58 | biter: 0, | 58 | csr: 0, |
| 59 | }; 2]); | 59 | biter: 0, |
| 60 | }; 2], | ||
| 61 | ); | ||
| 60 | 62 | ||
| 61 | // AtomicBool to track scatter/gather completion | 63 | // AtomicBool to track scatter/gather completion |
| 62 | // Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads, | 64 | // Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads, |
| @@ -289,7 +291,8 @@ async fn main(_spawner: Spawner) { | |||
| 289 | // - True async/await support | 291 | // - True async/await support |
| 290 | // - Good for streaming data processing | 292 | // - Good for streaming data processing |
| 291 | 293 | ||
| 292 | tx.blocking_write(b"--- Approach 2: wait_half() demo ---\r\n\r\n").unwrap(); | 294 | tx.blocking_write(b"--- Approach 2: wait_half() demo ---\r\n\r\n") |
| 295 | .unwrap(); | ||
| 293 | 296 | ||
| 294 | // Enable DMA CH1 interrupt | 297 | // Enable DMA CH1 interrupt |
| 295 | unsafe { | 298 | unsafe { |
| @@ -310,10 +313,11 @@ async fn main(_spawner: Spawner) { | |||
| 310 | 313 | ||
| 311 | // Configure transfer with half-transfer interrupt enabled | 314 | // Configure transfer with half-transfer interrupt enabled |
| 312 | let mut options = TransferOptions::default(); | 315 | let mut options = TransferOptions::default(); |
| 313 | options.half_transfer_interrupt = true; // Enable half-transfer interrupt | 316 | options.half_transfer_interrupt = true; // Enable half-transfer interrupt |
| 314 | options.complete_transfer_interrupt = true; | 317 | options.complete_transfer_interrupt = true; |
| 315 | 318 | ||
| 316 | tx.blocking_write(b"Starting transfer with half_transfer_interrupt...\r\n").unwrap(); | 319 | tx.blocking_write(b"Starting transfer with half_transfer_interrupt...\r\n") |
| 320 | .unwrap(); | ||
| 317 | 321 | ||
| 318 | unsafe { | 322 | unsafe { |
| 319 | let src = &*core::ptr::addr_of!(SRC2); | 323 | let src = &*core::ptr::addr_of!(SRC2); |
| @@ -327,10 +331,12 @@ async fn main(_spawner: Spawner) { | |||
| 327 | let half_ok = transfer.wait_half().await; | 331 | let half_ok = transfer.wait_half().await; |
| 328 | 332 | ||
| 329 | if half_ok { | 333 | if half_ok { |
| 330 | tx.blocking_write(b"Half-transfer complete! First half of DST2: ").unwrap(); | 334 | tx.blocking_write(b"Half-transfer complete! First half of DST2: ") |
| 335 | .unwrap(); | ||
| 331 | print_buffer(&mut tx, core::ptr::addr_of!(DST2) as *const u32, 4); | 336 | print_buffer(&mut tx, core::ptr::addr_of!(DST2) as *const u32, 4); |
| 332 | tx.blocking_write(b"\r\n").unwrap(); | 337 | tx.blocking_write(b"\r\n").unwrap(); |
| 333 | tx.blocking_write(b"(Processing first half while second half transfers...)\r\n").unwrap(); | 338 | tx.blocking_write(b"(Processing first half while second half transfers...)\r\n") |
| 339 | .unwrap(); | ||
| 334 | } | 340 | } |
| 335 | 341 | ||
| 336 | // Wait for complete transfer | 342 | // Wait for complete transfer |
| @@ -363,10 +369,10 @@ async fn main(_spawner: Spawner) { | |||
| 363 | defmt::info!("PASS: Approach 2 verified."); | 369 | defmt::info!("PASS: Approach 2 verified."); |
| 364 | } | 370 | } |
| 365 | 371 | ||
| 366 | tx.blocking_write(b"\r\n=== All ping-pong demos complete ===\r\n").unwrap(); | 372 | tx.blocking_write(b"\r\n=== All ping-pong demos complete ===\r\n") |
| 373 | .unwrap(); | ||
| 367 | 374 | ||
| 368 | loop { | 375 | loop { |
| 369 | cortex_m::asm::wfe(); | 376 | cortex_m::asm::wfe(); |
| 370 | } | 377 | } |
| 371 | } | 378 | } |
| 372 | |||
diff --git a/examples/src/bin/dma_scatter_gather.rs b/examples/src/bin/dma_scatter_gather.rs index d78605acc..b5ae00057 100644 --- a/examples/src/bin/dma_scatter_gather.rs +++ b/examples/src/bin/dma_scatter_gather.rs | |||
| @@ -13,12 +13,12 @@ | |||
| 13 | #![no_main] | 13 | #![no_main] |
| 14 | 14 | ||
| 15 | use core::sync::atomic::{AtomicBool, Ordering}; | 15 | use core::sync::atomic::{AtomicBool, Ordering}; |
| 16 | |||
| 16 | use embassy_executor::Spawner; | 17 | use embassy_executor::Spawner; |
| 17 | use embassy_mcxa::clocks::config::Div8; | 18 | use embassy_mcxa::clocks::config::Div8; |
| 18 | use embassy_mcxa::dma::{self, DmaChannel, Tcd}; | 19 | use embassy_mcxa::dma::{self, DmaChannel, Tcd}; |
| 19 | use embassy_mcxa::bind_interrupts; | ||
| 20 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 20 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 21 | use embassy_mcxa::pac; | 21 | use embassy_mcxa::{bind_interrupts, pac}; |
| 22 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 22 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 23 | 23 | ||
| 24 | // Source and destination buffers | 24 | // Source and destination buffers |
| @@ -29,19 +29,21 @@ static mut DST: [u32; 8] = [0; 8]; | |||
| 29 | #[repr(C, align(32))] | 29 | #[repr(C, align(32))] |
| 30 | struct TcdPool([Tcd; 2]); | 30 | struct TcdPool([Tcd; 2]); |
| 31 | 31 | ||
| 32 | static mut TCD_POOL: TcdPool = TcdPool([Tcd { | 32 | static mut TCD_POOL: TcdPool = TcdPool( |
| 33 | saddr: 0, | 33 | [Tcd { |
| 34 | soff: 0, | 34 | saddr: 0, |
| 35 | attr: 0, | 35 | soff: 0, |
| 36 | nbytes: 0, | 36 | attr: 0, |
| 37 | slast: 0, | 37 | nbytes: 0, |
| 38 | daddr: 0, | 38 | slast: 0, |
| 39 | doff: 0, | 39 | daddr: 0, |
| 40 | citer: 0, | 40 | doff: 0, |
| 41 | dlast_sga: 0, | 41 | citer: 0, |
| 42 | csr: 0, | 42 | dlast_sga: 0, |
| 43 | biter: 0, | 43 | csr: 0, |
| 44 | }; 2]); | 44 | biter: 0, |
| 45 | }; 2], | ||
| 46 | ); | ||
| 45 | 47 | ||
| 46 | // AtomicBool to track scatter/gather completion | 48 | // AtomicBool to track scatter/gather completion |
| 47 | // Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads, | 49 | // Note: With ESG=1, DONE bit is cleared by hardware when next TCD loads, |
| @@ -53,7 +55,9 @@ static TRANSFER_DONE: AtomicBool = AtomicBool::new(false); | |||
| 53 | // (delegates to HAL + sets a flag) and the main task does the actual processing | 55 | // (delegates to HAL + sets a flag) and the main task does the actual processing |
| 54 | pub struct ScatterGatherDmaHandler; | 56 | pub struct ScatterGatherDmaHandler; |
| 55 | 57 | ||
| 56 | impl embassy_mcxa::interrupt::typelevel::Handler<embassy_mcxa::interrupt::typelevel::DMA_CH0> for ScatterGatherDmaHandler { | 58 | impl embassy_mcxa::interrupt::typelevel::Handler<embassy_mcxa::interrupt::typelevel::DMA_CH0> |
| 59 | for ScatterGatherDmaHandler | ||
| 60 | { | ||
| 57 | unsafe fn on_interrupt() { | 61 | unsafe fn on_interrupt() { |
| 58 | // Delegate to HAL's on_interrupt() which clears INT flag and wakes wakers | 62 | // Delegate to HAL's on_interrupt() which clears INT flag and wakes wakers |
| 59 | dma::on_interrupt(0); | 63 | dma::on_interrupt(0); |
| @@ -161,10 +165,7 @@ async fn main(_spawner: Spawner) { | |||
| 161 | // TCD0 transfers first half (SRC[0..4] -> DST[0..4]), then loads TCD1. | 165 | // TCD0 transfers first half (SRC[0..4] -> DST[0..4]), then loads TCD1. |
| 162 | // TCD1 transfers second half (SRC[4..8] -> DST[4..8]), last TCD. | 166 | // TCD1 transfers second half (SRC[4..8] -> DST[4..8]), last TCD. |
| 163 | unsafe { | 167 | unsafe { |
| 164 | let tcds = core::slice::from_raw_parts_mut( | 168 | let tcds = core::slice::from_raw_parts_mut(core::ptr::addr_of_mut!(TCD_POOL.0) as *mut Tcd, 2); |
| 165 | core::ptr::addr_of_mut!(TCD_POOL.0) as *mut Tcd, | ||
| 166 | 2, | ||
| 167 | ); | ||
| 168 | let src_ptr = core::ptr::addr_of!(SRC) as *const u32; | 169 | let src_ptr = core::ptr::addr_of!(SRC) as *const u32; |
| 169 | let dst_ptr = core::ptr::addr_of_mut!(DST) as *mut u32; | 170 | let dst_ptr = core::ptr::addr_of_mut!(DST) as *mut u32; |
| 170 | 171 | ||
| @@ -262,4 +263,3 @@ async fn main(_spawner: Spawner) { | |||
| 262 | cortex_m::asm::wfe(); | 263 | cortex_m::asm::wfe(); |
| 263 | } | 264 | } |
| 264 | } | 265 | } |
| 265 | |||
diff --git a/examples/src/bin/dma_scatter_gather_builder.rs b/examples/src/bin/dma_scatter_gather_builder.rs index 51bfbeb67..d42ff841e 100644 --- a/examples/src/bin/dma_scatter_gather_builder.rs +++ b/examples/src/bin/dma_scatter_gather_builder.rs | |||
| @@ -22,10 +22,9 @@ | |||
| 22 | 22 | ||
| 23 | use embassy_executor::Spawner; | 23 | use embassy_executor::Spawner; |
| 24 | use embassy_mcxa::clocks::config::Div8; | 24 | use embassy_mcxa::clocks::config::Div8; |
| 25 | use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler, ScatterGatherBuilder}; | 25 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, ScatterGatherBuilder}; |
| 26 | use embassy_mcxa::bind_interrupts; | ||
| 27 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 26 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 28 | use embassy_mcxa::pac; | 27 | use embassy_mcxa::{bind_interrupts, pac}; |
| 29 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 28 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 30 | 29 | ||
| 31 | // Bind DMA channel 0 interrupt | 30 | // Bind DMA channel 0 interrupt |
| @@ -97,7 +96,8 @@ async fn main(_spawner: Spawner) { | |||
| 97 | let (mut tx, _rx) = lpuart.split(); | 96 | let (mut tx, _rx) = lpuart.split(); |
| 98 | 97 | ||
| 99 | tx.blocking_write(b"DMA Scatter-Gather Builder Example\r\n").unwrap(); | 98 | tx.blocking_write(b"DMA Scatter-Gather Builder Example\r\n").unwrap(); |
| 100 | tx.blocking_write(b"===================================\r\n\r\n").unwrap(); | 99 | tx.blocking_write(b"===================================\r\n\r\n") |
| 100 | .unwrap(); | ||
| 101 | 101 | ||
| 102 | // Show source buffers | 102 | // Show source buffers |
| 103 | tx.blocking_write(b"Source buffers:\r\n").unwrap(); | 103 | tx.blocking_write(b"Source buffers:\r\n").unwrap(); |
| @@ -125,7 +125,8 @@ async fn main(_spawner: Spawner) { | |||
| 125 | // Create DMA channel | 125 | // Create DMA channel |
| 126 | let dma_ch0 = DmaChannel::new(p.DMA_CH0); | 126 | let dma_ch0 = DmaChannel::new(p.DMA_CH0); |
| 127 | 127 | ||
| 128 | tx.blocking_write(b"Building scatter-gather chain with builder API...\r\n").unwrap(); | 128 | tx.blocking_write(b"Building scatter-gather chain with builder API...\r\n") |
| 129 | .unwrap(); | ||
| 129 | 130 | ||
| 130 | // ========================================================================= | 131 | // ========================================================================= |
| 131 | // ScatterGatherBuilder API demonstration | 132 | // ScatterGatherBuilder API demonstration |
| @@ -159,7 +160,8 @@ async fn main(_spawner: Spawner) { | |||
| 159 | } | 160 | } |
| 160 | 161 | ||
| 161 | tx.blocking_write(b"Added 3 transfer segments to chain.\r\n").unwrap(); | 162 | tx.blocking_write(b"Added 3 transfer segments to chain.\r\n").unwrap(); |
| 162 | tx.blocking_write(b"Starting scatter-gather transfer with .await...\r\n\r\n").unwrap(); | 163 | tx.blocking_write(b"Starting scatter-gather transfer with .await...\r\n\r\n") |
| 164 | .unwrap(); | ||
| 163 | 165 | ||
| 164 | // Build and execute the scatter-gather chain | 166 | // Build and execute the scatter-gather chain |
| 165 | // The build() method: | 167 | // The build() method: |
| @@ -222,7 +224,8 @@ async fn main(_spawner: Spawner) { | |||
| 222 | defmt::error!("FAIL: Mismatch detected!"); | 224 | defmt::error!("FAIL: Mismatch detected!"); |
| 223 | } | 225 | } |
| 224 | 226 | ||
| 225 | tx.blocking_write(b"\r\n=== Scatter-Gather Builder example complete ===\r\n").unwrap(); | 227 | tx.blocking_write(b"\r\n=== Scatter-Gather Builder example complete ===\r\n") |
| 228 | .unwrap(); | ||
| 226 | 229 | ||
| 227 | loop { | 230 | loop { |
| 228 | cortex_m::asm::wfe(); | 231 | cortex_m::asm::wfe(); |
diff --git a/examples/src/bin/dma_wrap_transfer.rs b/examples/src/bin/dma_wrap_transfer.rs index 8e9aedbfb..0babf4c20 100644 --- a/examples/src/bin/dma_wrap_transfer.rs +++ b/examples/src/bin/dma_wrap_transfer.rs | |||
| @@ -12,10 +12,9 @@ | |||
| 12 | 12 | ||
| 13 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| 14 | use embassy_mcxa::clocks::config::Div8; | 14 | use embassy_mcxa::clocks::config::Div8; |
| 15 | use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler}; | 15 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; |
| 16 | use embassy_mcxa::bind_interrupts; | ||
| 17 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 16 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 18 | use embassy_mcxa::pac; | 17 | use embassy_mcxa::{bind_interrupts, pac}; |
| 19 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 18 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| 20 | 19 | ||
| 21 | // Bind DMA channel 0 interrupt using Embassy-style macro | 20 | // Bind DMA channel 0 interrupt using Embassy-style macro |
| @@ -93,8 +92,7 @@ async fn main(_spawner: Spawner) { | |||
| 93 | let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); | 92 | let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap(); |
| 94 | let (mut tx, _rx) = lpuart.split(); | 93 | let (mut tx, _rx) = lpuart.split(); |
| 95 | 94 | ||
| 96 | tx.blocking_write(b"EDMA wrap transfer example begin.\r\n\r\n") | 95 | tx.blocking_write(b"EDMA wrap transfer example begin.\r\n\r\n").unwrap(); |
| 97 | .unwrap(); | ||
| 98 | 96 | ||
| 99 | // Initialize buffers | 97 | // Initialize buffers |
| 100 | unsafe { | 98 | unsafe { |
| @@ -127,18 +125,25 @@ async fn main(_spawner: Spawner) { | |||
| 127 | 125 | ||
| 128 | // Reset channel state | 126 | // Reset channel state |
| 129 | t.ch_csr().write(|w| { | 127 | t.ch_csr().write(|w| { |
| 130 | w.erq().disable() | 128 | w.erq() |
| 131 | .earq().disable() | 129 | .disable() |
| 132 | .eei().no_error() | 130 | .earq() |
| 133 | .ebw().disable() | 131 | .disable() |
| 134 | .done().clear_bit_by_one() | 132 | .eei() |
| 133 | .no_error() | ||
| 134 | .ebw() | ||
| 135 | .disable() | ||
| 136 | .done() | ||
| 137 | .clear_bit_by_one() | ||
| 135 | }); | 138 | }); |
| 136 | t.ch_es().write(|w| w.bits(0)); | 139 | t.ch_es().write(|w| w.bits(0)); |
| 137 | t.ch_int().write(|w| w.int().clear_bit_by_one()); | 140 | t.ch_int().write(|w| w.int().clear_bit_by_one()); |
| 138 | 141 | ||
| 139 | // Source/destination addresses | 142 | // Source/destination addresses |
| 140 | t.tcd_saddr().write(|w| w.saddr().bits(core::ptr::addr_of!(SRC.0) as u32)); | 143 | t.tcd_saddr() |
| 141 | t.tcd_daddr().write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DST) as u32)); | 144 | .write(|w| w.saddr().bits(core::ptr::addr_of!(SRC.0) as u32)); |
| 145 | t.tcd_daddr() | ||
| 146 | .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DST) as u32)); | ||
| 142 | 147 | ||
| 143 | // Offsets: both increment by 4 bytes | 148 | // Offsets: both increment by 4 bytes |
| 144 | t.tcd_soff().write(|w| w.soff().bits(4)); | 149 | t.tcd_soff().write(|w| w.soff().bits(4)); |
| @@ -147,10 +152,14 @@ async fn main(_spawner: Spawner) { | |||
| 147 | // Attributes: 32-bit transfers (size = 2) | 152 | // Attributes: 32-bit transfers (size = 2) |
| 148 | // SMOD = 4 (2^4 = 16 byte modulo for source), DMOD = 0 (disabled) | 153 | // SMOD = 4 (2^4 = 16 byte modulo for source), DMOD = 0 (disabled) |
| 149 | t.tcd_attr().write(|w| { | 154 | t.tcd_attr().write(|w| { |
| 150 | w.ssize().bits(2) | 155 | w.ssize() |
| 151 | .dsize().bits(2) | 156 | .bits(2) |
| 152 | .smod().bits(4) // Source modulo: 2^4 = 16 bytes | 157 | .dsize() |
| 153 | .dmod().bits(0) // Dest modulo: disabled | 158 | .bits(2) |
| 159 | .smod() | ||
| 160 | .bits(4) // Source modulo: 2^4 = 16 bytes | ||
| 161 | .dmod() | ||
| 162 | .bits(0) // Dest modulo: disabled | ||
| 154 | }); | 163 | }); |
| 155 | 164 | ||
| 156 | // Transfer 32 bytes total in one minor loop | 165 | // Transfer 32 bytes total in one minor loop |
| @@ -179,7 +188,9 @@ async fn main(_spawner: Spawner) { | |||
| 179 | while !dma_ch0.is_done() { | 188 | while !dma_ch0.is_done() { |
| 180 | cortex_m::asm::nop(); | 189 | cortex_m::asm::nop(); |
| 181 | } | 190 | } |
| 182 | unsafe { dma_ch0.clear_done(); } | 191 | unsafe { |
| 192 | dma_ch0.clear_done(); | ||
| 193 | } | ||
| 183 | 194 | ||
| 184 | tx.blocking_write(b"\r\nEDMA wrap transfer example finish.\r\n\r\n") | 195 | tx.blocking_write(b"\r\nEDMA wrap transfer example finish.\r\n\r\n") |
| 185 | .unwrap(); | 196 | .unwrap(); |
| @@ -211,4 +222,3 @@ async fn main(_spawner: Spawner) { | |||
| 211 | cortex_m::asm::wfe(); | 222 | cortex_m::asm::wfe(); |
| 212 | } | 223 | } |
| 213 | } | 224 | } |
| 214 | |||
diff --git a/examples/src/bin/lpuart_dma.rs b/examples/src/bin/lpuart_dma.rs index 4e321b111..f4dfbcf39 100644 --- a/examples/src/bin/lpuart_dma.rs +++ b/examples/src/bin/lpuart_dma.rs | |||
| @@ -48,8 +48,7 @@ async fn main(_spawner: Spawner) { | |||
| 48 | 48 | ||
| 49 | // Create UART instance with DMA channels | 49 | // Create UART instance with DMA channels |
| 50 | let mut lpuart = LpuartDma::new( | 50 | let mut lpuart = LpuartDma::new( |
| 51 | p.LPUART2, | 51 | p.LPUART2, p.P2_2, // TX pin |
| 52 | p.P2_2, // TX pin | ||
| 53 | p.P2_3, // RX pin | 52 | p.P2_3, // RX pin |
| 54 | p.DMA_CH0, // TX DMA channel | 53 | p.DMA_CH0, // TX DMA channel |
| 55 | p.DMA_CH1, // RX DMA channel | 54 | p.DMA_CH1, // RX DMA channel |
| @@ -82,4 +81,3 @@ async fn main(_spawner: Spawner) { | |||
| 82 | 81 | ||
| 83 | defmt::info!("Example complete"); | 82 | defmt::info!("Example complete"); |
| 84 | } | 83 | } |
| 85 | |||
diff --git a/examples/src/bin/lpuart_ring_buffer.rs b/examples/src/bin/lpuart_ring_buffer.rs index d71876ade..6cc14f1c7 100644 --- a/examples/src/bin/lpuart_ring_buffer.rs +++ b/examples/src/bin/lpuart_ring_buffer.rs | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | use embassy_executor::Spawner; | 21 | use embassy_executor::Spawner; |
| 22 | use embassy_mcxa::clocks::config::Div8; | 22 | use embassy_mcxa::clocks::config::Div8; |
| 23 | use embassy_mcxa::dma::{DmaChannel, DmaCh0InterruptHandler, DmaCh1InterruptHandler, DMA_REQ_LPUART2_RX}; | 23 | use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaChannel, DMA_REQ_LPUART2_RX}; |
| 24 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; | 24 | use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; |
| 25 | use embassy_mcxa::{bind_interrupts, pac}; | 25 | use embassy_mcxa::{bind_interrupts, pac}; |
| 26 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; | 26 | use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; |
| @@ -91,7 +91,8 @@ async fn main(_spawner: Spawner) { | |||
| 91 | dma_ch_rx.set_request_source(DMA_REQ_LPUART2_RX); | 91 | dma_ch_rx.set_request_source(DMA_REQ_LPUART2_RX); |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | tx.blocking_write(b"Setting up circular DMA for UART RX...\r\n").unwrap(); | 94 | tx.blocking_write(b"Setting up circular DMA for UART RX...\r\n") |
| 95 | .unwrap(); | ||
| 95 | 96 | ||
| 96 | // Set up the ring buffer with circular DMA | 97 | // Set up the ring buffer with circular DMA |
| 97 | // This configures the DMA for continuous reception | 98 | // This configures the DMA for continuous reception |
| @@ -105,8 +106,10 @@ async fn main(_spawner: Spawner) { | |||
| 105 | dma_ch_rx.enable_request(); | 106 | dma_ch_rx.enable_request(); |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | tx.blocking_write(b"Ring buffer ready! Type characters to see them echoed.\r\n").unwrap(); | 109 | tx.blocking_write(b"Ring buffer ready! Type characters to see them echoed.\r\n") |
| 109 | tx.blocking_write(b"The DMA continuously receives in the background.\r\n\r\n").unwrap(); | 110 | .unwrap(); |
| 111 | tx.blocking_write(b"The DMA continuously receives in the background.\r\n\r\n") | ||
| 112 | .unwrap(); | ||
| 110 | 113 | ||
| 111 | // Main loop: read from ring buffer and echo back | 114 | // Main loop: read from ring buffer and echo back |
| 112 | let mut read_buf = [0u8; 16]; | 115 | let mut read_buf = [0u8; 16]; |
| @@ -144,4 +147,3 @@ async fn main(_spawner: Spawner) { | |||
| 144 | } | 147 | } |
| 145 | } | 148 | } |
| 146 | } | 149 | } |
| 147 | |||
diff --git a/src/dma.rs b/src/dma.rs index 66b610d93..7bfc95752 100644 --- a/src/dma.rs +++ b/src/dma.rs | |||
| @@ -107,12 +107,13 @@ use core::ptr::NonNull; | |||
| 107 | use core::sync::atomic::{fence, AtomicBool, AtomicUsize, Ordering}; | 107 | use core::sync::atomic::{fence, AtomicBool, AtomicUsize, Ordering}; |
| 108 | use core::task::{Context, Poll}; | 108 | use core::task::{Context, Poll}; |
| 109 | 109 | ||
| 110 | use embassy_hal_internal::PeripheralType; | ||
| 111 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 112 | |||
| 110 | use crate::clocks::Gate; | 113 | use crate::clocks::Gate; |
| 111 | use crate::pac; | 114 | use crate::pac; |
| 112 | use crate::pac::Interrupt; | 115 | use crate::pac::Interrupt; |
| 113 | use crate::peripherals::DMA0; | 116 | use crate::peripherals::DMA0; |
| 114 | use embassy_hal_internal::PeripheralType; | ||
| 115 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 116 | 117 | ||
| 117 | /// Static flag to track whether DMA has been initialized. | 118 | /// Static flag to track whether DMA has been initialized. |
| 118 | static DMA_INITIALIZED: AtomicBool = AtomicBool::new(false); | 119 | static DMA_INITIALIZED: AtomicBool = AtomicBool::new(false); |
