diff options
| author | xoviat <[email protected]> | 2023-10-01 12:36:21 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-10-01 12:36:21 +0000 |
| commit | 70005c3956dc985402824ad566eeb68546cb7f98 (patch) | |
| tree | 71d60b02036aec185f6cfc929c3efb95e8b39aec | |
| parent | 7bc57ca3f79b4b40ea11b11d34d82d933b198fba (diff) | |
| parent | 93adbb992218a43363fe20e5a740c3108bdaeeff (diff) | |
Merge pull request #1988 from JuliDi/expose-analog-switch-pins-rebased
[STM32] Handle STM32H7 "_C" pins (rebased)
| -rw-r--r-- | embassy-stm32/Cargo.toml | 21 | ||||
| -rw-r--r-- | embassy-stm32/build.rs | 92 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 12 |
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" | |||
| 59 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 59 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 60 | critical-section = "1.1" | 60 | critical-section = "1.1" |
| 61 | atomic-polyfill = "1.0.1" | 61 | atomic-polyfill = "1.0.1" |
| 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-735cab337aad6161f3d6bcf3e49cd1f034bc3130" } | 62 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-8ee2862086886cd8ebaf5fd5e3bd6cfbe5baa840" } |
| 63 | vcell = "0.1.3" | 63 | vcell = "0.1.3" |
| 64 | bxcan = "0.7.0" | 64 | bxcan = "0.7.0" |
| 65 | nb = "1.0.0" | 65 | nb = "1.0.0" |
| @@ -78,7 +78,8 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 78 | [build-dependencies] | 78 | [build-dependencies] |
| 79 | proc-macro2 = "1.0.36" | 79 | proc-macro2 = "1.0.36" |
| 80 | quote = "1.0.15" | 80 | quote = "1.0.15" |
| 81 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-735cab337aad6161f3d6bcf3e49cd1f034bc3130", default-features = false, features = ["metadata"]} | 81 | stm32-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] |
| 84 | default = ["rt"] | 85 | default = ["rt"] |
| @@ -134,6 +135,22 @@ time-driver-tim12 = ["_time-driver"] | |||
| 134 | time-driver-tim15 = ["_time-driver"] | 135 | time-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 | ||
| 143 | split-pa0 = ["_split-pins-enabled"] | ||
| 144 | ## Split PA1 | ||
| 145 | split-pa1 = ["_split-pins-enabled"] | ||
| 146 | ## Split PC2 | ||
| 147 | split-pc2 = ["_split-pins-enabled"] | ||
| 148 | ## Split PC3 | ||
| 149 | split-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)] |
