shibosoftwaredev/f1c100s-linux-nema17-stepper-controller
Compact four-layer NEMA 17 carrier PCB combining an F1C100S Linux SoC, USB-C PD power and buck regulation, W5500 10/100 Ethernet, STM32 safety/motion control, and DRV8825 stepper-driver hardware with protection, sensing, connectors, and dual-sided SMT assembly.
- Version
- 0.4.15
- License
- unset
- Stars
- 0
nema17-fixed-router.ts
import savedRoutes from "./nema17-route-pool.json"
import { writeFileSync } from "node:fs"
/**
* Deterministic fabrication router for the 42.3 mm NEMA17 carrier.
*
* The routes were generated with fanout-aware capacity-router passes and are
* checked into the package so local and tscircuit.com builds do not rerun a
* several-minute dense-board search. Final DRC and shorts checks still inspect
* every emitted segment and via.
*/
export async function nema17FixedRouter(input: any) {
if (process.env.TSCI_CAPTURE_ROUTER_INPUT)
writeFileSync(process.env.TSCI_CAPTURE_ROUTER_INPUT, `${JSON.stringify(input, null, 2)}\n`)
const handlers: Record<string, Array<(event: any) => void>> = {
complete: [], error: [], progress: [],
}
let isRouting = false
// The input traces are the F1C100S module's already-emitted child copper.
// They are routing obstacles, not parent routes to return again. Returning
// them here would duplicate the module fanout in the parent subcircuit.
const requestedNames = new Set((process.env.TSCI_ROUTE_NAMES ?? "").split(",").filter(Boolean))
const selectedRoutes = process.env.TSCI_EMPTY_CARRIER_ROUTER
? []
: process.env.TSCI_ROUTE_NAMES !== undefined
? (savedRoutes as any[]).filter((trace) => requestedNames.has(trace.connection_name))
: savedRoutes as any[]
const currentPortLocations = new Map<string, { x: number; y: number }>()
for (const connection of input.connections ?? [])
for (const point of connection.pointsToConnect ?? [])
if (point.pcb_port_id)
currentPortLocations.set(point.pcb_port_id, { x: point.x, y: point.y })
const traces = selectedRoutes.map((trace, index) => ({
...trace,
pcb_trace_id: `nema17_route_${index}`,
route: trace.route.map((point: any) => {
if (point.route_type === "via") return {
...point,
via_diameter: 0.45,
via_hole_diameter: 0.3,
}
const portId = point.start_pcb_port_id ?? point.end_pcb_port_id
const current = portId ? currentPortLocations.get(portId) : undefined
return current ? { ...point, x: current.x, y: current.y } : point
}),
}))
return {
input,
get isRouting() { return isRouting },
on(event: string, handler: (event: any) => void) {
handlers[event]?.push(handler)
},
start() {
isRouting = true
queueMicrotask(() => {
if (!isRouting) return
isRouting = false
for (const handler of handlers.complete)
handler({ type: "complete", traces })
})
},
stop() { isRouting = false },
solveSync() { return traces },
}
}