From 5d260e0551c8190950a8ae248437522d380ba2c7 Mon Sep 17 00:00:00 2001 From: Andelf Date: Thu, 11 Jul 2024 00:47:55 +0800 Subject: [PATCH] fix(dma): dmamux num calc, add hpm67 addr fix --- build.rs | 3 ++- src/dma/mod.rs | 3 +-- src/dma/v1.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/build.rs b/build.rs index 9aef29a..b0566d5 100644 --- a/build.rs +++ b/build.rs @@ -403,11 +403,12 @@ fn main() { let mut dmas = TokenStream::new(); for ch in METADATA.dma_channels.iter() { let name = format_ident!("{}", ch.name); - let idx = ch.channel as u8; let ch_num = ch.channel as usize; let mux_num = ch.dmamux_channel as usize; + let idx = ch.dmamux_channel as u8; // index in DMAMUX and Channel Info + // HDMA or XDMA let dma_name = format_ident!("{}", ch.name.split_once('_').expect("DMA channel name format").0); diff --git a/src/dma/mod.rs b/src/dma/mod.rs index 4a60000..88573da 100644 --- a/src/dma/mod.rs +++ b/src/dma/mod.rs @@ -112,6 +112,7 @@ pub(crate) trait ControllerInterrupt { // ========== // macros +// interrupts are not channel-based, they are controller-based macro_rules! dma_channel_impl { ($channel_peri:ident, $index:expr) => { impl crate::dma::SealedChannel for crate::peripherals::$channel_peri { @@ -120,8 +121,6 @@ macro_rules! dma_channel_impl { } } - // interrupts are not channel-based, they are controller-based - impl crate::dma::Channel for crate::peripherals::$channel_peri {} impl From for crate::dma::AnyChannel { diff --git a/src/dma/v1.rs b/src/dma/v1.rs index 34a7baf..b8adc25 100644 --- a/src/dma/v1.rs +++ b/src/dma/v1.rs @@ -116,6 +116,16 @@ pub(crate) unsafe fn init(cs: critical_section::CriticalSection) { interrupt::typelevel::HDMA::set_priority_with_cs(cs, interrupt::Priority::P1); interrupt::typelevel::HDMA::enable(); + + #[cfg(peri_xdma)] + { + crate::peripherals::XDMA::add_resource_group(0); + + pac::XDMA.dmactrl().modify(|w| w.set_reset(true)); + + interrupt::typelevel::XDMA::set_priority_with_cs(cs, interrupt::Priority::P1); + interrupt::typelevel::XDMA::enable(); + } } impl super::ControllerInterrupt for crate::peripherals::HDMA { @@ -147,7 +157,7 @@ unsafe fn dma_on_irq(r: pac::dma::Dma, mux_num_base: u32) { // - bit width alignment error // DMA error: this is normally a hardware error(memory alignment or access), but we can't do anything about it if err != 0 { - panic!("DMA: error on DMA@{:08x}, errsts=0{:08b}", r.as_ptr() as u32, err); + panic!("DMA: error on DMA@{:08x}, errsts=0b{:08b}", r.as_ptr() as u32, err); } if tc != 0 { @@ -227,11 +237,21 @@ impl AnyChannel { let ch_cr = r.chctrl(ch); + let mut src_addr = src_addr as u32; + let mut dst_addr = dst_addr as u32; + + #[cfg(hpm67)] + { + let core_id = 0; + src_addr = core_local_mem_to_sys_address(core_id, src_addr); + dst_addr = core_local_mem_to_sys_address(core_id, dst_addr); + } + // configure DMAMUX request and output channel super::dmamux::configure_dmamux(info.mux_num, request); - ch_cr.src_addr().write_value(src_addr as u32); - ch_cr.dst_addr().write_value(dst_addr as u32); + ch_cr.src_addr().write_value(src_addr); + ch_cr.dst_addr().write_value(dst_addr); ch_cr .tran_size() .modify(|w| w.0 = (size_in_bytes / src_width.bytes()) as u32); @@ -552,3 +572,31 @@ impl<'a> Future for Transfer<'a> { } } } + +#[cfg(hpm67)] +fn core_local_mem_to_sys_address(core_id: u8, addr: u32) -> u32 { + const ILM_LOCAL_BASE: u32 = 0x0; + const ILM_SIZE_IN_BYTE: u32 = 0x40000; + const DLM_LOCAL_BASE: u32 = 0x80000; + const DLM_SIZE_IN_BYTE: u32 = 0x40000; + const CORE0_ILM_SYSTEM_BASE: u32 = 0x1000000; + const CORE0_DLM_SYSTEM_BASE: u32 = 0x1040000; + const CORE1_ILM_SYSTEM_BASE: u32 = 0x1180000; + const CORE1_DLM_SYSTEM_BASE: u32 = 0x11C0000; + + let sys_addr = if addr < ILM_SIZE_IN_BYTE { + // Address in ILM + addr | CORE0_ILM_SYSTEM_BASE + } else if (addr >= DLM_LOCAL_BASE) && (addr < DLM_LOCAL_BASE + DLM_SIZE_IN_BYTE) { + // Address in DLM + (addr - DLM_LOCAL_BASE) | CORE0_DLM_SYSTEM_BASE + } else { + return addr; + }; + + if core_id == 1 { + sys_addr - CORE0_ILM_SYSTEM_BASE + CORE1_ILM_SYSTEM_BASE + } else { + sys_addr + } +}