aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-10-01 12:36:21 +0000
committerGitHub <[email protected]>2023-10-01 12:36:21 +0000
commit70005c3956dc985402824ad566eeb68546cb7f98 (patch)
tree71d60b02036aec185f6cfc929c3efb95e8b39aec
parent7bc57ca3f79b4b40ea11b11d34d82d933b198fba (diff)
parent93adbb992218a43363fe20e5a740c3108bdaeeff (diff)
Merge pull request #1988 from JuliDi/expose-analog-switch-pins-rebased
[STM32] Handle STM32H7 "_C" pins (rebased)
-rw-r--r--embassy-stm32/Cargo.toml21
-rw-r--r--embassy-stm32/build.rs92
-rw-r--r--embassy-stm32/src/lib.rs12
3 files changed, 120 insertions, 5 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 1ef92430f..87f9083b3 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -59,7 +59,7 @@ sdio-host = "0.5.0"
59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } 59embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true }
60critical-section = "1.1" 60critical-section = "1.1"
61atomic-polyfill = "1.0.1" 61atomic-polyfill = "1.0.1"
62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-735cab337aad6161f3d6bcf3e49cd1f034bc3130" } 62stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840" }
63vcell = "0.1.3" 63vcell = "0.1.3"
64bxcan = "0.7.0" 64bxcan = "0.7.0"
65nb = "1.0.0" 65nb = "1.0.0"
@@ -78,7 +78,8 @@ critical-section = { version = "1.1", features = ["std"] }
78[build-dependencies] 78[build-dependencies]
79proc-macro2 = "1.0.36" 79proc-macro2 = "1.0.36"
80quote = "1.0.15" 80quote = "1.0.15"
81stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-735cab337aad6161f3d6bcf3e49cd1f034bc3130", default-features = false, features = ["metadata"]} 81stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840", default-features = false, features = ["metadata"]}
82
82 83
83[features] 84[features]
84default = ["rt"] 85default = ["rt"]
@@ -134,6 +135,22 @@ time-driver-tim12 = ["_time-driver"]
134time-driver-tim15 = ["_time-driver"] 135time-driver-tim15 = ["_time-driver"]
135 136
136 137
138#! ## Analog Switch Pins (Pxy_C) on STM32H7 series
139#! Get `PXY` and `PXY_C` singletons. Digital impls are on `PXY`, Analog impls are on `PXY_C`
140#! If disabled, you get only the `PXY` singleton. It has both digital and analog impls.
141
142## Split PA0
143split-pa0 = ["_split-pins-enabled"]
144## Split PA1
145split-pa1 = ["_split-pins-enabled"]
146## Split PC2
147split-pc2 = ["_split-pins-enabled"]
148## Split PC3
149split-pc3 = ["_split-pins-enabled"]
150
151## internal use only
152_split-pins-enabled = []
153
137#! ## Chip-selection features 154#! ## Chip-selection features
138#! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`. 155#! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`.
139#! Check the `Cargo.toml` for the latest list of supported chips. 156#! 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..2c349e55e 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -81,6 +81,59 @@ fn main() {
81 singletons.push(c.name.to_string()); 81 singletons.push(c.name.to_string());
82 } 82 }
83 83
84 let mut pin_set = std::collections::HashSet::new();
85 for p in METADATA.peripherals {
86 for pin in p.pins {
87 pin_set.insert(pin.pin);
88 }
89 }
90
91 struct SplitFeature {
92 feature_name: String,
93 pin_name_with_c: String,
94 pin_name_without_c: String,
95 }
96
97 // Extra analog switch pins available on most H7 chips
98 let split_features: Vec<SplitFeature> = vec![
99 #[cfg(feature = "split-pa0")]
100 SplitFeature {
101 feature_name: "split-pa0".to_string(),
102 pin_name_with_c: "PA0_C".to_string(),
103 pin_name_without_c: "PA0".to_string(),
104 },
105 #[cfg(feature = "split-pa1")]
106 SplitFeature {
107 feature_name: "split-pa1".to_string(),
108 pin_name_with_c: "PA1_C".to_string(),
109 pin_name_without_c: "PA1".to_string(),
110 },
111 #[cfg(feature = "split-pc2")]
112 SplitFeature {
113 feature_name: "split-pc2".to_string(),
114 pin_name_with_c: "PC2_C".to_string(),
115 pin_name_without_c: "PC2".to_string(),
116 },
117 #[cfg(feature = "split-pc3")]
118 SplitFeature {
119 feature_name: "split-pc3".to_string(),
120 pin_name_with_c: "PC3_C".to_string(),
121 pin_name_without_c: "PC3".to_string(),
122 },
123 ];
124
125 for split_feature in &split_features {
126 if pin_set.contains(split_feature.pin_name_with_c.as_str()) {
127 singletons.push(split_feature.pin_name_with_c.clone());
128 } else {
129 panic!(
130 "'{}' feature invalid for this chip! No pin '{}' found.\n
131 Found pins: {:#?}",
132 split_feature.feature_name, split_feature.pin_name_with_c, pin_set
133 )
134 }
135 }
136
84 // ======== 137 // ========
85 // Handle time-driver-XXXX features. 138 // Handle time-driver-XXXX features.
86 139
@@ -679,7 +732,16 @@ fn main() {
679 let key = (regs.kind, pin.signal); 732 let key = (regs.kind, pin.signal);
680 if let Some(tr) = signals.get(&key) { 733 if let Some(tr) = signals.get(&key) {
681 let mut peri = format_ident!("{}", p.name); 734 let mut peri = format_ident!("{}", p.name);
682 let pin_name = format_ident!("{}", pin.pin); 735
736 let pin_name = {
737 // If we encounter a _C pin but the split_feature for this pin is not enabled, skip it
738 if pin.pin.ends_with("_C") && !split_features.iter().any(|x| x.pin_name_with_c == pin.pin) {
739 continue;
740 }
741
742 format_ident!("{}", pin.pin)
743 };
744
683 let af = pin.af.unwrap_or(0); 745 let af = pin.af.unwrap_or(0);
684 746
685 // MCO is special 747 // MCO is special
@@ -716,7 +778,13 @@ fn main() {
716 } 778 }
717 779
718 let peri = format_ident!("{}", p.name); 780 let peri = format_ident!("{}", p.name);
719 let pin_name = format_ident!("{}", pin.pin); 781 let pin_name = {
782 // If we encounter a _C pin but the split_feature for this pin is not enabled, skip it
783 if pin.pin.ends_with("_C") && !split_features.iter().any(|x| x.pin_name_with_c == pin.pin) {
784 continue;
785 }
786 format_ident!("{}", pin.pin)
787 };
720 788
721 // H7 has differential voltage measurements 789 // H7 has differential voltage measurements
722 let ch: Option<u8> = if pin.signal.starts_with("INP") { 790 let ch: Option<u8> = if pin.signal.starts_with("INP") {
@@ -866,13 +934,31 @@ fn main() {
866 934
867 for pin_num in 0u32..16 { 935 for pin_num in 0u32..16 {
868 let pin_name = format!("P{}{}", port_letter, pin_num); 936 let pin_name = format!("P{}{}", port_letter, pin_num);
937
869 pins_table.push(vec![ 938 pins_table.push(vec![
870 pin_name, 939 pin_name.clone(),
871 p.name.to_string(), 940 p.name.to_string(),
872 port_num.to_string(), 941 port_num.to_string(),
873 pin_num.to_string(), 942 pin_num.to_string(),
874 format!("EXTI{}", pin_num), 943 format!("EXTI{}", pin_num),
875 ]); 944 ]);
945
946 // If we have the split pins, we need to do a little extra work:
947 // Add the "_C" variant to the table. The solution is not optimal, though.
948 // Adding them only when the corresponding GPIOx also appears.
949 // This should avoid unintended side-effects as much as possible.
950 #[cfg(feature = "_split-pins-enabled")]
951 for split_feature in &split_features {
952 if split_feature.pin_name_without_c == pin_name {
953 pins_table.push(vec![
954 split_feature.pin_name_with_c.to_string(),
955 p.name.to_string(),
956 port_num.to_string(),
957 pin_num.to_string(),
958 format!("EXTI{}", pin_num),
959 ]);
960 }
961 }
876 } 962 }
877 } 963 }
878 964
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 {
191 peripherals::FLASH::enable(); 191 peripherals::FLASH::enable();
192 192
193 unsafe { 193 unsafe {
194 #[cfg(feature = "_split-pins-enabled")]
195 crate::pac::SYSCFG.pmcr().modify(|pmcr| {
196 #[cfg(feature = "split-pa0")]
197 pmcr.set_pa0so(true);
198 #[cfg(feature = "split-pa1")]
199 pmcr.set_pa1so(true);
200 #[cfg(feature = "split-pc2")]
201 pmcr.set_pc2so(true);
202 #[cfg(feature = "split-pc3")]
203 pmcr.set_pc3so(true);
204 });
205
194 gpio::init(); 206 gpio::init();
195 dma::init( 207 dma::init(
196 #[cfg(bdma)] 208 #[cfg(bdma)]