aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/build.rs59
-rw-r--r--embassy-stm32/src/dma/dmamux.rs24
-rw-r--r--embassy-stm32/src/dma/mod.rs2
-rw-r--r--embassy-stm32/src/macros.rs27
4 files changed, 35 insertions, 77 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index d2b352742..ba3af2550 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1169,42 +1169,52 @@ fn main() {
1169 1169
1170 let mut dupe = HashSet::new(); 1170 let mut dupe = HashSet::new();
1171 for ch in p.dma_channels { 1171 for ch in p.dma_channels {
1172 // Some chips have multiple request numbers for the same (peri, signal, channel) combos.
1173 // Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
1174 let key = (ch.signal, ch.channel);
1175 if !dupe.insert(key) {
1176 continue;
1177 }
1178
1179 if let Some(tr) = signals.get(&(regs.kind, ch.signal)) { 1172 if let Some(tr) = signals.get(&(regs.kind, ch.signal)) {
1180 let peri = format_ident!("{}", p.name); 1173 let peri = format_ident!("{}", p.name);
1181 1174
1182 let channel = if let Some(channel) = &ch.channel { 1175 let channels = if let Some(channel) = &ch.channel {
1183 // Chip with DMA/BDMA, without DMAMUX 1176 // Chip with DMA/BDMA, without DMAMUX
1184 let channel = format_ident!("{}", channel); 1177 vec![*channel]
1185 quote!({channel: #channel})
1186 } else if let Some(dmamux) = &ch.dmamux { 1178 } else if let Some(dmamux) = &ch.dmamux {
1187 // Chip with DMAMUX 1179 // Chip with DMAMUX
1188 let dmamux = format_ident!("{}", dmamux); 1180 METADATA
1189 quote!({dmamux: #dmamux}) 1181 .dma_channels
1182 .iter()
1183 .filter(|ch| ch.dmamux == Some(*dmamux))
1184 .map(|ch| ch.name)
1185 .collect()
1190 } else if let Some(dma) = &ch.dma { 1186 } else if let Some(dma) = &ch.dma {
1191 // Chip with GPDMA 1187 // Chip with GPDMA
1192 let dma = format_ident!("{}", dma); 1188 METADATA
1193 quote!({dma: #dma}) 1189 .dma_channels
1190 .iter()
1191 .filter(|ch| ch.dma == *dma)
1192 .map(|ch| ch.name)
1193 .collect()
1194 } else { 1194 } else {
1195 unreachable!(); 1195 unreachable!();
1196 }; 1196 };
1197 1197
1198 let request = if let Some(request) = ch.request { 1198 for channel in channels {
1199 let request = request as u8; 1199 // Some chips have multiple request numbers for the same (peri, signal, channel) combos.
1200 quote!(#request) 1200 // Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
1201 } else { 1201 let key = (ch.signal, channel.to_string());
1202 quote!(()) 1202 if !dupe.insert(key) {
1203 }; 1203 continue;
1204 }
1204 1205
1205 g.extend(quote! { 1206 let request = if let Some(request) = ch.request {
1206 dma_trait_impl!(#tr, #peri, #channel, #request); 1207 let request = request as u8;
1207 }); 1208 quote!(#request)
1209 } else {
1210 quote!(())
1211 };
1212
1213 let channel = format_ident!("{}", channel);
1214 g.extend(quote! {
1215 dma_trait_impl!(#tr, #peri, #channel, #request);
1216 });
1217 }
1208 } 1218 }
1209 } 1219 }
1210 } 1220 }
@@ -1447,9 +1457,6 @@ fn main() {
1447 Some(dmamux) => { 1457 Some(dmamux) => {
1448 let dmamux = format_ident!("{}", dmamux); 1458 let dmamux = format_ident!("{}", dmamux);
1449 let num = ch.dmamux_channel.unwrap() as usize; 1459 let num = ch.dmamux_channel.unwrap() as usize;
1450
1451 g.extend(quote!(dmamux_channel_impl!(#name, #dmamux);));
1452
1453 quote! { 1460 quote! {
1454 dmamux: crate::dma::DmamuxInfo { 1461 dmamux: crate::dma::DmamuxInfo {
1455 mux: crate::pac::#dmamux, 1462 mux: crate::pac::#dmamux,
diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs
index dc7cd3a66..1585b30d4 100644
--- a/embassy-stm32/src/dma/dmamux.rs
+++ b/embassy-stm32/src/dma/dmamux.rs
@@ -19,30 +19,6 @@ pub(crate) fn configure_dmamux(info: &DmamuxInfo, request: u8) {
19 }); 19 });
20} 20}
21 21
22pub(crate) trait SealedMuxChannel {}
23
24/// DMAMUX1 instance.
25pub struct DMAMUX1;
26/// DMAMUX2 instance.
27#[cfg(stm32h7)]
28pub struct DMAMUX2;
29
30/// DMAMUX channel trait.
31#[allow(private_bounds)]
32pub trait MuxChannel: SealedMuxChannel {
33 /// DMAMUX instance this channel is on.
34 type Mux;
35}
36
37macro_rules! dmamux_channel_impl {
38 ($channel_peri:ident, $dmamux:ident) => {
39 impl crate::dma::SealedMuxChannel for crate::peripherals::$channel_peri {}
40 impl crate::dma::MuxChannel for crate::peripherals::$channel_peri {
41 type Mux = crate::dma::$dmamux;
42 }
43 };
44}
45
46/// safety: must be called only once 22/// safety: must be called only once
47pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) { 23pub(crate) unsafe fn init(_cs: critical_section::CriticalSection) {
48 crate::_generated::init_dmamux(); 24 crate::_generated::init_dmamux();
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 8766d0a60..3f5687a62 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -14,7 +14,7 @@ pub use gpdma::*;
14#[cfg(dmamux)] 14#[cfg(dmamux)]
15mod dmamux; 15mod dmamux;
16#[cfg(dmamux)] 16#[cfg(dmamux)]
17pub use dmamux::*; 17pub(crate) use dmamux::*;
18 18
19mod util; 19mod util;
20pub(crate) use util::*; 20pub(crate) use util::*;
diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs
index 14137bc37..02dce1266 100644
--- a/embassy-stm32/src/macros.rs
+++ b/embassy-stm32/src/macros.rs
@@ -36,32 +36,7 @@ macro_rules! dma_trait {
36 36
37#[allow(unused)] 37#[allow(unused)]
38macro_rules! dma_trait_impl { 38macro_rules! dma_trait_impl {
39 // DMAMUX 39 (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, $channel:ident, $request:expr) => {
40 (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dmamux: $dmamux:ident}, $request:expr) => {
41 impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
42 where
43 T: crate::dma::Channel + crate::dma::MuxChannel<Mux = crate::dma::$dmamux>,
44 {
45 fn request(&self) -> crate::dma::Request {
46 $request
47 }
48 }
49 };
50
51 // DMAMUX
52 (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {dma: $dma:ident}, $request:expr) => {
53 impl<T> crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for T
54 where
55 T: crate::dma::Channel,
56 {
57 fn request(&self) -> crate::dma::Request {
58 $request
59 }
60 }
61 };
62
63 // DMA/GPDMA, without DMAMUX
64 (crate::$mod:ident::$trait:ident$(<$mode:ident>)?, $instance:ident, {channel: $channel:ident}, $request:expr) => {
65 impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel { 40 impl crate::$mod::$trait<crate::peripherals::$instance $(, crate::$mod::$mode)?> for crate::peripherals::$channel {
66 fn request(&self) -> crate::dma::Request { 41 fn request(&self) -> crate::dma::Request {
67 $request 42 $request