[MCXA] Add DMA1 support#6525
Conversation
| if peripheral.name.to_ascii_lowercase().starts_with("can") { | ||
| continue; | ||
| } | ||
|
|
There was a problem hiding this comment.
Skipping CAN because something in nxp-pac broke. I'm guessing/hoping #6435 fixes that
There was a problem hiding this comment.
So I patched this in #6524 -- there seems to be a missing config as well as a naming inconsistency
There was a problem hiding this comment.
Yep! I saw.
Didn't notice your PR. I was guessing you'd be asleep.
Your PR works, but my PR is a more proper durable implementation
There was a problem hiding this comment.
Agree completely that your solution is better -- if we can both extend DMA0 and add DMA1 I'll take it.
There was a problem hiding this comment.
I am intending to fix this directly in nxp-pac (see this PR) as part of #6435. The naming convention used in build.rs where gate.bit == peripheral.name.to_lowercase() is valid for most, but not all, peripherals. Among the latter are CAN0 and CAN1, which is what caused the build errors. The nxp-pac PR adds a bit member to the Gate struct and JSON schema that defaults to peripheral.name.to_lowercase() when unspecified (i.e., the vast majority of cases), but can be manually overwritten in the pac JSONs for outliers (e.g., CAN0/CAN1)
There was a problem hiding this comment.
Ok, then let's fix it in the hal when that PR lands
…ent page dma::init() only enabled the DMA0 clock gate and configured DMA0's management page (MP_CSR). DMA1 was left unclocked and held in reset, so the first write to any DMA1 TCD register faulted. This is why switching dma_mem_to_mem from DMA0_CH0 to DMA1_CH0 hardfaulted. Enable and reset DMA1 and configure its MP_CSR for mcxa5xx, mirroring the existing DMA0 setup. Verified on FRDM-MCXA577: dma_mem_to_mem now passes mem_to_mem and memset on DMA1_CH0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b465a11b-8384-4457-83e6-314125573eb3
|
@diondokter Found it — the hardfault happens because
The DMA1 gate is already generated by the new build.rs ( diff --git a/embassy-mcxa/src/dma.rs b/embassy-mcxa/src/dma.rs
--- a/embassy-mcxa/src/dma.rs
+++ b/embassy-mcxa/src/dma.rs
@@ use crate::pac::{self, Interrupt};
+#[cfg(feature = "mcxa5xx")]
+use crate::peripherals::DMA1;
use crate::peripherals::DMA0;
@@ pub(crate) fn init() {
w.set_gmrc(true);
});
+ // Enable DMA1 clock, release reset, and configure its management page.
+ // Without this, any access to the DMA1 TCD registers faults because the
+ // peripheral is unclocked and held in reset.
+ #[cfg(feature = "mcxa5xx")]
+ {
+ let _ = unsafe { enable_and_reset::<DMA1>(&NoConfig) };
+
+ pac::DMA1.mp_csr().modify(|w| {
+ w.set_edbg(true);
+ w.set_erca(true);
+ w.set_halt(Halt::NormalOperation);
+ w.set_gclc(true);
+ w.set_gmrc(true);
+ });
+ }
+
// Enable all DMA request lines for non-secure access.
#[cfg(all(feature = "mcxa5xx", feature = "dma-ipd-req"))]
for sec_gp_i in 0..=9 {Verified on an FRDM-MCXA577: with this patch, Both |
|
Ah well found! Yes please open a PR. If you do that within half an hour I can merge it all just before I go to bed 😇 |
|
Done — opened diondokter#3 against your mcxa_dma1 branch with the fix. 🚀 |
mcxa: fix DMA1 hardfault by initializing its clock, reset and management page
|
Hmm fmt failed. Sorry, but I need to go to bed now. I'll fix it tomorrow. Or you need @felipebalbi to fix and merge it |
Sort the peripherals imports so DMA0 precedes the cfg-gated DMA1, fixing the rustfmt CI failure on the merged DMA1 fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b465a11b-8384-4457-83e6-314125573eb3
|
Formatting slipped through — the imports weren't run through nightly rustfmt, which is why CI is red. One-line fix in diondokter#4 (reorders \DMA0/\DMA1\ imports). \cargo +nightly fmt --check\ is clean with it. No rush if you're already off — it'll be there in the morning. 🌙 |
mcxa: rustfmt DMA1 import ordering
Adds DMA0_8..=11 and DMA1_0..=3 support. This is now generated from the build.rs.
@bramsdell-ms I've tried adding DMA1 to the HAL. Implementation should work, but it doesn't... But I don't really have time to debug.
To reproduce, go to the mcxa5xx examples, dma_mem_to_mem and then change dma0_ch0 to dma1_ch0. Run the example and you'll see a hardfault because of some pointer write.