Ensure no duplicate irqs with the same signal.
This commit is contained in:
parent
f5a4c58efa
commit
4852f5040a
@ -79,6 +79,8 @@ impl ChipInterrupts {
|
|||||||
h: &crate::header::ParsedHeader,
|
h: &crate::header::ParsedHeader,
|
||||||
group: &ChipGroup,
|
group: &ChipGroup,
|
||||||
) {
|
) {
|
||||||
|
trace!("parsing interrupts for chip {} core {}", chip_name, core.name);
|
||||||
|
|
||||||
// =================== Populate nvic_priority_bits
|
// =================== Populate nvic_priority_bits
|
||||||
// With the current data sources, this value is always either 2 or 4, and never resolves to None
|
// With the current data sources, this value is always either 2 or 4, and never resolves to None
|
||||||
let header_defines = h.get_defines(&core.name);
|
let header_defines = h.get_defines(&core.name);
|
||||||
@ -113,7 +115,8 @@ impl ChipInterrupts {
|
|||||||
.get(&(chip_nvic.name.clone(), chip_nvic.version.clone()))
|
.get(&(chip_nvic.name.clone(), chip_nvic.version.clone()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut chip_signals = HashMap::<_, Vec<_>>::new();
|
// peripheral -> signal -> interrupts
|
||||||
|
let mut chip_signals = HashMap::<String, HashMap<String, HashSet<String>>>::new();
|
||||||
|
|
||||||
let exists_irq: HashSet<String> = core.interrupts.iter().map(|i| i.name.clone()).collect();
|
let exists_irq: HashSet<String> = core.interrupts.iter().map(|i| i.name.clone()).collect();
|
||||||
|
|
||||||
@ -135,7 +138,8 @@ impl ChipInterrupts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// More typos
|
// More typos
|
||||||
let mut name = name.replace("USAR11", "USART11");
|
let name = name.replace("USAR11", "USART11");
|
||||||
|
trace!(" name={name}");
|
||||||
|
|
||||||
// Skip interrupts that don't exist.
|
// Skip interrupts that don't exist.
|
||||||
// This is needed because NVIC files are shared between many chips.
|
// This is needed because NVIC files are shared between many chips.
|
||||||
@ -144,13 +148,14 @@ impl ChipInterrupts {
|
|||||||
("USB_HP_CAN_TX", &["CAN_TX"]),
|
("USB_HP_CAN_TX", &["CAN_TX"]),
|
||||||
("USB_LP_CAN_RX0", &["CAN_RX0"]),
|
("USB_LP_CAN_RX0", &["CAN_RX0"]),
|
||||||
];
|
];
|
||||||
|
let mut header_name = name.clone();
|
||||||
if !exists_irq.contains(&name) {
|
if !exists_irq.contains(&name) {
|
||||||
let &(_, eq_irqs) = EQUIVALENT_IRQS
|
let &(_, eq_irqs) = EQUIVALENT_IRQS
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(irq, _)| irq == &name)
|
.find(|(irq, _)| irq == &name)
|
||||||
.unwrap_or(&("", &[]));
|
.unwrap_or(&("", &[]));
|
||||||
let Some(new_name) = eq_irqs.iter().find(|i| exists_irq.contains(**i)) else { continue };
|
let Some(new_name) = eq_irqs.iter().find(|i| exists_irq.contains(**i)) else { continue };
|
||||||
name = new_name.to_string();
|
header_name = new_name.to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flags.
|
// Flags.
|
||||||
@ -306,65 +311,57 @@ impl ChipInterrupts {
|
|||||||
if !known.contains(&s.clone()) {
|
if !known.contains(&s.clone()) {
|
||||||
panic!("Unknown signal {s} for peri {p}, known={known:?}, parts={parts:?}");
|
panic!("Unknown signal {s} for peri {p}, known={known:?}, parts={parts:?}");
|
||||||
}
|
}
|
||||||
|
trace!(" signal: {} {}", p, s);
|
||||||
interrupt_signals.insert((p.clone(), s));
|
interrupt_signals.insert((p.clone(), s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (p, s) in interrupt_signals {
|
for (p, s) in interrupt_signals {
|
||||||
let irqs = chip_signals.entry(p).or_default();
|
let signals = chip_signals.entry(p).or_default();
|
||||||
let irq = stm32_data_serde::chip::core::peripheral::Interrupt {
|
let irqs = signals.entry(s).or_default();
|
||||||
signal: s,
|
irqs.insert(header_name.clone());
|
||||||
interrupt: name.clone(),
|
|
||||||
};
|
|
||||||
if !irqs.contains(&irq) {
|
|
||||||
irqs.push(irq);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
for (p, s) in &chip_signals {
|
|
||||||
let mut m: HashMap<&str, Vec<&str>> = HashMap::new();
|
|
||||||
for i in s {
|
|
||||||
m.entry(&i.signal).or_default().push(&i.interrupt);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (signal, irqs) in &mut m {
|
|
||||||
if irqs.len() != 1 {
|
|
||||||
*irqs = irqs.iter().copied().filter(|_| true).collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if irqs.len() != 1 {
|
|
||||||
panic!("dup irqs on file {:?} peri {} signal {}: {:?}", f, p, signal, irqs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
for p in &mut core.peripherals {
|
for p in &mut core.peripherals {
|
||||||
if let Some(peri_irqs) = chip_signals.get(&p.name) {
|
if let Some(signals) = chip_signals.get(&p.name) {
|
||||||
let mut irqs: Vec<_> = peri_irqs.clone();
|
let mut all_irqs: Vec<stm32_data_serde::chip::core::peripheral::Interrupt> = Vec::new();
|
||||||
irqs.sort_by_key(|x| (x.signal.clone(), x.interrupt.clone()));
|
|
||||||
irqs.dedup_by_key(|x| (x.signal.clone(), x.interrupt.clone()));
|
|
||||||
|
|
||||||
/*
|
// remove duplicates
|
||||||
// check there are no duplicate signals.
|
let globals = signals.get("GLOBAL").cloned().unwrap_or_default();
|
||||||
for i in 0..(irqs.len() - 1) {
|
for (signal, irqs) in signals {
|
||||||
if irqs[i].signal == irqs[i + 1].signal {
|
let mut irqs = irqs.clone();
|
||||||
|
|
||||||
|
// If there's a duplicate irqs in a signal other than "global", keep the non-global one.
|
||||||
|
if irqs.len() != 1 && signal != &"GLOBAL" {
|
||||||
|
irqs.retain(|irq| !globals.contains(irq));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's still duplicate irqs, keep the one that doesn't match the peri name.
|
||||||
|
if irqs.len() != 1 && signal != &"GLOBAL" {
|
||||||
|
irqs.retain(|irq| irq != &p.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if irqs.len() != 1 {
|
||||||
panic!(
|
panic!(
|
||||||
"duplicate interrupt on chip {} peripheral {} signal {}: irqs {} and {}",
|
"dup irqs on chip {:?} nvic {:?} peri {} signal {}: {:?}",
|
||||||
chip_name,
|
chip_name, chip_nvic.version, p.name, signal, irqs
|
||||||
p.name,
|
|
||||||
irqs[i].signal,
|
|
||||||
irqs[i].interrupt,
|
|
||||||
irqs[i + 1].interrupt
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
p.interrupts = Some(irqs);
|
for irq in irqs {
|
||||||
|
all_irqs.push(stm32_data_serde::chip::core::peripheral::Interrupt {
|
||||||
|
signal: signal.clone(),
|
||||||
|
interrupt: irq,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
all_irqs.sort_by_key(|x| (x.signal.clone(), x.interrupt.clone()));
|
||||||
|
all_irqs.dedup_by_key(|x| (x.signal.clone(), x.interrupt.clone()));
|
||||||
|
|
||||||
|
p.interrupts = Some(all_irqs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user