Record Accepted PCB Placement And Fit
Align component groups, repair affected routing, and add preservation audits. Assign the confirmed U2 footprint and update pull-ups to 2 kΩ across design files. Document user acceptance, switch to an A3 worksheet, and refresh PCB exports.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only PCB checks and fresh KiCad reports; does not regenerate or save PCB.
|
||||
|
||||
Requires KiCad's pcbnew binding in system Python. The known U2 footprint parity
|
||||
warning is reported explicitly, not hidden or added to KiCad's exclusions.
|
||||
Requires KiCad's pcbnew binding in system Python. Schematic footprint parity
|
||||
must be clean, including the user-confirmed U2 reference footprint assignment.
|
||||
"""
|
||||
import hashlib
|
||||
import json
|
||||
@@ -23,6 +23,13 @@ run("kicad-cli","sch","export","netlist","--format","kicadxml","-o",str(OUT/"pcb
|
||||
run("kicad-cli","pcb","drc","--format","json","--all-track-errors","--severity-all","--schematic-parity","-o",str(OUT/"pcb-parity-drc.json"),str(PCB))
|
||||
board=p.LoadBoard(str(PCB))
|
||||
verify(board)
|
||||
from update_presentation import expected_tree, CAPTION
|
||||
from validate_u1_update import parse, canonical
|
||||
tree=parse(PCB)
|
||||
assert ['paper', '"A3"'] in tree, "A3 worksheet required to clear the title block"
|
||||
assert canonical(expected_tree(tree)) == canonical(tree), "Stale presentation labels"
|
||||
assert board.GetTitleBlock().GetComment(0) == ""
|
||||
assert any(isinstance(g,p.PCB_TEXT) and g.GetText()==CAPTION for g in board.GetDrawings())
|
||||
source=ET.parse(OUT/"pcb-source-netlist.xml").getroot()
|
||||
comps={c.get("ref"):c for c in source.findall("components/comp")}
|
||||
footprints={f.GetReference():f for f in board.GetFootprints()}
|
||||
@@ -38,9 +45,9 @@ expected_edges={frozenset((a,b)) for a,b in zip(expected_outline,expected_outlin
|
||||
actual_edges={frozenset((round(p.ToMM(v.x)-100,5),round(p.ToMM(v.y)-100,5))
|
||||
for v in (d.GetStart(),d.GetEnd())) for d in outline}
|
||||
assert actual_edges==expected_edges
|
||||
placements={"U1":(8,23),"U2":(43,26.670),"DS1":(43,36),
|
||||
"R1":(43,34),"R2":(54,34),"R3":(65,34),
|
||||
"SW1":(43,68),"SW2":(55,68),"SW3":(67,68),
|
||||
placements={"U1":(8,23),"U2":(43,26.670),"DS1":(43.97,36),
|
||||
"R1":(42.16,32.6685),"R2":(53.16,32.6685),"R3":(64.16,32.6685),
|
||||
"SW1":(41.72,68),"SW2":(53.72,68),"SW3":(65.72,68),
|
||||
"H1":(3.5,22.5),"H2":(3.5,75),"H3":(78,4),"H4":(78,76)}
|
||||
for ref,(x,y) in placements.items():
|
||||
position=footprints[ref].GetPosition()
|
||||
@@ -72,7 +79,7 @@ for ref,comp in comps.items():
|
||||
assert fp.GetPath().AsString().endswith("/"+comp.findtext("tstamps")),ref
|
||||
wanted=comp.findtext("footprint")
|
||||
if ref=="U2":
|
||||
assert not wanted
|
||||
assert wanted=="Carrier:MAX3243_Reference_Provisional"
|
||||
assert fp.GetFPIDAsString()=="Carrier:MAX3243_Reference_Provisional"
|
||||
else:
|
||||
assert fp.GetFPIDAsString()==wanted,ref
|
||||
@@ -102,8 +109,7 @@ report=json.loads((OUT/"pcb-parity-drc.json").read_text())
|
||||
assert not report["violations"],report["violations"]
|
||||
assert not report["unconnected_items"],report["unconnected_items"]
|
||||
parity=report["schematic_parity"]
|
||||
assert len(parity)==1 and parity[0]["type"]=="footprint_symbol_mismatch",parity
|
||||
assert len(parity[0]["items"])==1 and parity[0]["items"][0]["uuid"]==footprints["U2"].m_Uuid.AsString()
|
||||
assert not parity,parity
|
||||
summary={
|
||||
"carrier_bounds_mm":[82,80],
|
||||
"outline_local_mm":expected_outline,
|
||||
@@ -120,12 +126,14 @@ summary={
|
||||
"physical_DRC_violations":0,
|
||||
"unconnected_items":0,
|
||||
"schematic_pad_nets_match":True,
|
||||
"known_parity_warning":"U2 reference footprint assigned on PCB only; schematic footprint intentionally blank; nominal male external metal dimensions user-confirmed",
|
||||
"schematic_parity_violations":0,
|
||||
"project_settings_sha256":hashlib.sha256((ROOT/'serial-carrier.kicad_pro').read_bytes()).hexdigest(),
|
||||
"ignored_DRC_checks":report["ignored_checks"],
|
||||
"not_validated":["male module pin map/header fit", "ESP32 measured-planar 1:1 fit and complete assembly envelope/heights", "header/socket fit", "RF performance and antenna clearance", "power/return-path integrity", "USB power path", "OLED pull-ups", "fabrication process", "hardware operation"],
|
||||
"user_accepted":["module dimensions/visual fit and USB clearance", "male pinout/header/footprint and pin-by-pin review", "M3 carrier/module and M2 display hardware", "RF keepout and power/ground routing"],
|
||||
"not_independently_verified":["reported 10 mm assembled module elevation", "regulator margin", "USB backfeed safety", "OLED onboard pull-up resistance/rail", "manufacturer RF qualification", "fabrication process/certification"],
|
||||
"new_hardware_tests":False,
|
||||
}
|
||||
(OUT/"pcb-validation-summary.json").write_text(json.dumps(summary,indent=2)+"\n")
|
||||
print("PCB draft verified: 82 x 80 mm; 2 copper layers; 0 physical DRC violations; 0 unrouted.")
|
||||
print("All schematic pad nets match. One expected U2 footprint parity warning remains visible.")
|
||||
print("All schematic pad nets and footprint assignments match. Zero schematic parity violations.")
|
||||
print("Not fabrication-ready; see ../../docs/devel/hardware/PCB/pcb-draft-notes.md and ignored checks in the DRC report.")
|
||||
|
||||
Reference in New Issue
Block a user