tools/epro2/kicad: fix two --all crashes found running the other 4 Pro projects
Running the new --all on the remaining 4 Pro projects (X86 motherboard, 220V power supply, Taishan Pi, Liangshan Pi) surfaced two crash modes not covered by ESP-VoCat: 1. Odd inner-layer count → KiCad rejects the file at load with "3 is not a valid layer count". The 220V power boards have one used inner SIGNAL layer (3 copper total: F.Cu / In1.Cu / B.Cu), but KiCad requires an even copper count. Fixed pcb_writer to pad with one empty inner layer when the inner count is odd, so the total stays even (2, 4, 6, ...). 2. Two BOARDs sharing the same META.title — twin "显示板" boards in the 220V power project — landed in the same project directory and the second silently overwrote the first's .kicad_sch / .kicad_pcb / .kicad_pro. Fixed --all to detect title collisions and suffix every colliding basename with the BOARD uuid prefix (so both '显示板' boards become '显示板_52e8cc76' and '显示板_55d32906' rather than one quietly winning). 71 → 73 unit tests pass (test_odd_inner_signal_count_padded_to_even_total + test_duplicate_board_titles_get_distinct_basenames). Tangentially noted while running this: Taishan Pi and Liangshan Pi are Pro 2.x JSON, not EPRO2 streams — our replay layer reads the files but doesn't decode docType, so SCH/PCB grouping returns nothing. Pro 2.x needs a separate writer; out of scope for this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,26 @@ def test_writer_emits_header_and_layers():
|
||||
assert "Edge.Cuts" in by_name
|
||||
|
||||
|
||||
def test_odd_inner_signal_count_padded_to_even_total():
|
||||
"""KiCad rejects odd copper layer counts ('3 is not a valid layer
|
||||
count'). A board with one used inner SIGNAL layer must therefore
|
||||
declare two — the second is empty padding, but without it the
|
||||
loader refuses to open the file at all."""
|
||||
d = _pcb([
|
||||
('["LAYER",1]', {"_type": "LAYER", "layerType": "TOP", "use": True}),
|
||||
('["LAYER",2]', {"_type": "LAYER", "layerType": "BOTTOM", "use": True}),
|
||||
('["LAYER",15]', {"_type": "LAYER", "layerType": "SIGNAL", "use": True}),
|
||||
("ln1", {"_type": "LINE", "layerId": 15,
|
||||
"startX": 0, "startY": 0, "endX": 100, "endY": 0, "width": 6}),
|
||||
])
|
||||
text = write_pcb(d, project_relations=_empty_pr(d))
|
||||
p = parse(text)
|
||||
rows = [r for r in _block(p, "layers")[0][1:] if isinstance(r, list)]
|
||||
cu_layers = [r[1] for r in rows if r[1].endswith(".Cu")]
|
||||
# 4 copper total: F.Cu, In1.Cu (used), In2.Cu (padding), B.Cu
|
||||
assert cu_layers == ["F.Cu", "In1.Cu", "In2.Cu", "B.Cu"]
|
||||
|
||||
|
||||
def test_inner_signal_layers_inserted_in_id_order():
|
||||
"""An EPRO2 4-layer board with SIGNAL ids 15 and 16 actually used must
|
||||
map to In1.Cu and In2.Cu (in EPRO2-id sorted order) so the PCB
|
||||
|
||||
Reference in New Issue
Block a user