Ensure no duplicate irqs with the same signal.

This commit is contained in:
Dario Nieuwenhuis 2023-11-18 00:39:24 +01:00
parent f5a4c58efa
commit 4852f5040a

View File

@ -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);
} }
} }
} }