diff options
| author | James Munns <[email protected]> | 2025-12-08 17:58:00 +0100 |
|---|---|---|
| committer | James Munns <[email protected]> | 2025-12-08 17:58:00 +0100 |
| commit | 6680ef22fa4b46adb4cda46d6cdbc9dac39dc78c (patch) | |
| tree | 367bfba7c960798db8f5813629e5bb206158e80c /embassy-mcxa | |
| parent | 5d8f3a3d18eda339e258193295cf332d7e01882e (diff) | |
Clean up examples, move interrupts to be more fully managed
Diffstat (limited to 'embassy-mcxa')
| -rw-r--r-- | embassy-mcxa/src/dma.rs | 58 | ||||
| -rw-r--r-- | embassy-mcxa/src/lib.rs | 35 |
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. | ||
| 2451 | macro_rules! impl_dma_interrupt_handler { | 2442 | macro_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 | ||
| 2471 | impl_dma_interrupt_handler!(DmaCh0InterruptHandler, DMA_CH0, 0); | 2453 | use crate::pac::interrupt; |
| 2472 | impl_dma_interrupt_handler!(DmaCh1InterruptHandler, DMA_CH1, 1); | 2454 | |
| 2473 | impl_dma_interrupt_handler!(DmaCh2InterruptHandler, DMA_CH2, 2); | 2455 | impl_dma_interrupt_handler!(DMA_CH0, 0); |
| 2474 | impl_dma_interrupt_handler!(DmaCh3InterruptHandler, DMA_CH3, 3); | 2456 | impl_dma_interrupt_handler!(DMA_CH1, 1); |
| 2475 | impl_dma_interrupt_handler!(DmaCh4InterruptHandler, DMA_CH4, 4); | 2457 | impl_dma_interrupt_handler!(DMA_CH2, 2); |
| 2476 | impl_dma_interrupt_handler!(DmaCh5InterruptHandler, DMA_CH5, 5); | 2458 | impl_dma_interrupt_handler!(DMA_CH3, 3); |
| 2477 | impl_dma_interrupt_handler!(DmaCh6InterruptHandler, DMA_CH6, 6); | 2459 | impl_dma_interrupt_handler!(DMA_CH4, 4); |
| 2478 | impl_dma_interrupt_handler!(DmaCh7InterruptHandler, DMA_CH7, 7); | 2460 | impl_dma_interrupt_handler!(DMA_CH5, 5); |
| 2461 | impl_dma_interrupt_handler!(DMA_CH6, 6); | ||
| 2462 | impl_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)] | ||
| 430 | pub unsafe fn __handle_interrupt<T, H>() | ||
| 431 | where | ||
| 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: |
