aboutsummaryrefslogtreecommitdiff
path: root/embassy-mcxa
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 /embassy-mcxa
parent5d8f3a3d18eda339e258193295cf332d7e01882e (diff)
Clean up examples, move interrupts to be more fully managed
Diffstat (limited to 'embassy-mcxa')
-rw-r--r--embassy-mcxa/src/dma.rs58
-rw-r--r--embassy-mcxa/src/lib.rs35
2 files changed, 21 insertions, 72 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: