mohan-bee/fitness-band

A 4-layer BLE wearable mainboard with Li-ion charging/protection, 3.3/1.8 V power regulation, motion and battery sensing, plus a folded 2-layer flex sensor board carrying MAX30102 optical and TMP117 temperature sensors.

Version
0.0.2
License
unset
Stars
0

scripts/extract-main-routing.py

import json, hashlib
from pathlib import Path
import pcbnew as k
root=Path(__file__).resolve().parents[1]
release=root/'manufacturing/rev-b'
pcb=release/'main/main.kicad_pcb'
assert hashlib.sha256(pcb.read_bytes()).hexdigest()==json.loads((release/'release-manifest.json').read_text())['main']['native_sha256']
b=k.LoadBoard(str(pcb))
layers={k.F_Cu:'top',k.In1_Cu:'inner1',k.In2_Cu:'inner2',k.B_Cu:'bottom'}
routes=[]
for track in b.GetTracks():
    net=track.GetNetname()
    assert net
    if isinstance(track,k.PCB_VIA):
        p=track.GetPosition()
        assert track.GetWidth(k.F_Cu)==450000 and track.GetDrillValue()==200000
        route=[{'route_type':'via','x':p.x/1e6-100,'y':100-p.y/1e6,'from_layer':'top','to_layer':'bottom'}]
    else:
        assert track.GetClass()=='PCB_TRACK'
        route=[{'route_type':'wire','x':p.x/1e6-100,'y':100-p.y/1e6,'width':track.GetWidth()/1e6,'layer':layers[track.GetLayer()]} for p in (track.GetStart(),track.GetEnd())]
    routes.append({'net':net,'route':route})
vias={(r['net'],round(r['route'][0]['x'],6),round(r['route'][0]['y'],6)):r['route'][0] for r in routes if r['route'][0]['route_type']=='via'}
for r in routes:
    if len(r['route'])!=2:continue
    start,end=r['route']
    for point,is_start in [(start,True),(end,False)]:
        v=vias.get((r['net'],round(point['x'],6),round(point['y'],6)))
        if v:
            if is_start:r['route'].insert(0,dict(v))
            else:r['route'].append(dict(v))
elements=json.loads((release/'source-snapshots/main.circuit.json').read_text())
components={e['source_component_id']:e['name'] for e in elements if e['type']=='source_component'}
ports={e['source_port_id']:e for e in elements if e['type']=='source_port'}
native={(fp.GetReference(),pad.GetNumber()):pad for fp in b.GetFootprints() for pad in fp.Pads()}
expected={}
for e in elements:
    if e['type']!='pcb_port':continue
    source=ports[e['source_port_id']]
    if source['source_component_id'] not in components:continue
    pad=native[(components[source['source_component_id']],str(source['pin_number']))]
    p=pad.GetPosition()
    assert abs(p.x/1e6-100-e['x'])<.01 and abs(100-p.y/1e6-e['y'])<.01
    expected[e['pcb_port_id']]={'x':e['x'],'y':e['y'],'net':pad.GetNetname()}
folder=root/'routing';folder.mkdir(exist_ok=True)
(folder/'main-native-routes.json').write_text(json.dumps(routes,indent=2)+'\n')
(folder/'main-native-ports.json').write_text(json.dumps(expected,indent=2)+'\n')
print(len(routes),'native track/via primitives exported')