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

routing/main-routing.ts

import { pcb_trace } from "circuit-json"
import type { AutorouterConfig } from "@tscircuit/props"
import nativeRoutes from "./main-native-routes.json"
import nativePorts from "./main-native-ports.json"
import reference from "./main-reference-input.json"

function canonical(input: unknown): string {
  if (typeof input === "number") return String(Math.round(input*1e6)/1e6)
  if (Array.isArray(input)) return `[${input.map(canonical).join(",")}]`
  if (input && typeof input === "object") return `{${Object.entries(input).filter(([,v])=>v!==undefined).sort(([a],[b])=>a.localeCompare(b)).map(([k,v])=>`${JSON.stringify(k)}:${canonical(v)}`).join(",")}}`
  return JSON.stringify(input)
}

// Replay the DRC-checked native copper; reject changed pads or connectivity.
export const mainRouting: NonNullable<AutorouterConfig["algorithmFn"]> = async input => {
  if (canonical(input)!==canonical(reference)) throw new Error("Native routing geometry or connectivity changed; reroute and validate before publishing")
  const connectionByNet = new Map<string, string>()
  const expectedPorts = new Map(Object.entries(nativePorts))
  for (const connection of input.connections) {
    let net: string | undefined
    for (const point of connection.pointsToConnect) {
      const expected = expectedPorts.get(point.pcb_port_id)
      if (!expected || Math.hypot(expected.x-point.x, expected.y-point.y)>0.001)
        throw new Error(`Native routing no longer matches port ${point.pcb_port_id}`)
      if (net !== undefined && net !== expected.net) throw new Error("Native routing connectivity changed")
      net = expected.net
    }
    if (!net || connectionByNet.has(net)) throw new Error("Native routing requires one connection per native net")
    connectionByNet.set(net, connection.name)
  }
  const traces = nativeRoutes.map((track, index) => {
    const sourceTraceId = connectionByNet.get(track.net)
    if (!sourceTraceId) throw new Error(`Native net ${track.net} is absent from source`)
    return {...pcb_trace.parse({type:"pcb_trace", pcb_trace_id:`native_main_${index}`, source_trace_id:sourceTraceId, route:track.route}), connection_name:sourceTraceId}
  })
  const listeners = new Map<string, (event: unknown) => void>()
  let stopped = false
  return {
    on(event: string, callback: (event: unknown) => void) { listeners.set(event, callback) },
    start() { queueMicrotask(() => { if (!stopped) listeners.get("complete")?.({traces}) }) },
    stop() { stopped = true },
  }
}