Skip to content

Commit 9cfcf01

Browse files
committed
update xtask to take into account of per package device ids
1 parent 2d457e2 commit 9cfcf01

2 files changed

Lines changed: 78 additions & 49 deletions

File tree

xtask/src/chip.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
use anyhow::{Context, Result};
22
use serde::Deserialize;
3+
use std::collections::HashSet;
34
use std::path::Path;
45

56
#[derive(Debug, Clone, Deserialize)]
67
pub struct Chip {
78
pub name: String,
9+
#[serde(default)]
10+
pub packages: Vec<Package>,
811
pub memory: Vec<MemoryRegion>,
912
pub cores: Vec<Core>,
1013
#[serde(default)]
1114
pub memory_ram_code_config: Option<RamCodeConfig>,
15+
}
16+
17+
#[derive(Debug, Clone, Deserialize)]
18+
pub struct Package {
19+
pub name: String,
1220
/// chip_id reported by WCH-Link `AttachChip`; drives `chip_detection`.
21+
/// `0` means unknown — emitted by ch32-data when no ID is on record.
1322
#[serde(default)]
14-
pub device_id: Option<u32>,
23+
pub device_id: u32,
1524
}
1625

1726
#[derive(Debug, Clone, Deserialize)]
@@ -204,5 +213,19 @@ pub fn load_all(dir: &Path) -> Result<Vec<Chip>> {
204213
out.push(chip);
205214
}
206215
out.sort_by(|a, b| a.name.cmp(&b.name));
216+
217+
// Drop per-package JSONs that duplicate a container chip's package entry.
218+
// Container = any chip whose `packages` doesn't reduce to a single self-named
219+
// entry (multi-package, or a single package with a different name).
220+
let owned_by_container: HashSet<String> = out
221+
.iter()
222+
.filter(|c| c.packages.len() > 1 || c.packages.iter().any(|p| p.name != c.name))
223+
.flat_map(|c| c.packages.iter().map(|p| p.name.clone()))
224+
.collect();
225+
out.retain(|c| {
226+
let self_named_single = c.packages.len() == 1 && c.packages[0].name == c.name;
227+
!(self_named_single && owned_by_container.contains(&c.name))
228+
});
229+
207230
Ok(out)
208231
}

xtask/src/render.rs

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -148,54 +148,60 @@ fn build_family(
148148
.as_ref()
149149
.map(|c| c.default.clone());
150150

151-
let refinement = build_ob_refinement(chip);
152-
153-
for variant in chip.variants() {
154-
let is_default_variant = match (&variant.option, &default_opt) {
155-
(Some(opt), Some(def)) => opt == def,
156-
_ => true,
157-
};
158-
let suffix = if is_default_variant {
159-
String::new()
160-
} else {
161-
format!("_{}", variant.option.as_deref().unwrap_or(""))
162-
};
163-
let target_name = format!("{}{}", chip.name, suffix);
164-
165-
let (memory_map, variant_algo_names) = build_variant(
166-
&variant,
167-
&core_name,
168-
silicon,
169-
arch,
170-
algos,
171-
&mut variant_algo_uses,
172-
&mut algo_kind,
173-
);
174-
175-
// Non-default splits share the same chip_id; OB refinement maps
176-
// OB.USER bits 5-7 to the right variant post-attach.
177-
if is_default_variant && let Some(id) = chip.device_id {
178-
let mask = mask_for(id);
179-
let group = detection_entries.entry(mask).or_default();
180-
group.variants.insert(id & mask, target_name.clone());
181-
if let Some(r) = &refinement {
182-
group.ob_refinement.insert(id & mask, r.clone());
151+
for package in &chip.packages {
152+
let refinement = build_ob_refinement(chip, &package.name);
153+
154+
for variant in chip.variants() {
155+
let is_default_variant = match (&variant.option, &default_opt) {
156+
(Some(opt), Some(def)) => opt == def,
157+
_ => true,
158+
};
159+
let suffix = if is_default_variant {
160+
String::new()
161+
} else {
162+
format!("_{}", variant.option.as_deref().unwrap_or(""))
163+
};
164+
let target_name = format!("{}{}", package.name, suffix);
165+
166+
let (memory_map, variant_algo_names) = build_variant(
167+
&variant,
168+
&core_name,
169+
silicon,
170+
arch,
171+
algos,
172+
&mut variant_algo_uses,
173+
&mut algo_kind,
174+
);
175+
176+
// Non-default splits share the same chip_id; OB refinement maps
177+
// OB.USER bits 5-7 to the right variant post-attach. device_id=0
178+
// is ch32-data's "unknown" sentinel — drop those so multiple
179+
// unknown-ID packages don't collide on key 0x0 in the variants
180+
// IndexMap (last-write-wins would otherwise hide all but one).
181+
if is_default_variant && package.device_id != 0 {
182+
let id = package.device_id;
183+
let mask = mask_for(id);
184+
let group = detection_entries.entry(mask).or_default();
185+
group.variants.insert(id & mask, target_name.clone());
186+
if let Some(r) = &refinement {
187+
group.ob_refinement.insert(id & mask, r.clone());
188+
}
183189
}
184-
}
185190

186-
variants.push(PrChip {
187-
name: target_name,
188-
part: None,
189-
svd: None,
190-
documentation: Default::default(),
191-
package_variants: vec![],
192-
cores: vec![core.clone()],
193-
memory_map,
194-
flash_algorithms: variant_algo_names,
195-
rtt_scan_ranges: None,
196-
jtag: None,
197-
default_binary_format: None,
198-
});
191+
variants.push(PrChip {
192+
name: target_name,
193+
part: None,
194+
svd: None,
195+
documentation: Default::default(),
196+
package_variants: vec![],
197+
cores: vec![core.clone()],
198+
memory_map,
199+
flash_algorithms: variant_algo_names,
200+
rtt_scan_ranges: None,
201+
jtag: None,
202+
default_binary_format: None,
203+
});
204+
}
199205
}
200206
}
201207

@@ -406,7 +412,7 @@ struct DetectionGroup {
406412
const OB_USER_ADDRESS: u64 = 0x1FFFF802;
407413
const RAM_CODE_MASK: u8 = 0xE0;
408414

409-
fn build_ob_refinement(chip: &Chip) -> Option<ObRefinement> {
415+
fn build_ob_refinement(chip: &Chip, package_name: &str) -> Option<ObRefinement> {
410416
let cfg = chip.memory_ram_code_config.as_ref()?;
411417
let ob_version = chip.ob_version()?;
412418
let encoding = ram_code_encoding(ob_version)?;
@@ -420,7 +426,7 @@ fn build_ob_refinement(chip: &Chip) -> Option<ObRefinement> {
420426
} else {
421427
format!("_{}", option_name)
422428
};
423-
let variant_name = format!("{}{}", chip.name, suffix);
429+
let variant_name = format!("{}{}", package_name, suffix);
424430
variants.insert(raw << 5, variant_name);
425431
}
426432

0 commit comments

Comments
 (0)