shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.

Version
0.4.56
License
unset
Stars
0

scripts/check-buck-enable.py

"""Check TI's open-EN option in both the netlist and emitted copper."""
from route_geometry import *
import sys,hashlib

def check(c):
    source=next(e for e in c if e['type']=='source_component' and e['name']=='U_BUCK')
    en=next(e for e in c if e['type']=='source_port' and e['source_component_id']==source['source_component_id'] and e['name']=='EN')
    assert en.get('do_not_connect'),'U_BUCK.EN must explicitly use TI internal-pull-up/open-pin enable'
    assert not any(en['source_port_id'] in e.get('connected_source_port_ids',[]) for e in c if e['type']=='source_trace'), 'EN has an unsafe external connection'
    port=next(e for e in c if e['type']=='pcb_port' and e['source_port_id']==en['source_port_id'])
    land=next(e for e in c if e['type']=='pcb_smtpad' and e.get('pcb_port_id')==port['pcb_port_id'])
    pad=geometry(land);clearances=[]
    for e in c:
        if e['type']=='pcb_trace':
            for a,b in zip(e['route'],e['route'][1:]):
                if a['route_type']==b['route_type']=='wire' and a['layer']==b['layer']==land['layer']:
                    if math.dist((a['x'],a['y']),(b['x'],b['y']))>1e-8:
                        clearances.append(pad.distance(LineString([(a['x'],a['y']),(b['x'],b['y'])]).buffer(max(a['width'],b['width'])/2)))
        elif e['type']=='pcb_via' and land['layer'] in e['layers']:
            clearances.append(pad.distance(Point(e['x'],e['y']).buffer(e['outer_diameter']/2)))
        elif e['type']=='pcb_copper_pour' and e['layer']==land['layer']:
            brep=e['brep_shape'];points=lambda ring:[(v['x'],v['y']) for v in ring['vertices']]
            area=Polygon(points(brep['outer_ring']),[points(h) for h in brep.get('inner_rings',[])]).buffer(0)
            clearances.append(pad.distance(area))
    assert clearances and min(clearances)>=.1-2e-4, f'EN pad touches/approaches emitted tracks, drills or pours: {min(clearances)} mm'
    return dict(logicalOpen=True,explicitNoConnect=True,minimumEmittedCopperClearanceMm=min(clearances))

if __name__=='__main__':
    path=Path(sys.argv[1] if len(sys.argv)>1 else 'dist/index/circuit.json')
    report=check(load_circuit(str(path)))
    report.update(circuitSha256=hashlib.sha256(path.read_bytes()).hexdigest(),
        emittedCopperIncludingPours=True,rule='TPS54302 Rev C pages 3/4: float EN to enable; do not tie EN to high-voltage VIN')
    Path('reports/buck-enable-audit.json').write_text(json.dumps(report,indent=2)+'\n')
    print(json.dumps(report))