seveibar/am3352-dev-board

A 324-ball TI AM3352 ARM processor with DDR3, LCD, USB, Ethernet, storage, serial, analog, clock, reset, power, and JTAG interfaces, paired with configurable JST-GH board connectors and constrained PCB routing.

Version
1.0.2
License
unset
Stars
0

scripts/copper-to-dsn.py

import json,sys,re
from pathlib import Path
# Keep the parser independent of the command-line resume helper.
source=Path('scripts/resume-router.py').read_text().split('board=parse(')[0];exec(source)
board=parse(Path(sys.argv[1]).read_text());data=json.loads(Path('design/routed-copper.json').read_text());c=json.loads(Path('dist/index/circuit.json').read_text())
names={p['source_net_id']:p['name'] for p in c if p['type']=='source_net'}
for k in data['nets']:
 if k not in names:
  t=next(t for t in c if t['type']=='source_trace' and t['source_trace_id']==k);names[k]='N_'+t['connected_source_port_ids'][-1]
# Direct LED net has the exporter union-root name; locate by actual endpoint.
placements={value(p[1]):(float(p[2])/1000,float(p[3])/1000) for p in walk(board,'place')}
for k in data['nets']:
 if k.startswith('source_trace'):
  xy=data['endpoints'][k][0];pin=next(n+'-1' for n,p in placements.items() if abs(p[0]-xy[0])<.002 and abs(p[1]-xy[1])<.002)
  names[k]=next(value(n[1]) for n in walk(child(board,'network'),'net') if pin in child(n,'pins'))
filledSites=json.loads(Path('design/plane-escape-report.json').read_text()) if Path('design/plane-escape-report.json').exists() else []
wiring=['wiring'];u=lambda x:str(round(x*1000,5));vias=set()
for k,routes in data['nets'].items():
 name=names[k]
 for r in routes:
  via=next((p for p in r if p['route_type']=='via'),None)
  if via:
   key=(round(via['x'],5),round(via['y'],5),name)
   if key in vias:continue
   vias.add(key);thermal=name=='GND' and abs(via['x']+23)<2 and abs(via['y']+3)<2
   filled=any(site.get('requiresFillAndCap') and abs(site['x']-via['x'])<.001 and abs(site['y']-via['y'])<.001 for site in filledSites)
   item=['via','VIA_THERMAL_400_200' if thermal else ('VIA_POWER_FILLED_300_150' if filled else ('VIA_300_150' if via.get('via_diameter',.4)<.35 else 'VIA_400_200')),u(via['x']),u(via['y'])]
  else:
   if len(r)<2:continue
   item=['wire',['path',r[0]['layer'],u(r[0]['width'])]+[u(p[a]) for p in r for a in ['x','y']]]
  item += [['net',json.dumps(name)],['type','protect' if name in ['GND','DDR_1V5','VDD_CORE','VDD_MPU','V1V8','V3V3','A3V3','SW2','PWRONRSTn'] or (name.startswith('DDR_') and (via or r[0]['layer']=='top')) else 'route']];wiring.append(item)
board=[x for x in board if not isinstance(x,list) or x[0]!='wiring']+[wiring]
Path(sys.argv[2]).write_text(emit(board)+'\n');print('Saved',len(wiring)-1,'copper records')