Skip to content

Commit

Permalink
can: fix missing interrupts
Browse files Browse the repository at this point in the history
  • Loading branch information
xoviat committed Jun 18, 2023
1 parent d52fe49 commit e388dce
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 53 deletions.
2 changes: 2 additions & 0 deletions .vscode/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
launch.json
tasks.json
37 changes: 32 additions & 5 deletions stm32-data-gen/src/chips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -935,13 +935,40 @@ fn process_core(
}

if let Some(peri_irqs) = chip_irqs.get(&pname) {
use stm32_data_serde::chip::core::peripheral::Interrupt;

//filter by available, because some are conditioned on <Die>
let mut irqs: Vec<_> = peri_irqs
.iter()
.filter(|i| header_irqs.contains_key(&i.interrupt))
.cloned()
.collect();

let mut irqs: Vec<_> =
if pname == "CAN" && (chip_name.starts_with("STM32F358") || chip_name.starts_with("STM32F398")) {
/*
This section is needed because the interrupt definition file does not apply uniformly to
all chips that it covers in this specific case. This cannot be done in interrupt.rs
because there, it's only possible to modify the interrupt definition file in a uniform manner.
*/

peri_irqs
.iter()
.map(|i| Interrupt {
interrupt: i
.interrupt
.trim_start_matches("USB_LP_")
.trim_start_matches("USB_HP_")
.to_owned(),
signal: i.signal.clone(),
})
.filter(|i| header_irqs.contains_key(&i.interrupt))
.collect()
} else {
peri_irqs
.iter()
.filter(|i| header_irqs.contains_key(&i.interrupt))
.cloned()
.collect()
};
irqs.sort_by_key(|x| (x.signal.clone(), x.interrupt.clone()));
irqs.dedup_by_key(|x| (x.signal.clone(), x.interrupt.clone()));

p.interrupts = Some(irqs);
}
peripherals.push(p);
Expand Down
70 changes: 22 additions & 48 deletions stm32-data-gen/src/interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mod xml {

#[derive(Debug)]
pub struct ChipInterrupts(
// (chip name, chip version), (signal name, [interrupt])
pub HashMap<(String, String), HashMap<String, Vec<stm32_data_serde::chip::core::peripheral::Interrupt>>>,
);

Expand All @@ -51,9 +52,10 @@ impl ChipInterrupts {

for f in files {
trace!("parsing {f:?}");
let mut irqs = HashMap::<String, _>::new();
let file = std::fs::read_to_string(f)?;
let file = std::fs::read_to_string(&f)?;
let parsed: xml::Ip = quick_xml::de::from_str(&file)?;
let mut chip_signals = HashMap::<_, Vec<_>>::new();

for irq in parsed
.ref_parameters
.into_iter()
Expand All @@ -79,11 +81,6 @@ impl ChipInterrupts {
// More typos
let name = name.replace("USAR11", "USART11");

let entry = match irqs.entry(name.to_string()) {
std::collections::hash_map::Entry::Occupied(_) => continue,
std::collections::hash_map::Entry::Vacant(entry) => entry,
};

// Flags.
// Y
// unknown, it's in all of them
Expand Down Expand Up @@ -113,7 +110,7 @@ impl ChipInterrupts {
continue;
}

let mut signals = HashSet::<(String, String)>::new();
let mut interrupt_signals = HashSet::<(String, String)>::new();
if [
"NonMaskableInt",
"HardFault",
Expand Down Expand Up @@ -147,27 +144,27 @@ impl ChipInterrupts {
ch_from..=ch_to
};
for ch in range {
signals.insert((dma.to_string(), format!("CH{ch}")));
interrupt_signals.insert((dma.to_string(), format!("CH{ch}")));
}
}
assert!(dmas_iter.next().is_none());
assert!(chans_iter.next().is_none());
} else if name == "DMAMUX1" || name == "DMAMUX1_S" || name == "DMAMUX_OVR" || name == "DMAMUX1_OVR" {
signals.insert(("DMAMUX1".to_string(), "OVR".to_string()));
interrupt_signals.insert(("DMAMUX1".to_string(), "OVR".to_string()));
} else if name == "DMAMUX2_OVR" {
signals.insert(("DMAMUX2".to_string(), "OVR".to_string()));
interrupt_signals.insert(("DMAMUX2".to_string(), "OVR".to_string()));
} else if flags.contains(&"DMAMUX") {
panic!("should've been handled above");
} else if flags.contains(&"EXTI") {
for signal in parts[2].split(',') {
signals.insert(("EXTI".to_string(), signal.to_string()));
interrupt_signals.insert(("EXTI".to_string(), signal.to_string()));
}
} else if name == "FLASH" {
signals.insert(("FLASH".to_string(), "GLOBAL".to_string()));
interrupt_signals.insert(("FLASH".to_string(), "GLOBAL".to_string()));
} else if name == "CRS" {
signals.insert(("RCC".to_string(), "CRS".to_string()));
interrupt_signals.insert(("RCC".to_string(), "CRS".to_string()));
} else if name == "RCC" {
signals.insert(("RCC".to_string(), "GLOBAL".to_string()));
interrupt_signals.insert(("RCC".to_string(), "GLOBAL".to_string()));
} else {
if parts[2].is_empty() {
continue;
Expand All @@ -193,7 +190,7 @@ impl ChipInterrupts {
curr_peris = peri_names.clone();
}

// Parse IRQ signals from the IRQ name.
// Parse IRQ interrupt_signals from the IRQ name.
for part in tokenize_name(name2) {
let part = {
if part == "TAMPER" {
Expand All @@ -204,13 +201,13 @@ impl ChipInterrupts {
};

if part == "LSECSS" {
signals.insert(("RCC".to_string(), "LSECSS".to_string()));
interrupt_signals.insert(("RCC".to_string(), "LSECSS".to_string()));
} else if part == "CSS" {
signals.insert(("RCC".to_string(), "CSS".to_string()));
interrupt_signals.insert(("RCC".to_string(), "CSS".to_string()));
} else if part == "LSE" {
signals.insert(("RCC".to_string(), "LSE".to_string()));
interrupt_signals.insert(("RCC".to_string(), "LSE".to_string()));
} else if part == "CRS" {
signals.insert(("RCC".to_string(), "CRS".to_string()));
interrupt_signals.insert(("RCC".to_string(), "CRS".to_string()));
} else {
let pp = match_peris(&peri_names, &part);
trace!(" part={part}, pp={pp:?}");
Expand All @@ -228,7 +225,7 @@ impl ChipInterrupts {
for (p, mut ss) in peri_signals.into_iter() {
let known = valid_signals(&p);

// If we have no signals for the peri, assume it's "global" so assign it all known ones
// If we have no interrupt_signals for the peri, assume it's "global" so assign it all known ones
if ss.is_empty() {
if p.starts_with("COMP") {
ss = vec!["WKUP".to_string()];
Expand All @@ -241,22 +238,14 @@ impl ChipInterrupts {
if !known.contains(&s.clone()) {
panic!("Unknown signal {s} for peri {p}, known={known:?}, parts={parts:?}");
}
signals.insert((p.clone(), s));
interrupt_signals.insert((p.clone(), s));
}
}
}

// for (peri, signal) in &signals {
// println!(" {peri}:{signal}");
// }
entry.insert(signals);
}

let mut irqs2 = HashMap::<_, Vec<_>>::new();
for (name, signals) in irqs {
for (p, s) in signals {
for (p, s) in interrupt_signals {
let key = if p == "USB_DRD_FS" { "USB".to_string() } else { p };
irqs2
chip_signals
.entry(key)
.or_default()
.push(stm32_data_serde::chip::core::peripheral::Interrupt {
Expand All @@ -266,22 +255,7 @@ impl ChipInterrupts {
}
}

for pirqs in irqs2.values_mut() {
let mut psirqs = HashMap::<_, Vec<_>>::new();
for irq in pirqs {
psirqs
.entry(irq.signal.clone())
.or_default()
.push(irq.interrupt.clone());
}
// for (s, irqs) in psirqs {
// if irqs.len() != 1 {
// println!("DUPE: {p} {s} {irqs:?}");
// }
// }
}

chip_interrupts.insert((parsed.name, parsed.version), irqs2);
chip_interrupts.insert((parsed.name, parsed.version), chip_signals);
}

Ok(Self(chip_interrupts))
Expand Down

0 comments on commit e388dce

Please sign in to comment.