muse/book-reading-clip-lamp

A 60‑mm ESP32‑S3 lamp-head PCB combining USB‑C battery charging/power regulation, OV5640 autofocus camera interfacing, I²S microphone and differential speaker audio, six‑LED boost-driven reading light, buttons, status indicators, and battery monitoring.

Version
0.2.5
License
unset
Stars
0

fresh-routing.ts

SchematicSchematic preview for fresh-routing.ts
import { AutoroutingPipelineSolver9_PreloadedTraceGraph, type SimpleRouteJson, type SimplifiedPcbTrace } from "@tscircuit/capacity-autorouter"

/** Fresh routing for this dense, two-sided board. Keep the normal topology,
 * detailed routing, repair, width expansion and final core DRC. Only omit
 * optional trace/via simplification, whose search takes excessive time here.
 * The detailed routed paths and vias remain; no clearance rule or DRC is disabled.
 * Saved copper is still guarded by saved-routing.ts on ordinary builds.
 */
export async function routeFreshBoard(input:SimpleRouteJson) {
 const solver = new AutoroutingPipelineSolver9_PreloadedTraceGraph(input)
 for (const step of solver.pipelineDef) {
  if (!["traceSimplificationSolver","mutatedPreloadedTraceSimplificationSolver"].includes(step.solverName)) continue
  // The public pipeline stage class has a heterogeneous constructor union.
  // Adapt only this identified stage; all other stages stay unchanged.
  const Base = step.solverClass as any
  step.solverClass = class ConservativeSimplification extends Base {
   constructor(config:Record<string,unknown>) {
    super({...config, iterations:0, enableCrossingViaReduction:false})
    this.MAX_SIMPLIFICATION_PIPELINE_LOOPS = 0
   }
  } as any
 }
 type Event = {type:string;traces?:SimplifiedPcbTrace[];error?:unknown;message?:string}
 const listeners = new Map<string,Array<(event:Event)=>void>>()
 let stopped=false
 let previousPhase=""
 const emit=(name:string,event:Event)=>listeners.get(name)?.forEach(fn=>fn(event))
 return {
  on(name:string,callback:(event:Event)=>void) {listeners.set(name,[...(listeners.get(name)??[]),callback])},
  start() {
   const tick=()=>{
    if((globalThis as unknown as {process?:{env?:Record<string,string>}}).process?.env?.LAMP_CAPTURE_INPUT === "1"){emit("complete",{type:"complete",traces:[]});return}
    if(stopped)return
    try {
     const phase=solver.getCurrentPhase()
     if(phase!==previousPhase){console.info(`[lamp routing] ${phase}`);previousPhase=phase}
     const until=Date.now()+30
     do {solver.step()} while(!solver.solved&&!solver.failed&&Date.now()<until)
     if(solver.failed){emit("error",{type:"error",error:solver.error,message:String(solver.error)});return}
     if(solver.solved){emit("complete",{type:"complete",traces:solver.getOutputSimplifiedPcbTraces()});return}
     setTimeout(tick,0)
    }catch(error){emit("error",{type:"error",error,message:String(error)})}
   }
   tick()
  },
  stop(){stopped=true},
 }
}