imrishabh18/rp2040-motor-controller

An RP2040-based NEMA17 stepper-motor controller with USB-C programming and PD motor-power negotiation, DRV8825 dual H-bridge drive, current/temperature telemetry, protected power filtering, status RGB LED, buzzer alarm, and optional magnetic encoder.

Version
1.0.42
License
unset
Stars
3

scripts/reroute-revision.tsx

import { Circuit } from "tscircuit";
import { AutoroutingPipelineSolver } from "@tscircuit/capacity-autorouter";
import { writeFileSync, mkdirSync } from "node:fs";
import Board from "../index.circuit";
mkdirSync("dist/revision",{recursive:true});
const circuit = new Circuit();
const route = async (input: any) => {
  writeFileSync("dist/revision/routing-input.json", JSON.stringify(input,null,2));
  const handlers = new Map<string,Function>();
  return {
    on(name:string, fn:Function){handlers.set(name,fn)}, stop(){},
    async start(){
      try {
        const solver=new AutoroutingPipelineSolver(input,{effort:2});
        // One simplification pass; all downstream width, DRC and power stages still run.
        const simplify=solver.pipelineDef.find(step=>step.solverName==='traceSimplificationSolver')!;
        const params=simplify.getConstructorParams;
        simplify.getConstructorParams=(state:any)=>{const args=params(state) as any[];args[0].iterations=1;args[0].enableCrossingViaReduction=false;return args as any;};
        const Simplifier=simplify.solverClass as any;
        simplify.solverClass=class extends Simplifier {
          constructor(...args:any[]){super(...args);this.MAX_SIMPLIFICATION_PIPELINE_LOOPS=1;}
          _step(){
            // Bound optional via merging: this library revision can cycle between
            // equivalent via positions. Every downstream DRC/width stage still runs.
            if(this.currentPhase==='via_merging' && this.activeSubSolver?.iterations>=100){
              console.log('Ending optional via merging after 100 iterations');
              this.activeSubSolver.solved=true;
            }
            super._step();
          }
        } as any;
        let last=Date.now(),lastPhase="";
        const started = Date.now();
        while(!solver.solved && !solver.failed){
          if (Date.now()-started > 1_800_000) throw new Error("Routing exceeded thirty minutes");
          const until=Date.now()+100;
          while(Date.now()<until && !solver.solved && !solver.failed) solver.step();
          if(solver.getCurrentPhase()!==lastPhase || Date.now()-last>15000){
            const phase=solver.getCurrentPhase();
            if(phase!==lastPhase && solver.highDensityStitchSolver?.solved) {
              try { writeFileSync(`dist/revision/checkpoint-${phase}.json`,JSON.stringify({expectedInput:input,traces:solver.getPrePowerTraceOutputSimplifiedPcbTraces()},null,2)); } catch(error) { console.log('Checkpoint unavailable:',String(error)); }
            }
            lastPhase=phase;last=Date.now();
            const sub=solver.traceSimplificationSolver;
            console.log(lastPhase,solver.iterations,solver.computeProgress(),sub?{simplificationPhase:sub.currentPhase,loop:sub.simplificationPipelineLoops}:null);
          }
          await Bun.sleep(0);
        }
        if(!solver.solved) throw new Error(String(solver.error));
        const output:any=solver.getOutputSimpleRouteJson();
        const traces=output.traces ?? output;
        // The fabrication stack uses drilled through vias, not blind/buried vias.
        // Preserve the route's wire layers; declare each physical via's full span.
        for(const t of traces) for(const p of t.route ?? []) if(p.route_type==='via'){p.from_layer='top';p.to_layer='bottom';}
        writeFileSync("dist/revision/route-plan.json",JSON.stringify({expectedInput:input,traces},null,2));
        handlers.get("complete")?.({traces});
      } catch(error){console.error(error);process.exit(1)}
    }
  };
};
circuit.add(<Board finalizeGroundPours={false} routingAlgorithm={route as any}/>);
await circuit.renderUntilSettled();
const json=circuit.getCircuitJson();
writeFileSync('dist/revision/circuit.json',JSON.stringify(json,null,2));
const errors = json.filter(x => x.type.endsWith('_error'));
console.log('Errors:', errors);
if (errors.length) process.exitCode = 1;