Lookup memory details by die instead of by chip name

This commit is contained in:
Rasmus Melchior Jacobsen 2023-03-29 09:44:23 +02:00
parent 8019b4f48f
commit a7503de2dc
2 changed files with 32 additions and 167 deletions

View File

@ -984,9 +984,9 @@ fn process_chip(
) -> Result<(), anyhow::Error> { ) -> Result<(), anyhow::Error> {
let chip = chips.get(chip_name).unwrap(); let chip = chips.get(chip_name).unwrap();
let flash_size = chip.flash * 1024; let flash_size = chip.flash * 1024;
let mut flash_remaining = flash_size;
let flash_regions = memories.determine_flash_regions(chip_name, flash_size);
let ram_total = chip.ram * 1024; let ram_total = chip.ram * 1024;
let memory = memories.get(group.die.as_ref().unwrap());
let mut flash_remaining = flash_size;
let mut memory_regions = Vec::new(); let mut memory_regions = Vec::new();
let mut found = HashSet::<&str>::new(); let mut found = HashSet::<&str>::new();
for each in [ for each in [
@ -1022,7 +1022,8 @@ fn process_chip(
memory::FlashBank::Bank2 => "BANK_2", memory::FlashBank::Bank2 => "BANK_2",
memory::FlashBank::Otp => "OTP", memory::FlashBank::Otp => "OTP",
}; };
let regions: Vec<_> = flash_regions let regions: Vec<_> = memory
.flash_regions
.iter() .iter()
.filter(|region| region.bank == *bank) .filter(|region| region.bank == *bank)
.enumerate() .enumerate()
@ -1097,8 +1098,16 @@ fn process_chip(
found.insert(key); found.insert(key);
let size = if key == "SRAM" { let size = if key == "SRAM" {
let size = memories.determine_ram_size(chip_name, flash_size); // if memory.ram.bytes != ram_total {
std::cmp::min(size, ram_total) // println!(
// "SRAM mismatch for chip {} with die {}: Expected {} was {}",
// chip_name,
// group.die.as_ref().unwrap(),
// ram_total,
// memory.ram.bytes,
// );
// }
std::cmp::min(memory.ram.bytes, ram_total)
} else { } else {
0 0
}; };
@ -1113,13 +1122,12 @@ fn process_chip(
} }
} }
let docs = docs.documents_for(chip_name); let docs = docs.documents_for(chip_name);
let device_id = memories.determine_device_id(chip_name, flash_size);
let chip = stm32_data_serde::Chip { let chip = stm32_data_serde::Chip {
name: chip_name.to_string(), name: chip_name.to_string(),
family: group.family.clone().unwrap(), family: group.family.clone().unwrap(),
line: group.line.clone().unwrap(), line: group.line.clone().unwrap(),
die: group.die.clone().unwrap(), die: group.die.clone().unwrap(),
device_id, device_id: memory.device_id,
packages: chip.packages.clone(), packages: chip.packages.clone(),
memory: memory_regions, memory: memory_regions,
docs, docs,

View File

@ -1,16 +1,15 @@
use std::{cmp::Ordering, fs}; use std::{cmp::Ordering, collections::HashMap, fs};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
struct Memory { pub struct Memory {
pub device_id: u16, pub device_id: u16,
pub names: Vec<String>,
pub ram: Ram, pub ram: Ram,
pub flash_size: u32, pub flash_size: u32,
pub flash_regions: Vec<FlashRegion>, pub flash_regions: Vec<FlashRegion>,
} }
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
struct Ram { pub struct Ram {
pub address: u32, pub address: u32,
pub bytes: u32, pub bytes: u32,
} }
@ -30,50 +29,6 @@ pub enum FlashBank {
Otp, Otp,
} }
fn splat_names(base: &str, parts: Vec<&str>) -> Vec<String> {
let mut names = Vec::new();
for part in parts {
if part.starts_with("STM32") {
names.push(base.to_string());
} else if part.starts_with(&base[5..6]) {
names.push("STM32".to_string() + part);
} else {
let diff = base.len() - part.len();
names.push((base[..diff]).to_string() + part);
}
}
names
}
fn split_names(str: &str) -> Vec<String> {
let mut cleaned = Vec::new();
let mut current_base = None;
for name in str.split('/') {
let name = name.split(' ').next().unwrap().trim();
if name.contains('-') {
let parts: Vec<_> = name.split('-').collect();
current_base = parts.first().map(ToString::to_string);
let splatted = splat_names(&current_base.unwrap(), parts);
current_base = splatted.first().map(Clone::clone);
cleaned.extend(splatted);
} else if name.starts_with("STM32") {
current_base = Some(name.to_string());
cleaned.push(name.to_string())
} else if name.starts_with(&current_base.clone().unwrap()[5..6]) {
// names.append('STM32' + name)
cleaned.push("STM32".to_string() + name);
} else {
cleaned.push(
(current_base.clone().unwrap()[0..(current_base.clone().unwrap().len() - name.len())]).to_string()
+ name,
)
}
}
cleaned
}
mod xml { mod xml {
use serde::Deserialize; use serde::Deserialize;
@ -203,7 +158,7 @@ mod xml {
} }
} }
} }
pub struct Memories(Vec<Memory>); pub struct Memories(HashMap<u16, Memory>);
impl Memories { impl Memories {
pub fn parse() -> anyhow::Result<Self> { pub fn parse() -> anyhow::Result<Self> {
@ -213,7 +168,7 @@ impl Memories {
.collect(); .collect();
paths.sort(); paths.sort();
let mut memories = Vec::new(); let mut memories = HashMap::new();
for f in paths { for f in paths {
// println!("Parsing {f:?}"); // println!("Parsing {f:?}");
@ -222,7 +177,6 @@ impl Memories {
// dbg!(&parsed); // dbg!(&parsed);
let device_id = parsed.device.device_id; let device_id = parsed.device.device_id;
let names = split_names(&parsed.device.name);
let mut ram = None; let mut ram = None;
let mut flash_size = None; let mut flash_size = None;
@ -309,121 +263,24 @@ impl Memories {
} }
} }
memories.push(Memory { memories.insert(
device_id,
Memory {
device_id, device_id,
names,
ram: ram.unwrap(), ram: ram.unwrap(),
flash_size: flash_size.unwrap_or_default(), flash_size: flash_size.unwrap_or_default(),
flash_regions, flash_regions,
}); },
);
} }
// The chips below are missing from cubeprogdb
memories.push(Memory {
device_id: 0,
names: vec!["STM32F302xD".to_string()],
ram: Ram {
address: 0x20000000,
bytes: 64 * 1024,
},
flash_size: 384 * 1024,
flash_regions: vec![FlashRegion {
bank: FlashBank::Bank1,
address: 0x08000000,
bytes: 384 * 1024,
settings: stm32_data_serde::chip::memory::Settings {
erase_value: 0xFF,
write_size: 8,
erase_size: 2048,
},
}],
});
memories.push(Memory {
device_id: 0,
names: vec!["STM32F303xD".to_string()],
ram: Ram {
address: 0x20000000,
bytes: 80 * 1024,
},
flash_size: 384 * 1024,
flash_regions: vec![FlashRegion {
bank: FlashBank::Bank1,
address: 0x08000000,
bytes: 384 * 1024,
settings: stm32_data_serde::chip::memory::Settings {
erase_value: 0xFF,
write_size: 8,
erase_size: 2048,
},
}],
});
memories.push(Memory {
device_id: 0,
names: vec!["STM32L100x6".to_string()],
ram: Ram {
address: 0x20000000,
bytes: 4 * 1024,
},
flash_size: 32 * 1024,
flash_regions: vec![FlashRegion {
bank: FlashBank::Bank1,
address: 0x08000000,
bytes: 32 * 1024,
settings: stm32_data_serde::chip::memory::Settings {
erase_size: 256,
write_size: 4,
erase_value: 0xFF,
},
}],
});
// Sort memories by flash size in descending order so that when we look
// a chip up later by name, the it will find the one with the largest flash size.
memories.sort_by(|a, b| b.flash_size.cmp(&a.flash_size));
Ok(Self(memories)) Ok(Self(memories))
} }
fn lookup_chip(&self, chip_name: &str, flash_size: u32) -> &Memory { pub fn get(&self, die: &str) -> &Memory {
// We use here that the memories are sorted in descending order by flash size. assert!(die.starts_with("DIE"));
// We emit the memory for which which the regions include at least the flash size of the requested chip. let device_id = u16::from_str_radix(&die[3..], 16).unwrap();
for each in &self.0 {
if each.flash_size >= flash_size {
for name in &each.names {
if is_chip_name_match(name, chip_name) {
return each;
}
}
}
}
panic!("could not find memory information for {chip_name} with flash size {flash_size}"); self.0.get(&device_id).unwrap()
}
pub fn determine_ram_size(&self, chip_name: &str, flash_size: u32) -> u32 {
self.lookup_chip(chip_name, flash_size).ram.bytes
}
pub fn determine_flash_regions(&self, chip_name: &str, flash_size: u32) -> &[FlashRegion] {
self.lookup_chip(chip_name, flash_size).flash_regions.as_slice()
}
pub fn determine_device_id(&self, chip_name: &str, flash_size: u32) -> u16 {
self.lookup_chip(chip_name, flash_size).device_id
} }
} }
fn is_chip_name_match(pattern: &str, chip_name: &str) -> bool {
let mut chip_name = chip_name.replace("STM32F479", "STM32F469"); // F479 is missing, it's the same as F469.
chip_name = chip_name.replace("STM32G050", "STM32G051"); // same...
chip_name = chip_name.replace("STM32G060", "STM32G061"); // same...
chip_name = chip_name.replace("STM32G070", "STM32G071"); // same...
chip_name = chip_name.replace("STM32G0B0", "STM32G0B1"); // same...
chip_name = chip_name.replace("STM32G4A", "STM32G49"); // same...
chip_name = chip_name.replace("STM32L422", "STM32L412"); // same...
chip_name = chip_name.replace("STM32WB30", "STM32WB35"); // same...
let pattern = pattern.replace('x', ".");
regex::Regex::new(&pattern).unwrap().is_match(&chip_name)
}