aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-12-08 17:58:00 +0100
committerJames Munns <[email protected]>2025-12-08 17:58:00 +0100
commit6680ef22fa4b46adb4cda46d6cdbc9dac39dc78c (patch)
tree367bfba7c960798db8f5813629e5bb206158e80c
parent5d8f3a3d18eda339e258193295cf332d7e01882e (diff)
Clean up examples, move interrupts to be more fully managed
-rw-r--r--embassy-mcxa/src/dma.rs58
-rw-r--r--embassy-mcxa/src/lib.rs35
-rw-r--r--examples/mcxa/src/bin/adc_interrupt.rs4
-rw-r--r--examples/mcxa/src/bin/adc_polling.rs2
-rw-r--r--examples/mcxa/src/bin/dma_channel_link.rs21
-rw-r--r--examples/mcxa/src/bin/dma_interleave_transfer.rs58
-rw-r--r--examples/mcxa/src/bin/dma_mem_to_mem.rs81
-rw-r--r--examples/mcxa/src/bin/dma_memset.rs97
-rw-r--r--examples/mcxa/src/bin/dma_ping_pong_transfer.rs5
-rw-r--r--examples/mcxa/src/bin/dma_scatter_gather.rs3
-rw-r--r--examples/mcxa/src/bin/dma_scatter_gather_builder.rs16
-rw-r--r--examples/mcxa/src/bin/dma_wrap_transfer.rs16
-rw-r--r--examples/mcxa/src/bin/i2c-async.rs2
-rw-r--r--examples/mcxa/src/bin/i2c-scan-blocking.rs2
-rw-r--r--examples/mcxa/src/bin/lpuart_buffered.rs2
-rw-r--r--examples/mcxa/src/bin/lpuart_dma.rs11
-rw-r--r--examples/mcxa/src/bin/lpuart_ring_buffer.rs8
17 files changed, 93 insertions, 328 deletions
diff --git a/embassy-mcxa/src/dma.rs b/embassy-mcxa/src/dma.rs
index b3ea94dbf..07500e9a2 100644
--- a/embassy-mcxa/src/dma.rs
+++ b/embassy-mcxa/src/dma.rs
@@ -618,16 +618,9 @@ impl<C: Channel> DmaChannel<C> {
618 /// Note: DMA is initialized during `hal::init()` via `dma::init()`. 618 /// Note: DMA is initialized during `hal::init()` via `dma::init()`.
619 #[inline] 619 #[inline]
620 pub fn new(_ch: embassy_hal_internal::Peri<'_, C>) -> Self { 620 pub fn new(_ch: embassy_hal_internal::Peri<'_, C>) -> Self {
621 Self { 621 unsafe {
622 _ch: core::marker::PhantomData, 622 cortex_m::peripheral::NVIC::unmask(C::INTERRUPT);
623 } 623 }
624 }
625
626 /// Wrap a DMA channel token directly (for internal use).
627 ///
628 /// Note: DMA is initialized during `hal::init()` via `dma::init()`.
629 #[inline]
630 pub fn from_token(_ch: C) -> Self {
631 Self { 624 Self {
632 _ch: core::marker::PhantomData, 625 _ch: core::marker::PhantomData,
633 } 626 }
@@ -740,7 +733,8 @@ impl<C: Channel> DmaChannel<C> {
740 #[inline] 733 #[inline]
741 fn set_even_transfer_size(t: &'static pac::edma_0_tcd0::Tcd, sz: WordSize) { 734 fn set_even_transfer_size(t: &'static pac::edma_0_tcd0::Tcd, sz: WordSize) {
742 let hw_size = sz.to_hw_size(); 735 let hw_size = sz.to_hw_size();
743 t.tcd_attr().write(|w| unsafe { w.ssize().bits(hw_size).dsize().bits(hw_size) } ); 736 t.tcd_attr()
737 .write(|w| unsafe { w.ssize().bits(hw_size).dsize().bits(hw_size) });
744 } 738 }
745 739
746 #[inline] 740 #[inline]
@@ -1068,7 +1062,7 @@ impl<C: Channel> DmaChannel<C> {
1068 1062
1069 // Addresses 1063 // Addresses
1070 Self::set_source_ptr(t, buf.as_ptr()); 1064 Self::set_source_ptr(t, buf.as_ptr());
1071 t.tcd_daddr().write(|w| w.daddr().bits(peri_addr as u32)); 1065 Self::set_dest_ptr(t, peri_addr);
1072 1066
1073 // Offsets: Source increments, Dest fixed 1067 // Offsets: Source increments, Dest fixed
1074 Self::set_source_increment(t, size); 1068 Self::set_source_increment(t, size);
@@ -2357,7 +2351,7 @@ impl<W: Word> ScatterGatherBuilder<W> {
2357 2351
2358 // Reset channel state - clear DONE, disable requests, clear errors 2352 // Reset channel state - clear DONE, disable requests, clear errors
2359 // This ensures the channel is in a clean state before loading the TCD 2353 // This ensures the channel is in a clean state before loading the TCD
2360 Self::reset_channel_state(t); 2354 DmaChannel::<C>::reset_channel_state(t);
2361 2355
2362 // Memory barrier to ensure channel state is reset before loading TCD 2356 // Memory barrier to ensure channel state is reset before loading TCD
2363 cortex_m::asm::dsb(); 2357 cortex_m::asm::dsb();
@@ -2441,38 +2435,28 @@ pub unsafe fn on_interrupt(ch_index: usize) {
2441} 2435}
2442 2436
2443// ============================================================================ 2437// ============================================================================
2444// Type-level Interrupt Handlers for bind_interrupts! macro 2438// Type-level Interrupt Handlers
2445// ============================================================================ 2439// ============================================================================
2446 2440
2447/// Macro to generate DMA channel interrupt handlers. 2441/// Macro to generate DMA channel interrupt handlers.
2448///
2449/// This generates handler structs that implement the `Handler` trait for use
2450/// with the `bind_interrupts!` macro.
2451macro_rules! impl_dma_interrupt_handler { 2442macro_rules! impl_dma_interrupt_handler {
2452 ($name:ident, $irq:ident, $ch:expr) => { 2443 ($irq:ident, $ch:expr) => {
2453 /// Interrupt handler for DMA channel. 2444 #[interrupt]
2454 /// 2445 fn $irq() {
2455 /// Use this with the `bind_interrupts!` macro: 2446 unsafe {
2456 /// ```ignore
2457 /// bind_interrupts!(struct Irqs {
2458 #[doc = concat!(" ", stringify!($irq), " => dma::", stringify!($name), ";")]
2459 /// });
2460 /// ```
2461 pub struct $name;
2462
2463 impl crate::interrupt::typelevel::Handler<crate::interrupt::typelevel::$irq> for $name {
2464 unsafe fn on_interrupt() {
2465 on_interrupt($ch); 2447 on_interrupt($ch);
2466 } 2448 }
2467 } 2449 }
2468 }; 2450 };
2469} 2451}
2470 2452
2471impl_dma_interrupt_handler!(DmaCh0InterruptHandler, DMA_CH0, 0); 2453use crate::pac::interrupt;
2472impl_dma_interrupt_handler!(DmaCh1InterruptHandler, DMA_CH1, 1); 2454
2473impl_dma_interrupt_handler!(DmaCh2InterruptHandler, DMA_CH2, 2); 2455impl_dma_interrupt_handler!(DMA_CH0, 0);
2474impl_dma_interrupt_handler!(DmaCh3InterruptHandler, DMA_CH3, 3); 2456impl_dma_interrupt_handler!(DMA_CH1, 1);
2475impl_dma_interrupt_handler!(DmaCh4InterruptHandler, DMA_CH4, 4); 2457impl_dma_interrupt_handler!(DMA_CH2, 2);
2476impl_dma_interrupt_handler!(DmaCh5InterruptHandler, DMA_CH5, 5); 2458impl_dma_interrupt_handler!(DMA_CH3, 3);
2477impl_dma_interrupt_handler!(DmaCh6InterruptHandler, DMA_CH6, 6); 2459impl_dma_interrupt_handler!(DMA_CH4, 4);
2478impl_dma_interrupt_handler!(DmaCh7InterruptHandler, DMA_CH7, 7); 2460impl_dma_interrupt_handler!(DMA_CH5, 5);
2461impl_dma_interrupt_handler!(DMA_CH6, 6);
2462impl_dma_interrupt_handler!(DMA_CH7, 7);
diff --git a/embassy-mcxa/src/lib.rs b/embassy-mcxa/src/lib.rs
index 23cda7511..724f99234 100644
--- a/embassy-mcxa/src/lib.rs
+++ b/embassy-mcxa/src/lib.rs
@@ -400,41 +400,6 @@ pub fn init(cfg: crate::config::Config) -> Peripherals {
400 peripherals 400 peripherals
401} 401}
402 402
403// /// Optional hook called by cortex-m-rt before RAM init.
404// /// We proactively mask and clear all NVIC IRQs to avoid wedges from stale state
405// /// left by soft resets/debug sessions.
406// ///
407// /// NOTE: Manual VTOR setup is required for RAM execution. The cortex-m-rt 'set-vtor'
408// /// feature is incompatible with our setup because it expects __vector_table to be
409// /// defined differently than how our RAM-based linker script arranges it.
410// #[no_mangle]
411// pub unsafe extern "C" fn __pre_init() {
412// // Set the VTOR to point to the interrupt vector table in RAM
413// // This is required since code runs from RAM on this MCU
414// crate::interrupt::vtor_set_ram_vector_base(0x2000_0000 as *const u32);
415
416// // Mask and clear pending for all NVIC lines (0..127) to avoid stale state across runs.
417// let nvic = &*cortex_m::peripheral::NVIC::PTR;
418// for i in 0..4 {
419// // 4 words x 32 = 128 IRQs
420// nvic.icer[i].write(0xFFFF_FFFF);
421// nvic.icpr[i].write(0xFFFF_FFFF);
422// }
423// // Do NOT touch peripheral registers here: clocks may be off and accesses can fault.
424// crate::interrupt::clear_default_handler_snapshot();
425// }
426
427/// Internal helper to dispatch a type-level interrupt handler.
428#[inline(always)]
429#[doc(hidden)]
430pub unsafe fn __handle_interrupt<T, H>()
431where
432 T: crate::interrupt::typelevel::Interrupt,
433 H: crate::interrupt::typelevel::Handler<T>,
434{
435 H::on_interrupt();
436}
437
438/// Macro to bind interrupts to handlers, similar to embassy-imxrt. 403/// Macro to bind interrupts to handlers, similar to embassy-imxrt.
439/// 404///
440/// Example: 405/// Example:
diff --git a/examples/mcxa/src/bin/adc_interrupt.rs b/examples/mcxa/src/bin/adc_interrupt.rs
index c88b1fe8d..83d8046b3 100644
--- a/examples/mcxa/src/bin/adc_interrupt.rs
+++ b/examples/mcxa/src/bin/adc_interrupt.rs
@@ -4,13 +4,13 @@
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa_examples::init_adc_pins; 5use embassy_mcxa_examples::init_adc_pins;
6use hal::adc::{LpadcConfig, TriggerPriorityPolicy}; 6use hal::adc::{LpadcConfig, TriggerPriorityPolicy};
7use hal::clocks::PoweredClock;
8use hal::clocks::periph_helpers::{AdcClockSel, Div4}; 7use hal::clocks::periph_helpers::{AdcClockSel, Div4};
8use hal::clocks::PoweredClock;
9use hal::pac::adc1::cfg::{Pwrsel, Refsel}; 9use hal::pac::adc1::cfg::{Pwrsel, Refsel};
10use hal::pac::adc1::cmdl1::{Adch, Mode}; 10use hal::pac::adc1::cmdl1::{Adch, Mode};
11use hal::pac::adc1::ctrl::CalAvgs; 11use hal::pac::adc1::ctrl::CalAvgs;
12use hal::pac::adc1::tctrl::Tcmd; 12use hal::pac::adc1::tctrl::Tcmd;
13use hal::{InterruptExt, bind_interrupts}; 13use hal::{bind_interrupts, InterruptExt};
14use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 14use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
15 15
16bind_interrupts!(struct Irqs { 16bind_interrupts!(struct Irqs {
diff --git a/examples/mcxa/src/bin/adc_polling.rs b/examples/mcxa/src/bin/adc_polling.rs
index 07c50f224..ddf3f586b 100644
--- a/examples/mcxa/src/bin/adc_polling.rs
+++ b/examples/mcxa/src/bin/adc_polling.rs
@@ -4,8 +4,8 @@
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa_examples::init_adc_pins; 5use embassy_mcxa_examples::init_adc_pins;
6use hal::adc::{ConvResult, LpadcConfig, TriggerPriorityPolicy}; 6use hal::adc::{ConvResult, LpadcConfig, TriggerPriorityPolicy};
7use hal::clocks::PoweredClock;
8use hal::clocks::periph_helpers::{AdcClockSel, Div4}; 7use hal::clocks::periph_helpers::{AdcClockSel, Div4};
8use hal::clocks::PoweredClock;
9use hal::pac::adc1::cfg::{Pwrsel, Refsel}; 9use hal::pac::adc1::cfg::{Pwrsel, Refsel};
10use hal::pac::adc1::cmdl1::{Adch, Mode}; 10use hal::pac::adc1::cmdl1::{Adch, Mode};
11use hal::pac::adc1::ctrl::CalAvgs; 11use hal::pac::adc1::ctrl::CalAvgs;
diff --git a/examples/mcxa/src/bin/dma_channel_link.rs b/examples/mcxa/src/bin/dma_channel_link.rs
index f7ab5d8fd..2d757a636 100644
--- a/examples/mcxa/src/bin/dma_channel_link.rs
+++ b/examples/mcxa/src/bin/dma_channel_link.rs
@@ -16,13 +16,14 @@
16#![no_std] 16#![no_std]
17#![no_main] 17#![no_main]
18 18
19use core::fmt::Write as _;
20
19use embassy_executor::Spawner; 21use embassy_executor::Spawner;
20use embassy_mcxa::clocks::config::Div8; 22use embassy_mcxa::clocks::config::Div8;
21use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler, DmaCh2InterruptHandler, DmaChannel}; 23use embassy_mcxa::dma::DmaChannel;
22use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 24use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
23use embassy_mcxa::{bind_interrupts, pac}; 25use embassy_mcxa::pac;
24use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 26use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
25use core::fmt::Write as _;
26 27
27// Buffers 28// Buffers
28static mut SRC_BUFFER: [u32; 4] = [1, 2, 3, 4]; 29static mut SRC_BUFFER: [u32; 4] = [1, 2, 3, 4];
@@ -30,14 +31,6 @@ static mut DEST_BUFFER0: [u32; 4] = [0; 4];
30static mut DEST_BUFFER1: [u32; 4] = [0; 4]; 31static mut DEST_BUFFER1: [u32; 4] = [0; 4];
31static mut DEST_BUFFER2: [u32; 4] = [0; 4]; 32static mut DEST_BUFFER2: [u32; 4] = [0; 4];
32 33
33// Bind DMA channel interrupts using Embassy-style macro
34// The standard handlers call on_interrupt() which wakes wakers and clears flags
35bind_interrupts!(struct Irqs {
36 DMA_CH0 => DmaCh0InterruptHandler;
37 DMA_CH1 => DmaCh1InterruptHandler;
38 DMA_CH2 => DmaCh2InterruptHandler;
39});
40
41/// Helper to print a buffer to UART 34/// Helper to print a buffer to UART
42fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) { 35fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) {
43 write!(tx, "{:?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok(); 36 write!(tx, "{:?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok();
@@ -84,12 +77,6 @@ async fn main(_spawner: Spawner) {
84 .normal_operation() 77 .normal_operation()
85 }); 78 });
86 79
87 unsafe {
88 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH0);
89 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH1);
90 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH2);
91 }
92
93 let config = Config { 80 let config = Config {
94 baudrate_bps: 115_200, 81 baudrate_bps: 115_200,
95 ..Default::default() 82 ..Default::default()
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
13use core::fmt::Write as _;
14
13use embassy_executor::Spawner; 15use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 16use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; 17use embassy_mcxa::dma::DmaChannel;
16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 18use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
17use embassy_mcxa::{bind_interrupts, pac}; 19use static_cell::ConstStaticCell;
18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 20use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
19use core::fmt::Write as _;
20
21// Bind DMA channel 0 interrupt using Embassy-style macro
22bind_interrupts!(struct Irqs {
23 DMA_CH0 => DmaCh0InterruptHandler;
24});
25 21
26const BUFFER_LENGTH: usize = 16; 22const BUFFER_LENGTH: usize = 16;
27const HALF_BUFF_LENGTH: usize = BUFFER_LENGTH / 2; 23const HALF_BUFF_LENGTH: usize = BUFFER_LENGTH / 2;
28 24
29// Buffers in RAM 25// Buffers in RAM
30static mut SRC_BUFFER: [u32; HALF_BUFF_LENGTH] = [0; HALF_BUFF_LENGTH]; 26static SRC_BUFFER: ConstStaticCell<[u32; HALF_BUFF_LENGTH]> = ConstStaticCell::new([0; HALF_BUFF_LENGTH]);
31static mut DEST_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; 27static 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
34fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) { 30fn 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 {
diff --git a/examples/mcxa/src/bin/dma_mem_to_mem.rs b/examples/mcxa/src/bin/dma_mem_to_mem.rs
index b78745464..b20068b79 100644
--- a/examples/mcxa/src/bin/dma_mem_to_mem.rs
+++ b/examples/mcxa/src/bin/dma_mem_to_mem.rs
@@ -15,17 +15,9 @@
15 15
16use embassy_executor::Spawner; 16use embassy_executor::Spawner;
17use embassy_mcxa::clocks::config::Div8; 17use embassy_mcxa::clocks::config::Div8;
18use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, TransferOptions}; 18use embassy_mcxa::dma::{DmaChannel, TransferOptions};
19use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
20use embassy_mcxa::{bind_interrupts, pac};
21use static_cell::ConstStaticCell; 19use static_cell::ConstStaticCell;
22use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 20use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
23use core::fmt::Write as _;
24
25// Bind DMA channel 0 interrupt using Embassy-style macro
26bind_interrupts!(struct Irqs {
27 DMA_CH0 => DmaCh0InterruptHandler;
28});
29 21
30const BUFFER_LENGTH: usize = 4; 22const BUFFER_LENGTH: usize = 4;
31 23
@@ -34,12 +26,6 @@ static SRC_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new(
34static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]); 26static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
35static MEMSET_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]); 27static MEMSET_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
36 28
37/// Helper to print a buffer as [v1, v2, v3, v4] to UART
38/// Takes a raw pointer to avoid warnings about shared references to mutable statics
39fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: &[u32; BUFFER_LENGTH]) {
40 write!(tx, "{:?}", buf_ptr).ok();
41}
42
43#[embassy_executor::main] 29#[embassy_executor::main]
44async fn main(_spawner: Spawner) { 30async fn main(_spawner: Spawner) {
45 // Small delay to allow probe-rs to attach after reset 31 // Small delay to allow probe-rs to attach after reset
@@ -54,37 +40,15 @@ async fn main(_spawner: Spawner) {
54 40
55 defmt::info!("DMA memory-to-memory example starting..."); 41 defmt::info!("DMA memory-to-memory example starting...");
56 42
57 // Enable DMA interrupt (DMA clock/reset/init is handled automatically by HAL) 43 defmt::info!("EDMA memory to memory example begin.");
58 unsafe {
59 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH0);
60 }
61
62 // Create UART for debug output
63 let config = Config {
64 baudrate_bps: 115_200,
65 ..Default::default()
66 };
67
68 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap();
69 let (mut tx, _rx) = lpuart.split();
70
71 tx.blocking_write(b"EDMA memory to memory example begin.\r\n\r\n")
72 .unwrap();
73 44
74 let src = SRC_BUFFER.take(); 45 let src = SRC_BUFFER.take();
75 let dst = DEST_BUFFER.take(); 46 let dst = DEST_BUFFER.take();
76 let mst = MEMSET_BUFFER.take(); 47 let mst = MEMSET_BUFFER.take();
77 48
78 tx.blocking_write(b"Source Buffer: ").unwrap(); 49 defmt::info!("Source Buffer: {=[?]}", src.as_slice());
79 print_buffer(&mut tx, src); 50 defmt::info!("Destination Buffer (before): {=[?]}", dst.as_slice());
80 tx.blocking_write(b"\r\n").unwrap(); 51 defmt::info!("Configuring DMA with Embassy-style API...");
81
82 tx.blocking_write(b"Destination Buffer (before): ").unwrap();
83 print_buffer(&mut tx, dst);
84 tx.blocking_write(b"\r\n").unwrap();
85
86 tx.blocking_write(b"Configuring DMA with Embassy-style API...\r\n")
87 .unwrap();
88 52
89 // Create DMA channel 53 // Create DMA channel
90 let dma_ch0 = DmaChannel::new(p.DMA_CH0); 54 let dma_ch0 = DmaChannel::new(p.DMA_CH0);
@@ -109,19 +73,13 @@ async fn main(_spawner: Spawner) {
109 let transfer = dma_ch0.mem_to_mem(src, dst, options); 73 let transfer = dma_ch0.mem_to_mem(src, dst, options);
110 transfer.await; 74 transfer.await;
111 75
112 tx.blocking_write(b"DMA mem-to-mem transfer complete!\r\n\r\n").unwrap(); 76 defmt::info!("DMA mem-to-mem transfer complete!");
113 tx.blocking_write(b"Destination Buffer (after): ").unwrap(); 77 defmt::info!("Destination Buffer (after): {=[?]}", dst.as_slice());
114 print_buffer(&mut tx, dst);
115 tx.blocking_write(b"\r\n").unwrap();
116 78
117 // Verify data 79 // Verify data
118 let mut mismatch = src != dst; 80 if src != dst {
119
120 if mismatch {
121 tx.blocking_write(b"FAIL: mem_to_mem mismatch!\r\n").unwrap();
122 defmt::error!("FAIL: mem_to_mem mismatch!"); 81 defmt::error!("FAIL: mem_to_mem mismatch!");
123 } else { 82 } else {
124 tx.blocking_write(b"PASS: mem_to_mem verified.\r\n\r\n").unwrap();
125 defmt::info!("PASS: mem_to_mem verified."); 83 defmt::info!("PASS: mem_to_mem verified.");
126 } 84 }
127 85
@@ -134,36 +92,27 @@ async fn main(_spawner: Spawner) {
134 // - Incrementing destination address 92 // - Incrementing destination address
135 // - Uses the same Transfer future pattern 93 // - Uses the same Transfer future pattern
136 94
137 tx.blocking_write(b"--- Demonstrating memset() feature ---\r\n\r\n") 95 defmt::info!("--- Demonstrating memset() feature ---");
138 .unwrap();
139 96
140 tx.blocking_write(b"Memset Buffer (before): ").unwrap(); 97 defmt::info!("Memset Buffer (before): {=[?]}", mst.as_slice());
141 print_buffer(&mut tx, mst);
142 tx.blocking_write(b"\r\n").unwrap();
143 98
144 // Fill buffer with a pattern value using DMA memset 99 // Fill buffer with a pattern value using DMA memset
145 let pattern: u32 = 0xDEADBEEF; 100 let pattern: u32 = 0xDEADBEEF;
146 tx.blocking_write(b"Filling with pattern 0xDEADBEEF...\r\n").unwrap(); 101 defmt::info!("Filling with pattern 0xDEADBEEF...");
147 102
148 // Using blocking_wait() for demonstration - also shows non-async usage 103 // Using blocking_wait() for demonstration - also shows non-async usage
149 let transfer = dma_ch0.memset(&pattern, mst, options); 104 let transfer = dma_ch0.memset(&pattern, mst, options);
150 transfer.blocking_wait(); 105 transfer.blocking_wait();
151 106
152 tx.blocking_write(b"DMA memset complete!\r\n\r\n").unwrap(); 107 defmt::info!("DMA memset complete!");
153 tx.blocking_write(b"Memset Buffer (after): ").unwrap(); 108 defmt::info!("Memset Buffer (after): {=[?]}", mst.as_slice());
154 print_buffer(&mut tx, mst);
155 tx.blocking_write(b"\r\n").unwrap();
156 109
157 // Verify memset result 110 // Verify memset result
158 let memset_ok = mst.iter().all(|&v| v == pattern); 111 if !mst.iter().all(|&v| v == pattern) {
159
160 if !memset_ok {
161 tx.blocking_write(b"FAIL: memset mismatch!\r\n").unwrap();
162 defmt::error!("FAIL: memset mismatch!"); 112 defmt::error!("FAIL: memset mismatch!");
163 } else { 113 } else {
164 tx.blocking_write(b"PASS: memset verified.\r\n\r\n").unwrap();
165 defmt::info!("PASS: memset verified."); 114 defmt::info!("PASS: memset verified.");
166 } 115 }
167 116
168 tx.blocking_write(b"=== All DMA tests complete ===\r\n").unwrap(); 117 defmt::info!("=== All DMA tests complete ===");
169} 118}
diff --git a/examples/mcxa/src/bin/dma_memset.rs b/examples/mcxa/src/bin/dma_memset.rs
index bc4e78701..d7b03e91b 100644
--- a/examples/mcxa/src/bin/dma_memset.rs
+++ b/examples/mcxa/src/bin/dma_memset.rs
@@ -12,27 +12,15 @@
12 12
13use embassy_executor::Spawner; 13use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 14use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; 15use embassy_mcxa::dma::DmaChannel;
16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 16use static_cell::ConstStaticCell;
17use embassy_mcxa::{bind_interrupts, pac};
18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 17use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
19use core::fmt::Write as _;
20
21// Bind DMA channel 0 interrupt using Embassy-style macro
22bind_interrupts!(struct Irqs {
23 DMA_CH0 => DmaCh0InterruptHandler;
24});
25 18
26const BUFFER_LENGTH: usize = 4; 19const BUFFER_LENGTH: usize = 4;
27 20
28// Buffers in RAM 21// Buffers in RAM
29static mut PATTERN: u32 = 0; 22static PATTERN: u32 = 0xDEADBEEF;
30static mut DEST_BUFFER: [u32; BUFFER_LENGTH] = [0; BUFFER_LENGTH]; 23static DEST_BUFFER: ConstStaticCell<[u32; BUFFER_LENGTH]> = ConstStaticCell::new([0; BUFFER_LENGTH]);
31
32/// Helper to print a buffer to UART
33fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) {
34 write!(tx, "{:?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok();
35}
36 24
37#[embassy_executor::main] 25#[embassy_executor::main]
38async fn main(_spawner: Spawner) { 26async fn main(_spawner: Spawner) {
@@ -47,48 +35,14 @@ async fn main(_spawner: Spawner) {
47 let p = hal::init(cfg); 35 let p = hal::init(cfg);
48 36
49 defmt::info!("DMA memset example starting..."); 37 defmt::info!("DMA memset example starting...");
50 38 defmt::info!("EDMA memset example begin.");
51 // Enable DMA interrupt (DMA clock/reset/init is handled automatically by HAL)
52 unsafe {
53 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH0);
54 }
55
56 let config = Config {
57 baudrate_bps: 115_200,
58 ..Default::default()
59 };
60
61 let lpuart = Lpuart::new_blocking(p.LPUART2, p.P2_2, p.P2_3, config).unwrap();
62 let (mut tx, _rx) = lpuart.split();
63
64 tx.blocking_write(b"EDMA memset example begin.\r\n\r\n").unwrap();
65 39
66 // Initialize buffers 40 // Initialize buffers
67 unsafe { 41 let pat = &PATTERN;
68 PATTERN = 0xDEADBEEF; 42 let dst = DEST_BUFFER.take();
69 DEST_BUFFER = [0; BUFFER_LENGTH]; 43 defmt::info!("Pattern Value: {=u32}", pat);
70 } 44 defmt::info!("Destination Buffer (before): {=[?]}", dst.as_slice());
71 45 defmt::info!("Configuring DMA with Embassy-style API...");
72 tx.blocking_write(b"Pattern value: 0x").unwrap();
73 // Print pattern in hex
74 unsafe {
75 let hex_chars = b"0123456789ABCDEF";
76 let mut hex_buf = [0u8; 8];
77 let mut val = PATTERN;
78 for i in (0..8).rev() {
79 hex_buf[i] = hex_chars[(val & 0xF) as usize];
80 val >>= 4;
81 }
82 tx.blocking_write(&hex_buf).ok();
83 }
84 tx.blocking_write(b"\r\n").unwrap();
85
86 tx.blocking_write(b"Destination Buffer (before): ").unwrap();
87 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH);
88 tx.blocking_write(b"\r\n").unwrap();
89
90 tx.blocking_write(b"Configuring DMA with Embassy-style API...\r\n")
91 .unwrap();
92 46
93 // Create DMA channel using Embassy-style API 47 // Create DMA channel using Embassy-style API
94 let dma_ch0 = DmaChannel::new(p.DMA_CH0); 48 let dma_ch0 = DmaChannel::new(p.DMA_CH0);
@@ -116,11 +70,9 @@ async fn main(_spawner: Spawner) {
116 t.ch_int().write(|w| w.int().clear_bit_by_one()); 70 t.ch_int().write(|w| w.int().clear_bit_by_one());
117 71
118 // Source address (pattern) - fixed 72 // Source address (pattern) - fixed
119 t.tcd_saddr() 73 t.tcd_saddr().write(|w| w.saddr().bits(pat as *const _ as u32));
120 .write(|w| w.saddr().bits(core::ptr::addr_of_mut!(PATTERN) as u32));
121 // Destination address - increments 74 // Destination address - increments
122 t.tcd_daddr() 75 t.tcd_daddr().write(|w| w.daddr().bits(dst.as_mut_ptr() as u32));
123 .write(|w| w.daddr().bits(core::ptr::addr_of_mut!(DEST_BUFFER) as u32));
124 76
125 // Source offset = 0 (stays fixed), Dest offset = 4 (increments) 77 // Source offset = 0 (stays fixed), Dest offset = 4 (increments)
126 t.tcd_soff().write(|w| w.soff().bits(0)); 78 t.tcd_soff().write(|w| w.soff().bits(0));
@@ -147,7 +99,7 @@ async fn main(_spawner: Spawner) {
147 99
148 cortex_m::asm::dsb(); 100 cortex_m::asm::dsb();
149 101
150 tx.blocking_write(b"Triggering transfer...\r\n").unwrap(); 102 defmt::info!("Triggering transfer...");
151 dma_ch0.trigger_start(); 103 dma_ch0.trigger_start();
152 } 104 }
153 105
@@ -159,32 +111,15 @@ async fn main(_spawner: Spawner) {
159 dma_ch0.clear_done(); 111 dma_ch0.clear_done();
160 } 112 }
161 113
162 tx.blocking_write(b"\r\nEDMA memset example finish.\r\n\r\n").unwrap(); 114 defmt::info!("EDMA memset example finish.");
163 tx.blocking_write(b"Destination Buffer (after): ").unwrap(); 115 defmt::info!("Destination Buffer (after): {=[?]}", dst.as_slice());
164 print_buffer(&mut tx, core::ptr::addr_of!(DEST_BUFFER) as *const u32, BUFFER_LENGTH);
165 tx.blocking_write(b"\r\n\r\n").unwrap();
166 116
167 // Verify: All elements should equal PATTERN 117 // Verify: All elements should equal PATTERN
168 let mut mismatch = false; 118 let mismatch = dst.iter().any(|i| *i != *pat);
169 unsafe {
170 #[allow(clippy::needless_range_loop)]
171 for i in 0..BUFFER_LENGTH {
172 if DEST_BUFFER[i] != PATTERN {
173 mismatch = true;
174 break;
175 }
176 }
177 }
178 119
179 if mismatch { 120 if mismatch {
180 tx.blocking_write(b"FAIL: Mismatch detected!\r\n").unwrap();
181 defmt::error!("FAIL: Mismatch detected!"); 121 defmt::error!("FAIL: Mismatch detected!");
182 } else { 122 } else {
183 tx.blocking_write(b"PASS: Data verified.\r\n").unwrap();
184 defmt::info!("PASS: Data verified."); 123 defmt::info!("PASS: Data verified.");
185 } 124 }
186
187 loop {
188 cortex_m::asm::wfe();
189 }
190} 125}
diff --git a/examples/mcxa/src/bin/dma_ping_pong_transfer.rs b/examples/mcxa/src/bin/dma_ping_pong_transfer.rs
index 728e4d408..58f643b80 100644
--- a/examples/mcxa/src/bin/dma_ping_pong_transfer.rs
+++ b/examples/mcxa/src/bin/dma_ping_pong_transfer.rs
@@ -23,15 +23,15 @@
23#![no_std] 23#![no_std]
24#![no_main] 24#![no_main]
25 25
26use core::fmt::Write as _;
26use core::sync::atomic::{AtomicBool, Ordering}; 27use core::sync::atomic::{AtomicBool, Ordering};
27 28
28use embassy_executor::Spawner; 29use embassy_executor::Spawner;
29use embassy_mcxa::clocks::config::Div8; 30use embassy_mcxa::clocks::config::Div8;
30use embassy_mcxa::dma::{self, DmaCh1InterruptHandler, DmaChannel, Tcd, TransferOptions}; 31use embassy_mcxa::dma::{self, DmaChannel, Tcd, TransferOptions};
31use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 32use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
32use embassy_mcxa::{bind_interrupts, pac}; 33use embassy_mcxa::{bind_interrupts, pac};
33use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 34use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
34use core::fmt::Write as _;
35 35
36// Source and destination buffers for Approach 1 (scatter/gather) 36// Source and destination buffers for Approach 1 (scatter/gather)
37static mut SRC: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; 37static mut SRC: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
@@ -85,7 +85,6 @@ impl embassy_mcxa::interrupt::typelevel::Handler<embassy_mcxa::interrupt::typele
85// CH1: Standard handler for wait_half() demo 85// CH1: Standard handler for wait_half() demo
86bind_interrupts!(struct Irqs { 86bind_interrupts!(struct Irqs {
87 DMA_CH0 => PingPongDmaHandler; 87 DMA_CH0 => PingPongDmaHandler;
88 DMA_CH1 => DmaCh1InterruptHandler;
89}); 88});
90 89
91/// Helper to print a buffer to UART 90/// Helper to print a buffer to UART
diff --git a/examples/mcxa/src/bin/dma_scatter_gather.rs b/examples/mcxa/src/bin/dma_scatter_gather.rs
index ea553b843..3e34e95b1 100644
--- a/examples/mcxa/src/bin/dma_scatter_gather.rs
+++ b/examples/mcxa/src/bin/dma_scatter_gather.rs
@@ -12,6 +12,7 @@
12#![no_std] 12#![no_std]
13#![no_main] 13#![no_main]
14 14
15use core::fmt::Write as _;
15use core::sync::atomic::{AtomicBool, Ordering}; 16use core::sync::atomic::{AtomicBool, Ordering};
16 17
17use embassy_executor::Spawner; 18use embassy_executor::Spawner;
@@ -20,7 +21,6 @@ use embassy_mcxa::dma::{self, DmaChannel, Tcd};
20use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 21use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
21use embassy_mcxa::{bind_interrupts, pac}; 22use embassy_mcxa::{bind_interrupts, pac};
22use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 23use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
23use core::fmt::Write as _;
24 24
25// Source and destination buffers 25// Source and destination buffers
26static mut SRC: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; 26static mut SRC: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
@@ -73,7 +73,6 @@ bind_interrupts!(struct Irqs {
73 DMA_CH0 => ScatterGatherDmaHandler; 73 DMA_CH0 => ScatterGatherDmaHandler;
74}); 74});
75 75
76
77/// Helper to print a buffer to UART 76/// Helper to print a buffer to UART
78fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) { 77fn print_buffer(tx: &mut LpuartTx<'_, Blocking>, buf_ptr: *const u32, len: usize) {
79 write!(tx, "{:?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok(); 78 write!(tx, "{:?}", unsafe { core::slice::from_raw_parts(buf_ptr, len) }).ok();
diff --git a/examples/mcxa/src/bin/dma_scatter_gather_builder.rs b/examples/mcxa/src/bin/dma_scatter_gather_builder.rs
index 29c54ca42..d0f9ae9c4 100644
--- a/examples/mcxa/src/bin/dma_scatter_gather_builder.rs
+++ b/examples/mcxa/src/bin/dma_scatter_gather_builder.rs
@@ -20,18 +20,13 @@
20#![no_std] 20#![no_std]
21#![no_main] 21#![no_main]
22 22
23use core::fmt::Write as _;
24
23use embassy_executor::Spawner; 25use embassy_executor::Spawner;
24use embassy_mcxa::clocks::config::Div8; 26use embassy_mcxa::clocks::config::Div8;
25use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel, ScatterGatherBuilder}; 27use embassy_mcxa::dma::{DmaChannel, ScatterGatherBuilder};
26use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 28use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
27use embassy_mcxa::{bind_interrupts, pac};
28use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 29use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
29use core::fmt::Write as _;
30
31// Bind DMA channel 0 interrupt
32bind_interrupts!(struct Irqs {
33 DMA_CH0 => DmaCh0InterruptHandler;
34});
35 30
36// Source buffers (multiple segments) 31// Source buffers (multiple segments)
37static mut SRC1: [u32; 4] = [0x11111111, 0x22222222, 0x33333333, 0x44444444]; 32static mut SRC1: [u32; 4] = [0x11111111, 0x22222222, 0x33333333, 0x44444444];
@@ -62,11 +57,6 @@ async fn main(_spawner: Spawner) {
62 57
63 defmt::info!("DMA Scatter-Gather Builder example starting..."); 58 defmt::info!("DMA Scatter-Gather Builder example starting...");
64 59
65 // Enable DMA interrupt (DMA clock/reset/init is handled automatically by HAL)
66 unsafe {
67 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::DMA_CH0);
68 }
69
70 // Create UART for debug output 60 // Create UART for debug output
71 let config = Config { 61 let config = Config {
72 baudrate_bps: 115_200, 62 baudrate_bps: 115_200,
diff --git a/examples/mcxa/src/bin/dma_wrap_transfer.rs b/examples/mcxa/src/bin/dma_wrap_transfer.rs
index 7fea4bf76..acfd29f08 100644
--- a/examples/mcxa/src/bin/dma_wrap_transfer.rs
+++ b/examples/mcxa/src/bin/dma_wrap_transfer.rs
@@ -10,18 +10,13 @@
10#![no_std] 10#![no_std]
11#![no_main] 11#![no_main]
12 12
13use core::fmt::Write as _;
14
13use embassy_executor::Spawner; 15use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 16use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaChannel}; 17use embassy_mcxa::dma::DmaChannel;
16use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx}; 18use embassy_mcxa::lpuart::{Blocking, Config, Lpuart, LpuartTx};
17use embassy_mcxa::{bind_interrupts, pac};
18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 19use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
19use core::fmt::Write as _;
20
21// Bind DMA channel 0 interrupt using Embassy-style macro
22bind_interrupts!(struct Irqs {
23 DMA_CH0 => DmaCh0InterruptHandler;
24});
25 20
26// Source buffer: 4 words (16 bytes), aligned to 16 bytes for modulo 21// Source buffer: 4 words (16 bytes), aligned to 16 bytes for modulo
27#[repr(align(16))] 22#[repr(align(16))]
@@ -49,11 +44,6 @@ async fn main(_spawner: Spawner) {
49 44
50 defmt::info!("DMA wrap transfer example starting..."); 45 defmt::info!("DMA wrap transfer example starting...");
51 46
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 { 47 let config = Config {
58 baudrate_bps: 115_200, 48 baudrate_bps: 115_200,
59 ..Default::default() 49 ..Default::default()
diff --git a/examples/mcxa/src/bin/i2c-async.rs b/examples/mcxa/src/bin/i2c-async.rs
index edcfd5f22..47b5f3cbe 100644
--- a/examples/mcxa/src/bin/i2c-async.rs
+++ b/examples/mcxa/src/bin/i2c-async.rs
@@ -6,8 +6,8 @@ use embassy_time::Timer;
6use hal::bind_interrupts; 6use hal::bind_interrupts;
7use hal::clocks::config::Div8; 7use hal::clocks::config::Div8;
8use hal::config::Config; 8use hal::config::Config;
9use hal::i2c::InterruptHandler;
10use hal::i2c::controller::{self, I2c, Speed}; 9use hal::i2c::controller::{self, I2c, Speed};
10use hal::i2c::InterruptHandler;
11use hal::peripherals::LPI2C3; 11use hal::peripherals::LPI2C3;
12use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 12use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
13 13
diff --git a/examples/mcxa/src/bin/i2c-scan-blocking.rs b/examples/mcxa/src/bin/i2c-scan-blocking.rs
index 0197f9b1d..4e203597b 100644
--- a/examples/mcxa/src/bin/i2c-scan-blocking.rs
+++ b/examples/mcxa/src/bin/i2c-scan-blocking.rs
@@ -2,8 +2,8 @@
2#![no_main] 2#![no_main]
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa::Input;
6use embassy_mcxa::gpio::Pull; 5use embassy_mcxa::gpio::Pull;
6use embassy_mcxa::Input;
7use embassy_time::Timer; 7use embassy_time::Timer;
8use hal::clocks::config::Div8; 8use hal::clocks::config::Div8;
9use hal::config::Config; 9use hal::config::Config;
diff --git a/examples/mcxa/src/bin/lpuart_buffered.rs b/examples/mcxa/src/bin/lpuart_buffered.rs
index 47b56b7c7..420589d00 100644
--- a/examples/mcxa/src/bin/lpuart_buffered.rs
+++ b/examples/mcxa/src/bin/lpuart_buffered.rs
@@ -3,8 +3,8 @@
3 3
4use embassy_executor::Spawner; 4use embassy_executor::Spawner;
5use embassy_mcxa::clocks::config::Div8; 5use embassy_mcxa::clocks::config::Div8;
6use embassy_mcxa::lpuart::Config;
7use embassy_mcxa::lpuart::buffered::BufferedLpuart; 6use embassy_mcxa::lpuart::buffered::BufferedLpuart;
7use embassy_mcxa::lpuart::Config;
8use embassy_mcxa::{bind_interrupts, lpuart}; 8use embassy_mcxa::{bind_interrupts, lpuart};
9use embedded_io_async::Write; 9use embedded_io_async::Write;
10use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 10use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
diff --git a/examples/mcxa/src/bin/lpuart_dma.rs b/examples/mcxa/src/bin/lpuart_dma.rs
index 34d343452..cc86f6a40 100644
--- a/examples/mcxa/src/bin/lpuart_dma.rs
+++ b/examples/mcxa/src/bin/lpuart_dma.rs
@@ -12,17 +12,9 @@
12 12
13use embassy_executor::Spawner; 13use embassy_executor::Spawner;
14use embassy_mcxa::clocks::config::Div8; 14use embassy_mcxa::clocks::config::Div8;
15use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler};
16use embassy_mcxa::lpuart::{Config, LpuartDma}; 15use embassy_mcxa::lpuart::{Config, LpuartDma};
17use embassy_mcxa::bind_interrupts;
18use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 16use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
19 17
20// Bind DMA channel interrupts using Embassy-style macro
21bind_interrupts!(struct Irqs {
22 DMA_CH0 => DmaCh0InterruptHandler;
23 DMA_CH1 => DmaCh1InterruptHandler;
24});
25
26#[embassy_executor::main] 18#[embassy_executor::main]
27async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
28 let mut cfg = hal::config::Config::default(); 20 let mut cfg = hal::config::Config::default();
@@ -40,7 +32,8 @@ async fn main(_spawner: Spawner) {
40 32
41 // Create UART instance with DMA channels 33 // Create UART instance with DMA channels
42 let mut lpuart = LpuartDma::new( 34 let mut lpuart = LpuartDma::new(
43 p.LPUART2, p.P2_2, // TX pin 35 p.LPUART2, // Instance
36 p.P2_2, // TX pin
44 p.P2_3, // RX pin 37 p.P2_3, // RX pin
45 p.DMA_CH0, // TX DMA channel 38 p.DMA_CH0, // TX DMA channel
46 p.DMA_CH1, // RX DMA channel 39 p.DMA_CH1, // RX DMA channel
diff --git a/examples/mcxa/src/bin/lpuart_ring_buffer.rs b/examples/mcxa/src/bin/lpuart_ring_buffer.rs
index b707e20f8..be7fd4534 100644
--- a/examples/mcxa/src/bin/lpuart_ring_buffer.rs
+++ b/examples/mcxa/src/bin/lpuart_ring_buffer.rs
@@ -19,19 +19,11 @@
19#![no_main] 19#![no_main]
20 20
21use embassy_executor::Spawner; 21use embassy_executor::Spawner;
22use embassy_mcxa::bind_interrupts;
23use embassy_mcxa::clocks::config::Div8; 22use embassy_mcxa::clocks::config::Div8;
24use embassy_mcxa::dma::{DmaCh0InterruptHandler, DmaCh1InterruptHandler};
25use embassy_mcxa::lpuart::{Config, LpuartDma, LpuartTxDma}; 23use embassy_mcxa::lpuart::{Config, LpuartDma, LpuartTxDma};
26use static_cell::ConstStaticCell; 24use static_cell::ConstStaticCell;
27use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; 25use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _};
28 26
29// Bind DMA channel interrupts
30bind_interrupts!(struct Irqs {
31 DMA_CH0 => DmaCh0InterruptHandler;
32 DMA_CH1 => DmaCh1InterruptHandler;
33});
34
35// Ring buffer for RX - power of 2 is ideal for modulo efficiency 27// Ring buffer for RX - power of 2 is ideal for modulo efficiency
36static RX_RING_BUFFER: ConstStaticCell<[u8; 64]> = ConstStaticCell::new([0; 64]); 28static RX_RING_BUFFER: ConstStaticCell<[u8; 64]> = ConstStaticCell::new([0; 64]);
37 29