aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-04-29 22:02:37 +0000
committerGitHub <[email protected]>2024-04-29 22:02:37 +0000
commite6d90b18c0bb4d3b02ecf73ee682e5892fe83b14 (patch)
treec4db46ebe52c160d118fe67620b41d4d551488c7
parent2410e91785b318283f6e8b3cf9de1738ab064bd8 (diff)
parent1ed2a0504aba38e4b404c776808ee5229cd72615 (diff)
Merge pull request #2889 from embassy-rs/update-metapac-42
stm32: update metapac. Adds U5 LPDMA, fixes ADC_COMMONs.
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs133
-rw-r--r--embassy-stm32/src/adc/v1.rs14
-rw-r--r--embassy-stm32/src/dac/mod.rs2
-rw-r--r--embassy-stm32/src/dma/dmamux.rs24
-rw-r--r--embassy-stm32/src/dma/gpdma.rs6
-rw-r--r--embassy-stm32/src/dma/mod.rs2
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs4
-rw-r--r--embassy-stm32/src/macros.rs27
-rw-r--r--embassy-stm32/src/rcc/f013.rs84
-rw-r--r--examples/stm32f0/src/bin/adc.rs6
-rw-r--r--examples/stm32f4/src/bin/dac.rs2
-rw-r--r--examples/stm32l0/src/bin/adc.rs6
-rw-r--r--tests/stm32/src/bin/dac_l1.rs2
-rw-r--r--tests/stm32/src/common.rs6
15 files changed, 151 insertions, 171 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 653a376bd..93a30c5c5 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -72,7 +72,7 @@ rand_core = "0.6.3"
72sdio-host = "0.5.0" 72sdio-host = "0.5.0"
73critical-section = "1.1" 73critical-section = "1.1"
74#stm32-metapac = { version = "15" } 74#stm32-metapac = { version = "15" }
75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0" } 75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-37a0941112fd16fee53aaa2005fd67b77adab59c" }
76 76
77vcell = "0.1.3" 77vcell = "0.1.3"
78nb = "1.0.0" 78nb = "1.0.0"
@@ -98,7 +98,7 @@ proc-macro2 = "1.0.36"
98quote = "1.0.15" 98quote = "1.0.15"
99 99
100#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} 100#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
101stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-823168933f3860770111f7bde2a82b912eac58c0", default-features = false, features = ["metadata"]} 101stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-37a0941112fd16fee53aaa2005fd67b77adab59c", default-features = false, features = ["metadata"]}
102 102
103[features] 103[features]
104default = ["rt"] 104default = ["rt"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 67fceda56..ba3af2550 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1,6 +1,8 @@
1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; 1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
2use std::fmt::Write as _; 2use std::fmt::Write as _;
3use std::path::PathBuf; 3use std::io::Write;
4use std::path::{Path, PathBuf};
5use std::process::Command;
4use std::{env, fs}; 6use std::{env, fs};
5 7
6use proc_macro2::{Ident, TokenStream}; 8use proc_macro2::{Ident, TokenStream};
@@ -49,6 +51,8 @@ fn main() {
49 .unwrap() 51 .unwrap()
50 .to_ascii_lowercase(); 52 .to_ascii_lowercase();
51 53
54 eprintln!("chip: {chip_name}");
55
52 for p in METADATA.peripherals { 56 for p in METADATA.peripherals {
53 if let Some(r) = &p.registers { 57 if let Some(r) = &p.registers {
54 println!("cargo:rustc-cfg={}", r.kind); 58 println!("cargo:rustc-cfg={}", r.kind);
@@ -1165,42 +1169,52 @@ fn main() {
1165 1169
1166 let mut dupe = HashSet::new(); 1170 let mut dupe = HashSet::new();
1167 for ch in p.dma_channels { 1171 for ch in p.dma_channels {
1168 // Some chips have multiple request numbers for the same (peri, signal, channel) combos.
1169 // Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
1170 let key = (ch.signal, ch.channel);
1171 if !dupe.insert(key) {
1172 continue;
1173 }
1174
1175 if let Some(tr) = signals.get(&(regs.kind, ch.signal)) { 1172 if let Some(tr) = signals.get(&(regs.kind, ch.signal)) {
1176 let peri = format_ident!("{}", p.name); 1173 let peri = format_ident!("{}", p.name);
1177 1174
1178 let channel = if let Some(channel) = &ch.channel { 1175 let channels = if let Some(channel) = &ch.channel {
1179 // Chip with DMA/BDMA, without DMAMUX 1176 // Chip with DMA/BDMA, without DMAMUX
1180 let channel = format_ident!("{}", channel); 1177 vec![*channel]
1181 quote!({channel: #channel})
1182 } else if let Some(dmamux) = &ch.dmamux { 1178 } else if let Some(dmamux) = &ch.dmamux {
1183 // Chip with DMAMUX 1179 // Chip with DMAMUX
1184 let dmamux = format_ident!("{}", dmamux); 1180 METADATA
1185 quote!({dmamux: #dmamux}) 1181 .dma_channels
1182 .iter()
1183 .filter(|ch| ch.dmamux == Some(*dmamux))
1184 .map(|ch| ch.name)
1185 .collect()
1186 } else if let Some(dma) = &ch.dma { 1186 } else if let Some(dma) = &ch.dma {
1187 // Chip with GPDMA 1187 // Chip with GPDMA
1188 let dma = format_ident!("{}", dma); 1188 METADATA
1189 quote!({dma: #dma}) 1189 .dma_channels
1190 .iter()
1191 .filter(|ch| ch.dma == *dma)
1192 .map(|ch| ch.name)
1193 .collect()
1190 } else { 1194 } else {
1191 unreachable!(); 1195 unreachable!();
1192 }; 1196 };
1193 1197
1194 let request = if let Some(request) = ch.request { 1198 for channel in channels {
1195 let request = request as u8; 1199 // Some chips have multiple request numbers for the same (peri, signal, channel) combos.
1196 quote!(#request) 1200 // Ignore the dupes, picking the first one. Otherwise this causes conflicting trait impls
1197 } else { 1201 let key = (ch.signal, channel.to_string());
1198 quote!(()) 1202 if !dupe.insert(key) {
1199 }; 1203 continue;
1204 }
1200 1205
1201 g.extend(quote! { 1206 let request = if let Some(request) = ch.request {
1202 dma_trait_impl!(#tr, #peri, #channel, #request); 1207 let request = request as u8;
1203 }); 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 }
1204 } 1218 }
1205 } 1219 }
1206 } 1220 }
@@ -1321,17 +1335,7 @@ fn main() {
1321 let mut interrupts_table: Vec<Vec<String>> = Vec::new(); 1335 let mut interrupts_table: Vec<Vec<String>> = Vec::new();
1322 let mut peripherals_table: Vec<Vec<String>> = Vec::new(); 1336 let mut peripherals_table: Vec<Vec<String>> = Vec::new();
1323 let mut pins_table: Vec<Vec<String>> = Vec::new(); 1337 let mut pins_table: Vec<Vec<String>> = Vec::new();
1324 let mut adc_common_table: Vec<Vec<String>> = Vec::new(); 1338 let mut adc_table: Vec<Vec<String>> = Vec::new();
1325
1326 /*
1327 If ADC3_COMMON exists, ADC3 and higher are assigned to it
1328 All other ADCs are assigned to ADC_COMMON
1329
1330 ADC3 and higher are assigned to the adc34 clock in the table
1331 The adc3_common cfg directive is added if ADC3_COMMON exists
1332 */
1333 let has_adc3 = METADATA.peripherals.iter().any(|p| p.name == "ADC3_COMMON");
1334 let set_adc345 = HashSet::from(["ADC3", "ADC4", "ADC5"]);
1335 1339
1336 for m in METADATA 1340 for m in METADATA
1337 .memory 1341 .memory
@@ -1388,14 +1392,18 @@ fn main() {
1388 } 1392 }
1389 1393
1390 if regs.kind == "adc" { 1394 if regs.kind == "adc" {
1391 let (adc_common, adc_clock) = if set_adc345.contains(p.name) && has_adc3 { 1395 let adc_num = p.name.strip_prefix("ADC").unwrap();
1392 ("ADC3_COMMON", "adc34") 1396 let mut adc_common = None;
1393 } else { 1397 for p2 in METADATA.peripherals {
1394 ("ADC_COMMON", "adc") 1398 if let Some(common_nums) = p2.name.strip_prefix("ADC").and_then(|s| s.strip_suffix("_COMMON")) {
1395 }; 1399 if common_nums.contains(adc_num) {
1396 1400 adc_common = Some(p2);
1397 let row = vec![p.name.to_string(), adc_common.to_string(), adc_clock.to_string()]; 1401 }
1398 adc_common_table.push(row); 1402 }
1403 }
1404 let adc_common = adc_common.map(|p| p.name).unwrap_or("none");
1405 let row = vec![p.name.to_string(), adc_common.to_string(), "adc".to_string()];
1406 adc_table.push(row);
1399 } 1407 }
1400 1408
1401 for irq in p.interrupts { 1409 for irq in p.interrupts {
@@ -1441,6 +1449,7 @@ fn main() {
1441 "dma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)), 1449 "dma" => quote!(crate::dma::DmaInfo::Dma(crate::pac::#dma)),
1442 "bdma" => quote!(crate::dma::DmaInfo::Bdma(crate::pac::#dma)), 1450 "bdma" => quote!(crate::dma::DmaInfo::Bdma(crate::pac::#dma)),
1443 "gpdma" => quote!(crate::pac::#dma), 1451 "gpdma" => quote!(crate::pac::#dma),
1452 "lpdma" => quote!(unsafe { crate::pac::gpdma::Gpdma::from_ptr(crate::pac::#dma.as_ptr())}),
1444 _ => panic!("bad dma channel kind {}", bi.kind), 1453 _ => panic!("bad dma channel kind {}", bi.kind),
1445 }; 1454 };
1446 1455
@@ -1448,9 +1457,6 @@ fn main() {
1448 Some(dmamux) => { 1457 Some(dmamux) => {
1449 let dmamux = format_ident!("{}", dmamux); 1458 let dmamux = format_ident!("{}", dmamux);
1450 let num = ch.dmamux_channel.unwrap() as usize; 1459 let num = ch.dmamux_channel.unwrap() as usize;
1451
1452 g.extend(quote!(dmamux_channel_impl!(#name, #dmamux);));
1453
1454 quote! { 1460 quote! {
1455 dmamux: crate::dma::DmamuxInfo { 1461 dmamux: crate::dma::DmamuxInfo {
1456 mux: crate::pac::#dmamux, 1462 mux: crate::pac::#dmamux,
@@ -1535,17 +1541,19 @@ fn main() {
1535 make_table(&mut m, "foreach_interrupt", &interrupts_table); 1541 make_table(&mut m, "foreach_interrupt", &interrupts_table);
1536 make_table(&mut m, "foreach_peripheral", &peripherals_table); 1542 make_table(&mut m, "foreach_peripheral", &peripherals_table);
1537 make_table(&mut m, "foreach_pin", &pins_table); 1543 make_table(&mut m, "foreach_pin", &pins_table);
1538 make_table(&mut m, "foreach_adc", &adc_common_table); 1544 make_table(&mut m, "foreach_adc", &adc_table);
1539 1545
1540 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 1546 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
1541 let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string(); 1547 let out_file = out_dir.join("_macros.rs").to_string_lossy().to_string();
1542 fs::write(out_file, m).unwrap(); 1548 fs::write(&out_file, m).unwrap();
1549 rustfmt(&out_file);
1543 1550
1544 // ======== 1551 // ========
1545 // Write generated.rs 1552 // Write generated.rs
1546 1553
1547 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); 1554 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
1548 fs::write(out_file, g.to_string()).unwrap(); 1555 fs::write(&out_file, g.to_string()).unwrap();
1556 rustfmt(&out_file);
1549 1557
1550 // ======== 1558 // ========
1551 // Multicore 1559 // Multicore
@@ -1569,13 +1577,6 @@ fn main() {
1569 } 1577 }
1570 1578
1571 // ======= 1579 // =======
1572 // ADC3_COMMON is present
1573 #[allow(clippy::print_literal)]
1574 if has_adc3 {
1575 println!("cargo:rustc-cfg={}", "adc3_common");
1576 }
1577
1578 // =======
1579 // Features for targeting groups of chips 1580 // Features for targeting groups of chips
1580 1581
1581 if &chip_name[..8] == "stm32wba" { 1582 if &chip_name[..8] == "stm32wba" {
@@ -1667,3 +1668,23 @@ fn get_flash_region_type_name(name: &str) -> String {
1667 .replace("REGION", "Region") 1668 .replace("REGION", "Region")
1668 .replace('_', "") 1669 .replace('_', "")
1669} 1670}
1671
1672/// rustfmt a given path.
1673/// Failures are logged to stderr and ignored.
1674fn rustfmt(path: impl AsRef<Path>) {
1675 let path = path.as_ref();
1676 match Command::new("rustfmt").args([path]).output() {
1677 Err(e) => {
1678 eprintln!("failed to exec rustfmt {:?}: {:?}", path, e);
1679 }
1680 Ok(out) => {
1681 if !out.status.success() {
1682 eprintln!("rustfmt {:?} failed:", path);
1683 eprintln!("=== STDOUT:");
1684 std::io::stderr().write_all(&out.stdout).unwrap();
1685 eprintln!("=== STDERR:");
1686 std::io::stderr().write_all(&out.stderr).unwrap();
1687 }
1688 }
1689 }
1690}
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 1dda28cf2..f17522076 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -9,7 +9,7 @@ use stm32_metapac::adc::vals::Ckmode;
9use super::blocking_delay_us; 9use super::blocking_delay_us;
10use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; 10use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
11use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
12use crate::peripherals::ADC; 12use crate::peripherals::ADC1;
13use crate::{interrupt, Peripheral}; 13use crate::{interrupt, Peripheral};
14 14
15pub const VDDA_CALIB_MV: u32 = 3300; 15pub const VDDA_CALIB_MV: u32 = 3300;
@@ -36,26 +36,26 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
36pub struct Vbat; 36pub struct Vbat;
37 37
38#[cfg(not(adc_l0))] 38#[cfg(not(adc_l0))]
39impl AdcPin<ADC> for Vbat {} 39impl AdcPin<ADC1> for Vbat {}
40 40
41#[cfg(not(adc_l0))] 41#[cfg(not(adc_l0))]
42impl super::SealedAdcPin<ADC> for Vbat { 42impl super::SealedAdcPin<ADC1> for Vbat {
43 fn channel(&self) -> u8 { 43 fn channel(&self) -> u8 {
44 18 44 18
45 } 45 }
46} 46}
47 47
48pub struct Vref; 48pub struct Vref;
49impl AdcPin<ADC> for Vref {} 49impl AdcPin<ADC1> for Vref {}
50impl super::SealedAdcPin<ADC> for Vref { 50impl super::SealedAdcPin<ADC1> for Vref {
51 fn channel(&self) -> u8 { 51 fn channel(&self) -> u8 {
52 17 52 17
53 } 53 }
54} 54}
55 55
56pub struct Temperature; 56pub struct Temperature;
57impl AdcPin<ADC> for Temperature {} 57impl AdcPin<ADC1> for Temperature {}
58impl super::SealedAdcPin<ADC> for Temperature { 58impl super::SealedAdcPin<ADC1> for Temperature {
59 fn channel(&self) -> u8 { 59 fn channel(&self) -> u8 {
60 16 60 16
61 } 61 }
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index 26298a08b..8a748ad72 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -368,7 +368,7 @@ impl<'d, T: Instance, const N: u8, DMA> Drop for DacChannel<'d, T, N, DMA> {
368/// 368///
369/// ```ignore 369/// ```ignore
370/// // Pins may need to be changed for your specific device. 370/// // Pins may need to be changed for your specific device.
371/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC, NoDma, NoDma, p.PA4, p.PA5).split(); 371/// let (dac_ch1, dac_ch2) = embassy_stm32::dac::Dac::new(p.DAC1, NoDma, NoDma, p.PA4, p.PA5).split();
372/// ``` 372/// ```
373pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> { 373pub struct Dac<'d, T: Instance, DMACh1 = NoDma, DMACh2 = NoDma> {
374 ch1: DacChannel<'d, T, 1, DMACh1>, 374 ch1: DacChannel<'d, T, 1, DMACh1>,
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/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs
index ef03970ef..a3717e67b 100644
--- a/embassy-stm32/src/dma/gpdma.rs
+++ b/embassy-stm32/src/dma/gpdma.rs
@@ -32,7 +32,7 @@ impl Default for TransferOptions {
32 } 32 }
33} 33}
34 34
35impl From<WordSize> for vals::ChTr1Dw { 35impl From<WordSize> for vals::Dw {
36 fn from(raw: WordSize) -> Self { 36 fn from(raw: WordSize) -> Self {
37 match raw { 37 match raw {
38 WordSize::OneByte => Self::BYTE, 38 WordSize::OneByte => Self::BYTE,
@@ -235,8 +235,8 @@ impl<'a> Transfer<'a> {
235 }); 235 });
236 ch.tr2().write(|w| { 236 ch.tr2().write(|w| {
237 w.set_dreq(match dir { 237 w.set_dreq(match dir {
238 Dir::MemoryToPeripheral => vals::ChTr2Dreq::DESTINATIONPERIPHERAL, 238 Dir::MemoryToPeripheral => vals::Dreq::DESTINATIONPERIPHERAL,
239 Dir::PeripheralToMemory => vals::ChTr2Dreq::SOURCEPERIPHERAL, 239 Dir::PeripheralToMemory => vals::Dreq::SOURCEPERIPHERAL,
240 }); 240 });
241 w.set_reqsel(request); 241 w.set_reqsel(request);
242 }); 242 });
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/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index c6e015022..37f460574 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -94,8 +94,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
94 94
95 #[cfg(rcc_h5)] 95 #[cfg(rcc_h5)]
96 critical_section::with(|_| { 96 critical_section::with(|_| {
97 crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true));
98
99 crate::pac::RCC.ahb1enr().modify(|w| { 97 crate::pac::RCC.ahb1enr().modify(|w| {
100 w.set_ethen(true); 98 w.set_ethen(true);
101 w.set_ethtxen(true); 99 w.set_ethtxen(true);
@@ -161,8 +159,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
161 159
162 #[cfg(rcc_h5)] 160 #[cfg(rcc_h5)]
163 critical_section::with(|_| { 161 critical_section::with(|_| {
164 crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true));
165
166 crate::pac::RCC.ahb1enr().modify(|w| { 162 crate::pac::RCC.ahb1enr().modify(|w| {
167 w.set_ethen(true); 163 w.set_ethen(true);
168 w.set_ethtxen(true); 164 w.set_ethtxen(true);
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
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 215f8a3d2..f33351e74 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -299,54 +299,66 @@ pub(crate) unsafe fn init(config: Config) {
299 299
300 let rtc = config.ls.init(); 300 let rtc = config.ls.init();
301 301
302 // TODO: all this ADC stuff should probably go into the ADC module, not here.
303 // Most STM32s manage ADC clocks in a similar way with ADCx_COMMON.
302 #[cfg(all(stm32f3, not(rcc_f37)))] 304 #[cfg(all(stm32f3, not(rcc_f37)))]
303 use crate::pac::adccommon::vals::Ckmode; 305 use crate::pac::adccommon::vals::Ckmode;
304 306
305 #[cfg(all(stm32f3, not(rcc_f37)))] 307 #[cfg(all(stm32f3, not(rcc_f37)))]
306 let adc = match config.adc { 308 let adc = {
307 AdcClockSource::Pll(adcpres) => { 309 #[cfg(peri_adc1_common)]
308 RCC.cfgr2().modify(|w| w.set_adc12pres(adcpres)); 310 let common = crate::pac::ADC1_COMMON;
309 crate::pac::ADC_COMMON 311 #[cfg(peri_adc12_common)]
310 .ccr() 312 let common = crate::pac::ADC12_COMMON;
311 .modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS)); 313
312 314 match config.adc {
313 unwrap!(pll) / adcpres 315 AdcClockSource::Pll(adcpres) => {
314 } 316 RCC.cfgr2().modify(|w| w.set_adc12pres(adcpres));
315 AdcClockSource::Hclk(adcpres) => { 317 common.ccr().modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS));
316 assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1)); 318
319 unwrap!(pll) / adcpres
320 }
321 AdcClockSource::Hclk(adcpres) => {
322 assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1));
317 323
318 let (div, ckmode) = match adcpres { 324 let (div, ckmode) = match adcpres {
319 AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1), 325 AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1),
320 AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2), 326 AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2),
321 AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4), 327 AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4),
322 }; 328 };
323 crate::pac::ADC_COMMON.ccr().modify(|w| w.set_ckmode(ckmode)); 329 common.ccr().modify(|w| w.set_ckmode(ckmode));
324 330
325 hclk / div 331 hclk / div
332 }
326 } 333 }
327 }; 334 };
328 335
329 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 336 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))]
330 let adc34 = match config.adc34 { 337 let adc34 = {
331 AdcClockSource::Pll(adcpres) => { 338 #[cfg(peri_adc3_common)]
332 RCC.cfgr2().modify(|w| w.set_adc34pres(adcpres)); 339 let common = crate::pac::ADC3_COMMON;
333 crate::pac::ADC3_COMMON 340 #[cfg(peri_adc34_common)]
334 .ccr() 341 let common = crate::pac::ADC34_COMMON;
335 .modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS)); 342
336 343 match config.adc34 {
337 unwrap!(pll) / adcpres 344 AdcClockSource::Pll(adcpres) => {
338 } 345 RCC.cfgr2().modify(|w| w.set_adc34pres(adcpres));
339 AdcClockSource::Hclk(adcpres) => { 346 common.ccr().modify(|w| w.set_ckmode(Ckmode::ASYNCHRONOUS));
340 assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1)); 347
348 unwrap!(pll) / adcpres
349 }
350 AdcClockSource::Hclk(adcpres) => {
351 assert!(!(adcpres == AdcHclkPrescaler::Div1 && config.ahb_pre != AHBPrescaler::DIV1));
341 352
342 let (div, ckmode) = match adcpres { 353 let (div, ckmode) = match adcpres {
343 AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1), 354 AdcHclkPrescaler::Div1 => (1u32, Ckmode::SYNCDIV1),
344 AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2), 355 AdcHclkPrescaler::Div2 => (2u32, Ckmode::SYNCDIV2),
345 AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4), 356 AdcHclkPrescaler::Div4 => (4u32, Ckmode::SYNCDIV4),
346 }; 357 };
347 crate::pac::ADC3_COMMON.ccr().modify(|w| w.set_ckmode(ckmode)); 358 common.ccr().modify(|w| w.set_ckmode(ckmode));
348 359
349 hclk / div 360 hclk / div
361 }
350 } 362 }
351 }; 363 };
352 364
diff --git a/examples/stm32f0/src/bin/adc.rs b/examples/stm32f0/src/bin/adc.rs
index a5a4186ea..8825e2687 100644
--- a/examples/stm32f0/src/bin/adc.rs
+++ b/examples/stm32f0/src/bin/adc.rs
@@ -4,13 +4,13 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::peripherals::ADC; 7use embassy_stm32::peripherals::ADC1;
8use embassy_stm32::{adc, bind_interrupts}; 8use embassy_stm32::{adc, bind_interrupts};
9use embassy_time::Timer; 9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12bind_interrupts!(struct Irqs { 12bind_interrupts!(struct Irqs {
13 ADC1_COMP => adc::InterruptHandler<ADC>; 13 ADC1_COMP => adc::InterruptHandler<ADC1>;
14}); 14});
15 15
16#[embassy_executor::main] 16#[embassy_executor::main]
@@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) {
18 let p = embassy_stm32::init(Default::default()); 18 let p = embassy_stm32::init(Default::default());
19 info!("Hello World!"); 19 info!("Hello World!");
20 20
21 let mut adc = Adc::new(p.ADC, Irqs); 21 let mut adc = Adc::new(p.ADC1, Irqs);
22 adc.set_sample_time(SampleTime::CYCLES71_5); 22 adc.set_sample_time(SampleTime::CYCLES71_5);
23 let mut pin = p.PA1; 23 let mut pin = p.PA1;
24 24
diff --git a/examples/stm32f4/src/bin/dac.rs b/examples/stm32f4/src/bin/dac.rs
index 9c7754c4f..dd2a45718 100644
--- a/examples/stm32f4/src/bin/dac.rs
+++ b/examples/stm32f4/src/bin/dac.rs
@@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) -> ! {
12 let p = embassy_stm32::init(Default::default()); 12 let p = embassy_stm32::init(Default::default());
13 info!("Hello World, dude!"); 13 info!("Hello World, dude!");
14 14
15 let mut dac = DacCh1::new(p.DAC, NoDma, p.PA4); 15 let mut dac = DacCh1::new(p.DAC1, NoDma, p.PA4);
16 16
17 loop { 17 loop {
18 for v in 0..=255 { 18 for v in 0..=255 {
diff --git a/examples/stm32l0/src/bin/adc.rs b/examples/stm32l0/src/bin/adc.rs
index 507c3204a..9dd09bc45 100644
--- a/examples/stm32l0/src/bin/adc.rs
+++ b/examples/stm32l0/src/bin/adc.rs
@@ -4,13 +4,13 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::adc::{Adc, SampleTime}; 6use embassy_stm32::adc::{Adc, SampleTime};
7use embassy_stm32::peripherals::ADC; 7use embassy_stm32::peripherals::ADC1;
8use embassy_stm32::{adc, bind_interrupts}; 8use embassy_stm32::{adc, bind_interrupts};
9use embassy_time::Timer; 9use embassy_time::Timer;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12bind_interrupts!(struct Irqs { 12bind_interrupts!(struct Irqs {
13 ADC1_COMP => adc::InterruptHandler<ADC>; 13 ADC1_COMP => adc::InterruptHandler<ADC1>;
14}); 14});
15 15
16#[embassy_executor::main] 16#[embassy_executor::main]
@@ -18,7 +18,7 @@ async fn main(_spawner: Spawner) {
18 let p = embassy_stm32::init(Default::default()); 18 let p = embassy_stm32::init(Default::default());
19 info!("Hello World!"); 19 info!("Hello World!");
20 20
21 let mut adc = Adc::new(p.ADC, Irqs); 21 let mut adc = Adc::new(p.ADC1, Irqs);
22 adc.set_sample_time(SampleTime::CYCLES79_5); 22 adc.set_sample_time(SampleTime::CYCLES79_5);
23 let mut pin = p.PA1; 23 let mut pin = p.PA1;
24 24
diff --git a/tests/stm32/src/bin/dac_l1.rs b/tests/stm32/src/bin/dac_l1.rs
index f8b00aaef..d5e9c9722 100644
--- a/tests/stm32/src/bin/dac_l1.rs
+++ b/tests/stm32/src/bin/dac_l1.rs
@@ -19,7 +19,7 @@ use micromath::F32Ext;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21bind_interrupts!(struct Irqs { 21bind_interrupts!(struct Irqs {
22 ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC>; 22 ADC1 => embassy_stm32::adc::InterruptHandler<peripherals::ADC1>;
23}); 23});
24 24
25#[embassy_executor::main] 25#[embassy_executor::main]
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index 0e555efc8..24d33dc3b 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -120,7 +120,7 @@ define_peris!(
120define_peris!( 120define_peris!(
121 UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1, 121 UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1,
122 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, 122 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
123 ADC = ADC1, DAC = DAC, DAC_PIN = PA4, 123 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
124 CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1, 124 CAN = CAN1, CAN_RX = PD0, CAN_TX = PD1,
125 @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;}, 125 @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;},
126); 126);
@@ -128,7 +128,7 @@ define_peris!(
128define_peris!( 128define_peris!(
129 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5, 129 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA2_CH7, UART_RX_DMA = DMA2_CH5,
130 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2, 130 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
131 ADC = ADC1, DAC = DAC, DAC_PIN = PA4, 131 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
132 CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12, 132 CAN = CAN1, CAN_RX = PA11, CAN_TX = PA12,
133 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, 133 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
134); 134);
@@ -210,7 +210,7 @@ define_peris!(
210define_peris!( 210define_peris!(
211 UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3, 211 UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
212 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, 212 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
213 ADC = ADC, DAC = DAC, DAC_PIN = PA4, 213 ADC = ADC1, DAC = DAC1, DAC_PIN = PA4,
214 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;}, 214 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
215); 215);
216#[cfg(feature = "stm32l552ze")] 216#[cfg(feature = "stm32l552ze")]