Skip to content

Commit 028140e

Browse files
committed
Generate both pin mappings and feature list
1 parent 8e5d235 commit 028140e

File tree

1 file changed

+92
-45
lines changed

1 file changed

+92
-45
lines changed

src/main.rs

Lines changed: 92 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,12 @@ mod internal_peripheral;
1010
mod mcu;
1111
mod utils;
1212

13+
#[derive(Debug, PartialEq)]
1314
enum GenerateTarget {
1415
PinMappings,
1516
Features,
1617
}
1718

18-
fn render_pin_modes(ip: &internal_peripheral::IpGPIO) {
19-
let mut pin_map: HashMap<String, Vec<String>> = HashMap::new();
20-
21-
for p in &ip.gpio_pin {
22-
let name = p.get_name();
23-
if let Some(n) = name {
24-
pin_map.insert(n, p.get_af_modes());
25-
}
26-
}
27-
28-
let mut pin_map = pin_map
29-
.into_iter()
30-
.map(|(k, mut v)| {
31-
#[allow(clippy::redundant_closure)]
32-
v.sort_by(|a, b| compare_str(a, b));
33-
(k, v)
34-
})
35-
.collect::<Vec<_>>();
36-
37-
pin_map.sort_by(|a, b| compare_str(&a.0, &b.0));
38-
39-
println!("pins! {{");
40-
for (n, af) in pin_map {
41-
if af.is_empty() {
42-
continue;
43-
} else if af.len() == 1 {
44-
println!(" {} => {{{}}},", n, af[0]);
45-
} else {
46-
println!(" {} => {{", n);
47-
for a in af {
48-
println!(" {},", a);
49-
}
50-
println!(" }},");
51-
}
52-
}
53-
println!("}}");
54-
}
55-
5619
lazy_static! {
5720
// Note: Version >1.0 is not currently supported
5821
static ref GPIO_VERSION: Regex = Regex::new("^([^_]*)_gpio_v1_0$").unwrap();
@@ -127,24 +90,108 @@ fn main() -> Result<(), String> {
12790
mcu_gpio_map
12891
.entry(gpio_version)
12992
.or_insert(vec![])
130-
.push(mcu.name.clone());
93+
.push(mcu.ref_name.clone());
13194
}
13295
}
13396

97+
match generate {
98+
GenerateTarget::Features => generate_features(&mcu_gpio_map)?,
99+
GenerateTarget::PinMappings => generate_pin_mappings(&mcu_gpio_map, &db_dir)?,
100+
};
101+
102+
Ok(())
103+
}
104+
105+
/// Print the IO features, followed by MCU features that act purely as aliases
106+
/// for the IO features.
107+
///
108+
/// Both lists are sorted alphanumerically.
109+
fn generate_features(mcu_gpio_map: &HashMap<String, Vec<String>>) -> Result<(), String> {
110+
let mut main_features = mcu_gpio_map
111+
.keys()
112+
.map(|gpio| gpio_version_to_feature(gpio))
113+
.collect::<Result<Vec<String>, String>>()?;
114+
main_features.sort();
115+
116+
let mut mcu_aliases = vec![];
134117
for (gpio, mcu_list) in mcu_gpio_map {
135-
let gpio_data = internal_peripheral::IpGPIO::load(db_dir, &gpio)
136-
.map_err(|e| format!("Could not load IP GPIO file: {}", e))?;
137-
println!("#[cfg(feature = \"{}\")]", gpio_version_to_feature(&gpio)?);
118+
let gpio_version_feature = gpio_version_to_feature(gpio).unwrap();
138119
for mcu in mcu_list {
139-
println!("// {}", mcu);
120+
let mcu_feature = format!("mcu-{}", mcu);
121+
mcu_aliases.push(format!("{} = [\"{}\"]", mcu_feature, gpio_version_feature));
140122
}
123+
}
124+
mcu_aliases.sort();
125+
126+
println!("// Features based on the GPIO peripheral version.");
127+
println!("// This determines the pin function mapping of the MCU.");
128+
for feature in main_features {
129+
println!("{} = []", feature);
130+
}
131+
println!("\n// Per-MCU aliases for the GPIO peripheral version.");
132+
for alias in mcu_aliases {
133+
println!("{}", alias);
134+
}
135+
136+
Ok(())
137+
}
138+
139+
/// Generate the pin mappings for the target MCU family.
140+
fn generate_pin_mappings(
141+
mcu_gpio_map: &HashMap<String, Vec<String>>,
142+
db_dir: &Path,
143+
) -> Result<(), String> {
144+
let mut gpio_versions = mcu_gpio_map.keys().collect::<Vec<_>>();
145+
gpio_versions.sort();
146+
for gpio in gpio_versions {
147+
let gpio_version_feature = gpio_version_to_feature(&gpio)?;
148+
println!("#[cfg(feature = \"{}\")]", gpio_version_feature);
149+
let gpio_data = internal_peripheral::IpGPIO::load(db_dir, &gpio)
150+
.map_err(|e| format!("Could not load IP GPIO file: {}", e))?;
141151
render_pin_modes(&gpio_data);
142152
println!("\n");
143153
}
144-
145154
Ok(())
146155
}
147156

157+
fn render_pin_modes(ip: &internal_peripheral::IpGPIO) {
158+
let mut pin_map: HashMap<String, Vec<String>> = HashMap::new();
159+
160+
for p in &ip.gpio_pin {
161+
let name = p.get_name();
162+
if let Some(n) = name {
163+
pin_map.insert(n, p.get_af_modes());
164+
}
165+
}
166+
167+
let mut pin_map = pin_map
168+
.into_iter()
169+
.map(|(k, mut v)| {
170+
#[allow(clippy::redundant_closure)]
171+
v.sort_by(|a, b| compare_str(a, b));
172+
(k, v)
173+
})
174+
.collect::<Vec<_>>();
175+
176+
pin_map.sort_by(|a, b| compare_str(&a.0, &b.0));
177+
178+
println!("pins! {{");
179+
for (n, af) in pin_map {
180+
if af.is_empty() {
181+
continue;
182+
} else if af.len() == 1 {
183+
println!(" {} => {{{}}},", n, af[0]);
184+
} else {
185+
println!(" {} => {{", n);
186+
for a in af {
187+
println!(" {},", a);
188+
}
189+
println!(" }},");
190+
}
191+
}
192+
println!("}}");
193+
}
194+
148195
#[cfg(test)]
149196
mod tests {
150197
use super::*;
@@ -165,7 +212,7 @@ mod tests {
165212
assert!(gpio_version_to_feature("STM32F333_gpio_v1_1").is_err());
166213

167214
// Error parsing, wrong pattern
168-
assert!(gpio_version_to_feature("STM32F333_asdf_v1_0").is_err());
215+
assert!(gpio_version_to_feature("STM32F333_qqio_v1_0").is_err());
169216

170217
// Error parsing, too many underscores
171218
assert!(gpio_version_to_feature("STM32_STM32F333_gpio_v1_0").is_err());

0 commit comments

Comments
 (0)