seveibar/am3352-dev-board-4layer-dogbone
Defines PCB footprints and pin mappings for a TI AM3352ZCZ100 processor, JST GH connectors, and assembly-part lookup helpers for capacitors, resistors, and headers.
- Version
- 0.1.5
- License
- unset
- Stars
- 0
scripts/test-no-via-in-pad.py
"""Check both faces and annular copper, including same-net pad contacts."""
import json, os, subprocess, sys, tempfile
from pathlib import Path
base=[dict(type='pcb_board',num_layers=4),dict(type='source_net',source_net_id='net',name='TEST'),dict(type='source_trace',source_trace_id='trace',connected_source_net_ids=['net'],connected_source_port_ids=['source_port']),dict(type='pcb_port',pcb_port_id='port',source_port_id='source_port')]
with tempfile.TemporaryDirectory() as tmp:
inp=Path(tmp)/'circuit.json';out=Path(tmp)/'pads.json'
def check(layer,x,expected,standalone=True):
pad=dict(type='pcb_smtpad',pcb_smtpad_id='pad',pcb_port_id='port',shape='rect',x=0,y=0,width=.4,height=.4,layer=layer)
via=dict(route_type='via',x=x,y=0,from_layer='top',to_layer='bottom',via_diameter=.3,via_hole_diameter=.15)
c=base+[pad,dict(type='pcb_trace',pcb_trace_id='copper',source_trace_id='trace',route=[via])]
if standalone:c.append(dict(type='pcb_via',pcb_via_id='via',x=x,y=0,outer_diameter=.3,hole_diameter=.15))
inp.write_text(json.dumps(c));r=subprocess.run([sys.executable,'scripts/check-no-via-in-pad.py','--strict'],env={**os.environ,'AUDIT_CIRCUIT':str(inp),'AUDIT_REPORT_PATH':str(Path(tmp)/'copper.json'),'PAD_AUDIT_REPORT':str(out)},capture_output=True,text=True)
assert (r.returncode==0)==expected,(layer,x,r.stdout,r.stderr)
report=json.loads(out.read_text());assert report['viaCount']==1
assert bool(report['violations'])==(not expected)
for layer in ['top','bottom']:
check(layer,0,False) # same-net drill inside pad
check(layer,.3,False) # drill clears pad, annulus still overlaps
check(layer,.4,False) # annulus clears pad but misses required gap
check(layer,.46,True) # full 0.1 mm gap
check(layer,.3,False,False) # route-only checkpoint also checked
print('No-via-in-pad regressions passed: both faces, same-net contacts, annulus and spacing, route-only inputs')