diff options
Diffstat (limited to 'examples/src/bin/dma_channel_link.rs')
| -rw-r--r-- | examples/src/bin/dma_channel_link.rs | 88 |
1 files changed, 56 insertions, 32 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 | |||
