stm32-metapac: assume RCC is always present
This commit is contained in:
parent
f3de443ee7
commit
dd62790f36
@ -1,4 +1,5 @@
|
|||||||
use chiptool::generate::CommonModule;
|
use chiptool::generate::CommonModule;
|
||||||
|
use chiptool::ir::IR;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
@ -273,19 +274,18 @@ pub fn gen(options: Options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Load RCC register for chip
|
// Load RCC register for chip
|
||||||
let rcc = core.peripherals.iter().find_map(|(name, p)| {
|
let (_, rcc) = core
|
||||||
if name == "RCC" {
|
.peripherals
|
||||||
p.block.as_ref().map(|block| {
|
.iter()
|
||||||
let bi = BlockInfo::parse(block);
|
.find(|(name, _)| name == &"RCC")
|
||||||
let rcc_reg_path = data_dir
|
.expect("RCC peripheral missing");
|
||||||
.join("registers")
|
|
||||||
.join(&format!("{}_{}.yaml", bi.module, bi.version));
|
let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
|
||||||
serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap()
|
let bi = BlockInfo::parse(&rcc_block);
|
||||||
})
|
let rcc_reg_path = data_dir
|
||||||
} else {
|
.join("registers")
|
||||||
None
|
.join(&format!("{}_{}.yaml", bi.module, bi.version));
|
||||||
}
|
let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
|
||||||
});
|
|
||||||
|
|
||||||
let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
|
let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
|
||||||
let mut pin_table: Vec<Vec<String>> = Vec::new();
|
let mut pin_table: Vec<Vec<String>> = Vec::new();
|
||||||
@ -424,73 +424,71 @@ pub fn gen(options: Options) {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rcc) = &rcc {
|
// Workaround for clock registers being split on some chip families. Assume fields are
|
||||||
// Workaround for clock registers being split on some chip families. Assume fields are
|
// named after peripheral and look for first field matching and use that register.
|
||||||
// named after peripheral and look for first field matching and use that register.
|
let mut en = find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name));
|
||||||
let mut en = find_reg_for_field(&rcc, "^.+ENR\\d*$", &format!("{}EN", name));
|
let mut rst = find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
|
||||||
let mut rst = find_reg_for_field(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
|
|
||||||
|
|
||||||
if en.is_none() && name.ends_with("1") {
|
if en.is_none() && name.ends_with("1") {
|
||||||
en = find_reg_for_field(
|
en = find_reg_for_field(
|
||||||
&rcc,
|
&rcc,
|
||||||
"^.+ENR\\d*$",
|
"^.+ENR\\d*$",
|
||||||
&format!("{}EN", &name[..name.len() - 1]),
|
&format!("{}EN", &name[..name.len() - 1]),
|
||||||
);
|
);
|
||||||
rst = find_reg_for_field(
|
rst = find_reg_for_field(
|
||||||
&rcc,
|
&rcc,
|
||||||
"^.+RSTR\\d*$",
|
"^.+RSTR\\d*$",
|
||||||
&format!("{}RST", &name[..name.len() - 1]),
|
&format!("{}RST", &name[..name.len() - 1]),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
match (en, rst) {
|
||||||
|
(Some((enable_reg, enable_field)), reset_reg_field) => {
|
||||||
|
let clock = match &p.clock {
|
||||||
|
Some(clock) => clock.as_str(),
|
||||||
|
None => {
|
||||||
|
// No clock was specified, derive the clock name from the enable register name.
|
||||||
|
Regex::new("([A-Z]+\\d*).*")
|
||||||
|
.unwrap()
|
||||||
|
.captures(enable_reg)
|
||||||
|
.unwrap()
|
||||||
|
.get(1)
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let clock = if name.starts_with("TIM") {
|
||||||
|
format!("{}_tim", clock.to_ascii_lowercase())
|
||||||
|
} else {
|
||||||
|
clock.to_ascii_lowercase()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut row = Vec::with_capacity(6);
|
||||||
|
row.push(name.clone());
|
||||||
|
row.push(clock);
|
||||||
|
row.push(enable_reg.to_ascii_lowercase());
|
||||||
|
|
||||||
|
if let Some((reset_reg, reset_field)) = reset_reg_field {
|
||||||
|
row.push(reset_reg.to_ascii_lowercase());
|
||||||
|
row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
|
||||||
|
row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
|
||||||
|
} else {
|
||||||
|
row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if !name.starts_with("GPIO") {
|
||||||
|
peripheral_rcc_table.push(row);
|
||||||
|
} else {
|
||||||
|
gpio_rcc_table.push(row);
|
||||||
|
gpio_regs.insert(enable_reg.to_ascii_lowercase());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
(None, Some(_)) => {
|
||||||
match (en, rst) {
|
println!("Unable to find enable register for {}", name)
|
||||||
(Some((enable_reg, enable_field)), reset_reg_field) => {
|
}
|
||||||
let clock = match &p.clock {
|
(None, None) => {
|
||||||
Some(clock) => clock.as_str(),
|
println!("Unable to find enable and reset register for {}", name)
|
||||||
None => {
|
|
||||||
// No clock was specified, derive the clock name from the enable register name.
|
|
||||||
Regex::new("([A-Z]+\\d*).*")
|
|
||||||
.unwrap()
|
|
||||||
.captures(enable_reg)
|
|
||||||
.unwrap()
|
|
||||||
.get(1)
|
|
||||||
.unwrap()
|
|
||||||
.as_str()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let clock = if name.starts_with("TIM") {
|
|
||||||
format!("{}_tim", clock.to_ascii_lowercase())
|
|
||||||
} else {
|
|
||||||
clock.to_ascii_lowercase()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut row = Vec::with_capacity(6);
|
|
||||||
row.push(name.clone());
|
|
||||||
row.push(clock);
|
|
||||||
row.push(enable_reg.to_ascii_lowercase());
|
|
||||||
|
|
||||||
if let Some((reset_reg, reset_field)) = reset_reg_field {
|
|
||||||
row.push(reset_reg.to_ascii_lowercase());
|
|
||||||
row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
|
|
||||||
row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
|
|
||||||
} else {
|
|
||||||
row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !name.starts_with("GPIO") {
|
|
||||||
peripheral_rcc_table.push(row);
|
|
||||||
} else {
|
|
||||||
gpio_rcc_table.push(row);
|
|
||||||
gpio_regs.insert(enable_reg.to_ascii_lowercase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(None, Some(_)) => {
|
|
||||||
println!("Unable to find enable register for {}", name)
|
|
||||||
}
|
|
||||||
(None, None) => {
|
|
||||||
println!("Unable to find enable and reset register for {}", name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::env::args;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use stm32_metapac_gen::*;
|
use stm32_metapac_gen::*;
|
||||||
|
|
||||||
@ -5,13 +6,24 @@ fn main() {
|
|||||||
let out_dir = PathBuf::from("out");
|
let out_dir = PathBuf::from("out");
|
||||||
let data_dir = PathBuf::from("../stm32-data/data");
|
let data_dir = PathBuf::from("../stm32-data/data");
|
||||||
|
|
||||||
let chips = std::fs::read_dir(data_dir.join("chips"))
|
let args: Vec<String> = args().collect();
|
||||||
.unwrap()
|
|
||||||
.filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string()))
|
let chips = match &args[..] {
|
||||||
.filter(|s| s.ends_with(".yaml"))
|
[_, chip] => {
|
||||||
.filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride
|
vec![chip.clone()]
|
||||||
.map(|s| s.strip_suffix(".yaml").unwrap().to_string())
|
}
|
||||||
.collect();
|
[_] => {
|
||||||
|
std::fs::read_dir(data_dir.join("chips"))
|
||||||
|
.unwrap()
|
||||||
|
.filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string()))
|
||||||
|
.filter(|s| s.ends_with(".yaml"))
|
||||||
|
.filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride
|
||||||
|
.filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4
|
||||||
|
.map(|s| s.strip_suffix(".yaml").unwrap().to_string())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
_ => panic!("usage: stm32-metapac-gen [chip?]"),
|
||||||
|
};
|
||||||
|
|
||||||
gen(Options {
|
gen(Options {
|
||||||
out_dir,
|
out_dir,
|
||||||
|
Loading…
Reference in New Issue
Block a user