mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 14:53:03 +00:00
stm32/dma: add support for same channel with different req in different DMAs/DMAMUXes.
This commit is contained in:
parent
7fb74ff756
commit
1ed2a0504a
@ -1169,42 +1169,52 @@ fn main() {
|
|||||||
|
|
||||||
let mut dupe = HashSet::new();
|
let mut dupe = HashSet::new();
|
||||||
for ch in p.dma_channels {
|
for ch in p.dma_channels {
|
||||||
// Some chips have multiple request numbers for the same (peri, signal, channel) combos.
|
|
||||||
// Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
|
|
||||||
let key = (ch.signal, ch.channel);
|
|
||||||
if !dupe.insert(key) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(tr) = signals.get(&(regs.kind, ch.signal)) {
|
if let Some(tr) = signals.get(&(regs.kind, ch.signal)) {
|
||||||
let peri = format_ident!("{}", p.name);
|
let peri = format_ident!("{}", p.name);
|
||||||
|
|
||||||
let channel = if let Some(channel) = &ch.channel {
|
let channels = if let Some(channel) = &ch.channel {
|
||||||
// Chip with DMA/BDMA, without DMAMUX
|
// Chip with DMA/BDMA, without DMAMUX
|
||||||
let channel = format_ident!("{}", channel);
|
vec![*channel]
|
||||||
quote!({channel: #channel})
|
|
||||||
} else if let Some(dmamux) = &ch.dmamux {
|
} else if let Some(dmamux) = &ch.dmamux {
|
||||||
// Chip with DMAMUX
|
// Chip with DMAMUX
|
||||||
let dmamux = format_ident!("{}", dmamux);
|
METADATA
|
||||||
quote!({dmamux: #dmamux})
|
.dma_channels
|
||||||
|
.iter()
|
||||||
|
.filter(|ch| ch.dmamux == Some(*dmamux))
|
||||||
|
.map(|ch| ch.name)
|
||||||
|
.collect()
|
||||||
} else if let Some(dma) = &ch.dma {
|
} else if let Some(dma) = &ch.dma {
|
||||||
// Chip with GPDMA
|
// Chip with GPDMA
|
||||||
let dma = format_ident!("{}", dma);
|
METADATA
|
||||||
quote!({dma: #dma})
|
.dma_channels
|
||||||
|
.iter()
|
||||||
|
.filter(|ch| ch.dma == *dma)
|
||||||
|
.map(|ch| ch.name)
|
||||||
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
|
|
||||||
let request = if let Some(request) = ch.request {
|
for channel in channels {
|
||||||
let request = request as u8;
|
// Some chips have multiple request numbers for the same (peri, signal, channel) combos.
|
||||||
quote!(#request)
|
// Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
|
||||||
} else {
|
let key = (ch.signal, channel.to_string());
|
||||||
quote!(())
|
if !dupe.insert(key) {
|
||||||
};
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
g.extend(quote! {
|
let request = if let Some(request) = ch.request {
|
||||||
dma_trait_impl!(#tr, #peri, #channel, #request);
|
let request = request as u8;
|
||||||
});
|
quote!(#request)
|
||||||
|
} else {
|
||||||
|
quote!(())
|
||||||
|
};
|
||||||
|
|
||||||
|
let channel = format_ident!("{}", channel);
|
||||||
|
g.extend(quote! {
|
||||||
|
dma_trait_impl!(#tr, #peri, #channel, #request);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1447,9 +1457,6 @@ fn main() {
|
|||||||
Some(dmamux) => {
|
Some(dmamux) => {
|
||||||
let dmamux = format_ident!("{}", dmamux);
|
let dmamux = format_ident!("{}", dmamux);
|
||||||
let num = ch.dmamux_channel.unwrap() as usize;
|
let num = ch.dmamux_channel.unwrap() as usize;
|
||||||
|
|
||||||
g.extend(quote!(dmamux_channel_impl!(#name, #dmamux);));
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
dmamux: crate::dma::DmamuxInfo {
|
dmamux: crate::dma::DmamuxInfo {
|
||||||
mux: crate::pac::#dmamux,
|
mux: crate::pac::#dmamux,
|
||||||
|
@ -19,30 +19,6 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait SealedMuxChannel {}
|
|
||||||
|
|
||||||
/// DMAMUX1 instance.
|
|
||||||
pub struct DMAMUX1;
|
|
||||||
/// DMAMUX2 instance.
|
|
||||||
#[cfg(stm32h7)]
|
|
||||||
pub struct DMAMUX2;
|
|
||||||
|
|
||||||
/// DMAMUX channel trait.
|
|
||||||
#[allow(private_bounds)]
|
|
||||||
pub trait MuxChannel: SealedMuxChannel {
|
|
||||||
/// DMAMUX instance this channel is on.
|
|
||||||
type Mux;
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! dmamux_channel_impl {
|
|
||||||
($channel_peri:ident, $dmamux:ident) => {
|
|
||||||
impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {}
|
|
||||||
impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
|
|
||||||
type Mux = crate::dma::$dmamux;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// safety: must be called only once
|
/// safety: must be called only once
|
||||||
pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) {
|
pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) {
|
||||||
crate::_generated::init_dmamux();
|
crate::_generated::init_dmamux();
|
||||||
|
@ -14,7 +14,7 @@ pub use gpdma::*;
|
|||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
mod dmamux;
|
mod dmamux;
|
||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
pub use dmamux::*;
|
pub(crate) use dmamux::*;
|
||||||
|
|
||||||
mod util;
|
mod util;
|
||||||
pub(crate) use util::*;
|
pub(crate) use util::*;
|
||||||
|
@ -36,32 +36,7 @@ macro_rules! dma_trait {
|
|||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
macro_rules! dma_trait_impl {
|
macro_rules! dma_trait_impl {
|
||||||
// DMAMUX
|
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $channel:ident, $request:expr) => {
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
|
|
||||||
impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
|
|
||||||
where
|
|
||||||
T: crate::dma::Channel + crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
|
|
||||||
{
|
|
||||||
fn request(&self) -> crate::dma::Request {
|
|
||||||
$request
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// DMAMUX
|
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dma: $dma:ident}, $request:expr) => {
|
|
||||||
impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
|
|
||||||
where
|
|
||||||
T: crate::dma::Channel,
|
|
||||||
{
|
|
||||||
fn request(&self) -> crate::dma::Request {
|
|
||||||
$request
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// DMA/GPDMA, without DMAMUX
|
|
||||||
(crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {channel: $channel:ident}, $request:expr) => {
|
|
||||||
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel {
|
impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel {
|
||||||
fn request(&self) -> crate::dma::Request {
|
fn request(&self) -> crate::dma::Request {
|
||||||
$request
|
$request
|
||||||
|
Loading…
Reference in New Issue
Block a user