Merge pull request #254 from JuliDi/dont-remove-analogswitch-pins
Handle "_C" pins
This commit is contained in:
commit
8ee2862086
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -620,6 +620,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"rayon",
|
||||
"ref_thread_local",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -68,7 +68,7 @@ pub struct ChipGroup {
|
||||
chip_names: Vec<String>,
|
||||
xml: xml::Mcu,
|
||||
ips: HashMap<String, xml::Ip>,
|
||||
pins: HashMap<stm32_data_serde::chip::core::peripheral::pin::Pin, xml::Pin>,
|
||||
pins: HashMap<String, xml::Pin>,
|
||||
family: Option<String>,
|
||||
line: Option<String>,
|
||||
die: Option<String>,
|
||||
@ -503,18 +503,20 @@ fn merge_periph_pins_info(
|
||||
}
|
||||
|
||||
// covert to hashmap
|
||||
let af_pins: HashMap<(stm32_data_serde::chip::core::peripheral::pin::Pin, &str), Option<u8>> =
|
||||
af_pins.iter().map(|v| ((v.pin, v.signal.as_str()), v.af)).collect();
|
||||
let af_pins: HashMap<(&str, &str), Option<u8>> = af_pins
|
||||
.iter()
|
||||
.map(|v| ((v.pin.as_str(), v.signal.as_str()), v.af))
|
||||
.collect();
|
||||
|
||||
for pin in core_pins {
|
||||
let af = af_pins.get(&(pin.pin, &pin.signal)).copied().flatten();
|
||||
let af = af_pins.get(&(&pin.pin, &pin.signal)).copied().flatten();
|
||||
|
||||
// try to look for a signal with another name
|
||||
let af = af.or_else(|| {
|
||||
if pin.signal == "CTS" {
|
||||
// for some godforsaken reason UART4's and UART5's CTS are called CTS_NSS in the GPIO xml
|
||||
// so try to match with these
|
||||
af_pins.get(&(pin.pin, "CTS_NSS")).copied().flatten()
|
||||
af_pins.get(&(pin.pin.as_str(), "CTS_NSS")).copied().flatten()
|
||||
} else if periph_name == "I2C1" {
|
||||
// it appears that for __some__ STM32 MCUs there is no AFIO specified in GPIO file
|
||||
// (notably - STM32F030C6 with it's I2C1 on PF6 and PF7)
|
||||
@ -910,7 +912,7 @@ fn process_core(
|
||||
if let Some(signal) = signal.strip_prefix(&format!("{periph}_")) {
|
||||
periph_pins.entry(periph.to_string()).or_default().push(
|
||||
stm32_data_serde::chip::core::peripheral::Pin {
|
||||
pin: *pin_name,
|
||||
pin: pin_name.clone(),
|
||||
signal: signal.to_string(),
|
||||
af: None,
|
||||
},
|
||||
@ -1002,7 +1004,7 @@ fn process_core(
|
||||
}
|
||||
|
||||
p.pins.extend(i2s_pins.iter().map(|p| Pin {
|
||||
pin: p.pin,
|
||||
pin: p.pin.clone(),
|
||||
signal: "I2S_".to_owned() + &p.signal,
|
||||
af: p.af,
|
||||
}));
|
||||
|
@ -38,16 +38,9 @@ mod xml {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clean_pin(pin_name: &str) -> Option<stm32_data_serde::chip::core::peripheral::pin::Pin> {
|
||||
// some H7s have analog-only pins like PC2_C, PC3_C. Ignore these for now since the
|
||||
// data model can't deal with pins that are not part of a GPIO port yet.
|
||||
if regex!(r"^P[A-Z]\d+_C$").is_match(pin_name) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let pin_name = regex!(r"^P[A-Z]\d+").find(pin_name)?.as_str();
|
||||
|
||||
stm32_data_serde::chip::core::peripheral::pin::Pin::parse(pin_name)
|
||||
pub fn clean_pin(pin_name: &str) -> Option<String> {
|
||||
// Some H7 chips have additonal "_C" pins.
|
||||
Some(regex!(r"^P[A-Z]\d+(?:_C)?").find(pin_name)?.as_str().into())
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@ -87,7 +80,7 @@ impl Af {
|
||||
};
|
||||
peris.entry(peri_name.to_string()).or_default().push(
|
||||
stm32_data_serde::chip::core::peripheral::Pin {
|
||||
pin: pin_name,
|
||||
pin: pin_name.clone(),
|
||||
signal: signal_name.to_string(),
|
||||
af: afn,
|
||||
},
|
||||
|
@ -7,6 +7,8 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.157", features = ["derive"] }
|
||||
regex = "1.7.1"
|
||||
ref_thread_local = "0.1.1"
|
||||
|
||||
[dev-dependencies]
|
||||
itertools = "0.10.5"
|
||||
|
@ -1,5 +1,15 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! regex {
|
||||
($re:literal) => {{
|
||||
::ref_thread_local::ref_thread_local! {
|
||||
static managed REGEX: ::regex::Regex = ::regex::Regex::new($re).unwrap();
|
||||
}
|
||||
<REGEX as ::ref_thread_local::RefThreadLocal<::regex::Regex>>::borrow(®EX)
|
||||
}};
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct Chip {
|
||||
pub name: String,
|
||||
@ -121,76 +131,51 @@ pub mod chip {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
pub struct Pin {
|
||||
pub pin: pin::Pin,
|
||||
pub pin: String,
|
||||
pub signal: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub af: Option<u8>,
|
||||
}
|
||||
|
||||
pub mod pin {
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
|
||||
pub struct Pin {
|
||||
pub port: char,
|
||||
pub num: u8,
|
||||
fn extract_port_and_pin(pin: &str) -> (char, u8) {
|
||||
let captures = regex!(r"^P([A-Z])(\d+)(?:_C)?")
|
||||
.captures(pin)
|
||||
.expect("Could not match regex on pin");
|
||||
let port = captures
|
||||
.get(1)
|
||||
.expect("Could not extract port")
|
||||
.as_str()
|
||||
.chars()
|
||||
.next()
|
||||
.expect("Empty port");
|
||||
let pin_number = captures
|
||||
.get(2)
|
||||
.expect("Could not extract pin number")
|
||||
.as_str()
|
||||
.parse::<u8>()
|
||||
.expect("Could not parse pin number to u8");
|
||||
(port, pin_number)
|
||||
}
|
||||
|
||||
impl Pin {
|
||||
pub fn parse(pin: &str) -> Option<Self> {
|
||||
let mut chars = pin.chars();
|
||||
let p = chars.next()?;
|
||||
if p != 'P' {
|
||||
return None;
|
||||
}
|
||||
let port = chars.next()?;
|
||||
let num = chars.as_str().parse().ok()?;
|
||||
impl Ord for Pin {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
let (port_a, pin_number_a) = extract_port_and_pin(&self.pin);
|
||||
let (port_b, pin_number_b) = extract_port_and_pin(&other.pin);
|
||||
|
||||
Some(Self { port, num })
|
||||
if port_a != port_b {
|
||||
port_a.cmp(&port_b)
|
||||
} else if pin_number_a != pin_number_b {
|
||||
pin_number_a.cmp(&pin_number_b)
|
||||
} else {
|
||||
self.signal.cmp(&other.signal)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Pin {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "P{}{}", self.port, self.num)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Pin {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&format!("{self}"))
|
||||
}
|
||||
}
|
||||
|
||||
struct PinVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for PinVisitor {
|
||||
type Value = Pin;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("pin")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(Pin::parse(v).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Pin {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(PinVisitor)
|
||||
}
|
||||
impl PartialOrd for Pin {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user