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/via-manifest.py
"""List filled/capped via requirements from the final rendered copper geometry."""
import csv, json, runpy
from pathlib import Path
from shapely.geometry import Point
x=runpy.run_path('scripts/audit-copper.py');c=x['c']
byid={e[e['type']+'_id']:e for e in c if e['type']+'_id' in e}
reserved=[] # Regenerated four-layer routing: do not use the parent's reserved sites.
pads=[p for p in c if p['type']=='pcb_smtpad'];rows=[];seen=set()
for v in c:
if v['type']!='pcb_via':continue
xy=(round(v['x'],6),round(v['y'],6))
if xy in seen:continue
seen.add(xy)
hole=Point(*xy).buffer(v['hole_diameter']/2)
hits=[p for p in pads if hole.intersection(x['padshape'](p)).area>1e-8]
explicit=any(r.get('requiresFillAndCap') and abs(r['x']-xy[0])<.002 and abs(r['y']-xy[1])<.002 for r in reserved)
if not hits and not explicit:continue
refs=[];nets=set()
for p in hits:
port=x['ports'].get(p.get('pcb_port_id'))
if not port:continue
sp=byid[port['source_port_id']];sc=byid[sp['source_component_id']]
refs.append(sc['name']+'.'+sp['name']);net=x['find'](sp['source_port_id']);nets.add(x['netnames'].get(net,net))
if not nets:
nets.update(r['net'] for r in reserved if abs(r['x']-xy[0])<.002 and abs(r['y']-xy[1])<.002)
rows.append(dict(xMm=xy[0],yMm=xy[1],drillMm=v['hole_diameter'],padMm=v['outer_diameter'],net='; '.join(sorted(nets)),componentPads='; '.join(sorted(set(refs))),process='Filled and copper capped through via'))
rows.sort(key=lambda r:(r['net'],r['xMm'],r['yMm']))
Path('design/filled-vias.json').write_text(json.dumps({'coordinateOrigin':'PCB center, millimetres, native tscircuit coordinates','requirement':'Fabricator must review and apply fill and copper cap to these vias before assembly. This manifest accompanies the design; no fabrication release is implied.','vias':rows},indent=2)+'\n')
with open('design/filled-vias.csv','w',newline='') as f:
writer=csv.DictWriter(f,fieldnames=['xMm','yMm','drillMm','padMm','net','componentPads','process']);writer.writeheader();writer.writerows(rows)
print('Filled/capped via manifest:',len(rows),'unique vias')