From 5924cc8b49e683c94873523ae97daf7d5ef5a5d5 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Wed, 13 Sep 2023 21:16:27 +0200 Subject: [PATCH 1/8] handle _C pins --- embassy-stm32/Cargo.toml | 16 +++++++++++ embassy-stm32/build.rs | 61 ++++++++++++++++++++++++++++++++++++++-- embassy-stm32/src/lib.rs | 12 ++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 1ef92430f..474ca6cd1 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -134,6 +134,22 @@ time-driver-tim12 = ["_time-driver"] time-driver-tim15 = ["_time-driver"] +#! ## Analog Switch Pins (Pxy_C) on STM32H7 series +#! Get `PXY` and `PXY_C` singletons. Digital impls are on `PXY`, Analog impls are on `PXY_C` +#! If disabled, you get only the `PXY` singleton. It has both digital and analog impls. + +## Split PA0 +split-pa0 = ["_split-pins-enabled"] +## Split PA1 +split-pa1 = ["_split-pins-enabled"] +## Split PC2 +split-pc2 = ["_split-pins-enabled"] +## Split PC3 +split-pc3 = ["_split-pins-enabled"] + +## internal use only +_split-pins-enabled = [] + #! ## Chip-selection features #! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`. #! Check the `Cargo.toml` for the latest list of supported chips. diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index ccc9210df..2795f2597 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -81,6 +81,16 @@ fn main() { singletons.push(c.name.to_string()); } + // Extra analog switch pins available on most H7 chips + #[cfg(feature = "split-pa0")] + singletons.push("PA0_C".into()); + #[cfg(feature = "split-pa1")] + singletons.push("PA1_C".into()); + #[cfg(feature = "split-pc2")] + singletons.push("PC2_C".into()); + #[cfg(feature = "split-pc3")] + singletons.push("PC3_C".into()); + // ======== // Handle time-driver-XXXX features. @@ -679,7 +689,31 @@ fn main() { let key = (regs.kind, pin.signal); if let Some(tr) = signals.get(&key) { let mut peri = format_ident!("{}", p.name); - let pin_name = format_ident!("{}", pin.pin); + let pin_name = { + #[allow(unused_mut)] + let mut pin_name = pin.pin; + + #[cfg(not(feature = "split-pa0"))] + if pin.pin == "PA0_C" { + pin_name = "PA0"; + } + #[cfg(not(feature = "split-pa1"))] + if pin.pin == "PA1_C" { + pin_name = "PA1"; + } + + #[cfg(not(feature = "split-pc2"))] + if pin.pin == "PC2_C" { + pin_name = "PC2"; + } + #[cfg(not(feature = "split-pc3"))] + if pin.pin == "PC3_C" { + pin_name = "PC3"; + } + + format_ident!("{}", pin_name) + }; + let af = pin.af.unwrap_or(0); // MCO is special @@ -716,7 +750,30 @@ fn main() { } let peri = format_ident!("{}", p.name); - let pin_name = format_ident!("{}", pin.pin); + let pin_name = { + #[allow(unused_mut)] + let mut pin_name = pin.pin; + + #[cfg(not(feature = "split-pa0"))] + if pin.pin == "PA0_C" { + pin_name = "PA0"; + } + #[cfg(not(feature = "split-pa1"))] + if pin.pin == "PA1_C" { + pin_name = "PA1"; + } + + #[cfg(not(feature = "split-pc2"))] + if pin.pin == "PC2_C" { + pin_name = "PC2"; + } + #[cfg(not(feature = "split-pc3"))] + if pin.pin == "PC3_C" { + pin_name = "PC3"; + } + + format_ident!("{}", pin_name) + }; // H7 has differential voltage measurements let ch: Option = if pin.signal.starts_with("INP") { diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 2718c96da..9dd2f6163 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -191,6 +191,18 @@ pub fn init(config: Config) -> Peripherals { peripherals::FLASH::enable(); unsafe { + #[cfg(feature = "_split-pins-enabled")] + crate::pac::SYSCFG.pmcr().modify(|pmcr| { + #[cfg(feature = "split-pa0")] + pmcr.set_pa0so(true); + #[cfg(feature = "split-pa1")] + pmcr.set_pa1so(true); + #[cfg(feature = "split-pc2")] + pmcr.set_pc2so(true); + #[cfg(feature = "split-pc3")] + pmcr.set_pc3so(true); + }); + gpio::init(); dma::init( #[cfg(bdma)] From 6e5f3f95159a8fe22f2bc140aace726f57acc359 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Thu, 14 Sep 2023 16:34:01 +0200 Subject: [PATCH 2/8] update to testing pr #1889 --- embassy-stm32/Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 474ca6cd1..933759549 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-735cab337aad6161f3d6bcf3e49cd1f034bc3130" } +stm32-metapac = { git = "https://ci.embassy.dev/jobs/8f9e48d47e3f/artifacts/generated.git" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,8 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-735cab337aad6161f3d6bcf3e49cd1f034bc3130", default-features = false, features = ["metadata"]} + +stm32-metapac = { git = "https://ci.embassy.dev/jobs/8f9e48d47e3f/artifacts/generated.git", default-features = false, features = ["metadata"]} [features] default = ["rt"] From f116ca83e0e5d78e8bac92d037b90fc7deaecc55 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:36:06 +0200 Subject: [PATCH 3/8] check whether split-feature is valid --- embassy-stm32/build.rs | 51 +++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 2795f2597..00f52294c 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -81,15 +81,36 @@ fn main() { singletons.push(c.name.to_string()); } + let mut pin_set = std::collections::HashSet::new(); + for p in METADATA.peripherals { + for pin in p.pins { + pin_set.insert(pin.pin); + } + } + // Extra analog switch pins available on most H7 chips - #[cfg(feature = "split-pa0")] - singletons.push("PA0_C".into()); - #[cfg(feature = "split-pa1")] - singletons.push("PA1_C".into()); - #[cfg(feature = "split-pc2")] - singletons.push("PC2_C".into()); - #[cfg(feature = "split-pc3")] - singletons.push("PC3_C".into()); + let split_features = [ + #[cfg(feature = "split-pa0")] + ("split-pa0", "PA0_C"), + #[cfg(feature = "split-pa1")] + ("split-pa1", "PA1_C"), + #[cfg(feature = "split-pc2")] + ("split-pc2", "PC2_C"), + #[cfg(feature = "split-pc3")] + ("split-pc3", "PC3_C"), + ]; + + for (feature_name, pin_name) in split_features { + if pin_set.contains(pin_name) { + singletons.push(pin_name.into()); + } else { + panic!( + "'{}' feature invalid for this chip! No pin '{}' found.\n + Found pins: {:#?}", + feature_name, pin_name, pin_set + ) + } + } // ======== // Handle time-driver-XXXX features. @@ -923,6 +944,20 @@ fn main() { for pin_num in 0u32..16 { let pin_name = format!("P{}{}", port_letter, pin_num); + + // TODO: Here we need to take care of the _C pins properly. + // Maybe it would be better to not iterate over 0..16 but the + // Pin names directly. However, this might have side-effects... :( + if pin_name == "PC2" { + pins_table.push(vec![ + "PC2_C".to_string(), + p.name.to_string(), + port_num.to_string(), + "2".to_string(), + format!("EXTI{}", 2), + ]); + } + pins_table.push(vec![ pin_name, p.name.to_string(), From 49608714aaa509bd7720c2e8b68b3bf743cdfb39 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Wed, 27 Sep 2023 20:58:00 +0200 Subject: [PATCH 4/8] cleanup, fix pushing to pins_table --- embassy-stm32/build.rs | 122 +++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 00f52294c..717da9049 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -88,26 +88,48 @@ fn main() { } } + struct SplitFeature { + feature_name: String, + pin_name_with_c: String, + pin_name_without_c: String, + } + // Extra analog switch pins available on most H7 chips let split_features = [ #[cfg(feature = "split-pa0")] - ("split-pa0", "PA0_C"), + SplitFeature { + feature_name: "split-pa0".to_string(), + pin_name_with_c: "PA0_C".to_string(), + pin_name_without_c: "PA0".to_string(), + }, #[cfg(feature = "split-pa1")] - ("split-pa1", "PA1_C"), + SplitFeature { + feature_name: "split-pa1".to_string(), + pin_name_with_c: "PA1_C".to_string(), + pin_name_without_c: "PA1".to_string(), + }, #[cfg(feature = "split-pc2")] - ("split-pc2", "PC2_C"), + SplitFeature { + feature_name: "split-pc2".to_string(), + pin_name_with_c: "PC2_C".to_string(), + pin_name_without_c: "PC2".to_string(), + }, #[cfg(feature = "split-pc3")] - ("split-pc3", "PC3_C"), + SplitFeature { + feature_name: "split-pc3".to_string(), + pin_name_with_c: "PC3_C".to_string(), + pin_name_without_c: "PC3".to_string(), + }, ]; - for (feature_name, pin_name) in split_features { - if pin_set.contains(pin_name) { - singletons.push(pin_name.into()); + for split_feature in &split_features { + if pin_set.contains(split_feature.pin_name_with_c.as_str()) { + singletons.push(split_feature.pin_name_with_c.clone()); } else { panic!( "'{}' feature invalid for this chip! No pin '{}' found.\n Found pins: {:#?}", - feature_name, pin_name, pin_set + split_feature.feature_name, split_feature.pin_name_with_c, pin_set ) } } @@ -711,25 +733,13 @@ fn main() { if let Some(tr) = signals.get(&key) { let mut peri = format_ident!("{}", p.name); let pin_name = { - #[allow(unused_mut)] - let mut pin_name = pin.pin; - - #[cfg(not(feature = "split-pa0"))] - if pin.pin == "PA0_C" { - pin_name = "PA0"; - } - #[cfg(not(feature = "split-pa1"))] - if pin.pin == "PA1_C" { - pin_name = "PA1"; - } - - #[cfg(not(feature = "split-pc2"))] - if pin.pin == "PC2_C" { - pin_name = "PC2"; - } - #[cfg(not(feature = "split-pc3"))] - if pin.pin == "PC3_C" { - pin_name = "PC3"; + // If we encounter a "_C" pin, we remove the suffix + let mut pin_name = pin.pin.strip_suffix("_C").unwrap_or(pin.pin).to_string(); + // However, if the corresponding split_feature is enabled, we actually do want the pin name including "_C" + for split_feature in &split_features { + if pin.pin == split_feature.pin_name_with_c { + pin_name = split_feature.pin_name_with_c.clone(); + } } format_ident!("{}", pin_name) @@ -772,25 +782,13 @@ fn main() { let peri = format_ident!("{}", p.name); let pin_name = { - #[allow(unused_mut)] - let mut pin_name = pin.pin; - - #[cfg(not(feature = "split-pa0"))] - if pin.pin == "PA0_C" { - pin_name = "PA0"; - } - #[cfg(not(feature = "split-pa1"))] - if pin.pin == "PA1_C" { - pin_name = "PA1"; - } - - #[cfg(not(feature = "split-pc2"))] - if pin.pin == "PC2_C" { - pin_name = "PC2"; - } - #[cfg(not(feature = "split-pc3"))] - if pin.pin == "PC3_C" { - pin_name = "PC3"; + // If we encounter a "_C" pin, we remove the suffix + let mut pin_name = pin.pin.strip_suffix("_C").unwrap_or(pin.pin).to_string(); + // However, if the corresponding split_feature is enabled, we actually do want the pin name including "_C" + for split_feature in &split_features { + if pin.pin == split_feature.pin_name_with_c { + pin_name = split_feature.pin_name_with_c.clone(); + } } format_ident!("{}", pin_name) @@ -945,26 +943,30 @@ fn main() { for pin_num in 0u32..16 { let pin_name = format!("P{}{}", port_letter, pin_num); - // TODO: Here we need to take care of the _C pins properly. - // Maybe it would be better to not iterate over 0..16 but the - // Pin names directly. However, this might have side-effects... :( - if pin_name == "PC2" { - pins_table.push(vec![ - "PC2_C".to_string(), - p.name.to_string(), - port_num.to_string(), - "2".to_string(), - format!("EXTI{}", 2), - ]); - } - pins_table.push(vec![ - pin_name, + pin_name.clone(), p.name.to_string(), port_num.to_string(), pin_num.to_string(), format!("EXTI{}", pin_num), ]); + + // If we have the split pins, we need to do a little extra work: + // Add the "_C" variant to the table. The solution is not optimal, though. + // Adding them only when the corresponding GPIOx also appears. + // This should avoid unintended side-effects as much as possible. + #[cfg(feature = "_split-pins-enabled")] + for split_feature in &split_features { + if split_feature.pin_name_without_c == pin_name { + pins_table.push(vec![ + split_feature.pin_name_with_c.to_string(), + p.name.to_string(), + port_num.to_string(), + pin_num.to_string(), + format!("EXTI{}", pin_num), + ]); + } + } } } From 5c831790714c3b358046cf1be81ac530032dc688 Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Wed, 27 Sep 2023 21:02:26 +0200 Subject: [PATCH 5/8] change split_features from array to Vec --- embassy-stm32/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 717da9049..005ec5280 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -95,7 +95,7 @@ fn main() { } // Extra analog switch pins available on most H7 chips - let split_features = [ + let split_features: Vec = vec![ #[cfg(feature = "split-pa0")] SplitFeature { feature_name: "split-pa0".to_string(), From 5cb58754d49642fb0789625efe48ab3c37ae9fee Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sat, 30 Sep 2023 10:10:06 +0200 Subject: [PATCH 6/8] skip _C pins for pin impls if split_feature not enabled. --- embassy-stm32/build.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 005ec5280..2c349e55e 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -732,17 +732,14 @@ fn main() { let key = (regs.kind, pin.signal); if let Some(tr) = signals.get(&key) { let mut peri = format_ident!("{}", p.name); + let pin_name = { - // If we encounter a "_C" pin, we remove the suffix - let mut pin_name = pin.pin.strip_suffix("_C").unwrap_or(pin.pin).to_string(); - // However, if the corresponding split_feature is enabled, we actually do want the pin name including "_C" - for split_feature in &split_features { - if pin.pin == split_feature.pin_name_with_c { - pin_name = split_feature.pin_name_with_c.clone(); - } + // If we encounter a _C pin but the split_feature for this pin is not enabled, skip it + if pin.pin.ends_with("_C") && !split_features.iter().any(|x| x.pin_name_with_c == pin.pin) { + continue; } - format_ident!("{}", pin_name) + format_ident!("{}", pin.pin) }; let af = pin.af.unwrap_or(0); @@ -782,16 +779,11 @@ fn main() { let peri = format_ident!("{}", p.name); let pin_name = { - // If we encounter a "_C" pin, we remove the suffix - let mut pin_name = pin.pin.strip_suffix("_C").unwrap_or(pin.pin).to_string(); - // However, if the corresponding split_feature is enabled, we actually do want the pin name including "_C" - for split_feature in &split_features { - if pin.pin == split_feature.pin_name_with_c { - pin_name = split_feature.pin_name_with_c.clone(); - } + // If we encounter a _C pin but the split_feature for this pin is not enabled, skip it + if pin.pin.ends_with("_C") && !split_features.iter().any(|x| x.pin_name_with_c == pin.pin) { + continue; } - - format_ident!("{}", pin_name) + format_ident!("{}", pin.pin) }; // H7 has differential voltage measurements From e80df91e02f32e9cc207a7ef94d1b173eee1f45d Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sun, 1 Oct 2023 12:30:30 +0200 Subject: [PATCH 7/8] update stm32-metapac revision --- embassy-stm32/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 933759549..9954ef439 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -78,7 +78,6 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" - stm32-metapac = { git = "https://ci.embassy.dev/jobs/8f9e48d47e3f/artifacts/generated.git", default-features = false, features = ["metadata"]} [features] From 93adbb992218a43363fe20e5a740c3108bdaeeff Mon Sep 17 00:00:00 2001 From: JuliDi <20155974+JuliDi@users.noreply.github.com> Date: Sun, 1 Oct 2023 12:41:08 +0200 Subject: [PATCH 8/8] update stm32-metapac --- embassy-stm32/Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index 9954ef439..87f9083b3 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -59,7 +59,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = { git = "https://ci.embassy.dev/jobs/8f9e48d47e3f/artifacts/generated.git" } +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -78,7 +78,8 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { git = "https://ci.embassy.dev/jobs/8f9e48d47e3f/artifacts/generated.git", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840", default-features = false, features = ["metadata"]} + [features] default = ["rt"]