imrishabh18/pcbgolf

A complete 4-layer PCBGolf controller PCB with STM32H7 MCU, USB/SD and CAN interfaces, power regulation, protection, connectors, switches, LEDs, clocking, and supporting passives.

Version
1.6.1
License
unset
Stars
0

footprints/verify.tsx

import { Circuit } from "tscircuit"
import { footprints, footprintPinMaps, type FootprintName } from "./index"
import geometry from "./geometry.json"

const reports = []
for (const name of Object.keys(footprints) as FootprintName[]) {
  const circuit = new Circuit()
  const pinLabels = Object.fromEntries(
    Object.entries(footprintPinMaps[name]).map(([id, pin]) => [pin, `P_${id.replace(/[^A-Za-z0-9_]/g, "_")}`]),
  )
  circuit.add(
    <board width={60} height={60} routingDisabled schematicDisabled>
      <chip name="U1" pcbX={0} pcbY={0} footprint={footprints[name]()} pinLabels={pinLabels} />
    </board>,
  )
  await circuit.renderUntilSettled()
  const json = circuit.getCircuitJson()
  const copper = json.filter((e) => ["pcb_smtpad", "pcb_plated_hole", "pcb_hole"].includes(e.type))
  const expected = geometry[name].pads as Record<string, any>[]
  if (copper.length !== expected.length) throw new Error(`${name}: expected ${expected.length} pads/holes, got ${copper.length}`)
  const almostEqual = (a: number, b: number) => Math.abs(a - b) < 1e-8
  for (const [index, expectedPad] of expected.entries()) {
    const renderedPad = copper[index] as Record<string, any>
    for (const [inputKey, outputKey] of [
      ["pcbX", "x"], ["pcbY", "y"], ["width", "width"],
      ["height", "height"], ["radius", "radius"], ["cornerRadius", "corner_radius"],
      ["ccwRotation", "ccw_rotation"], ["outerDiameter", "outer_diameter"],
      ["holeDiameter", "hole_diameter"], ["rectPadWidth", "rect_pad_width"],
      ["rectPadHeight", "rect_pad_height"],
    ]) {
      if (expectedPad[inputKey] !== undefined && !almostEqual(expectedPad[inputKey], renderedPad[outputKey]))
        throw new Error(`${name} pad ${index + 1}: ${inputKey}=${expectedPad[inputKey]}, rendered ${outputKey}=${renderedPad[outputKey]}`)
    }
  }
  const errors = json.filter((e) => e.type.includes("error"))
  reports.push({ name, pads: copper.length, errors, component: json.find((e) => e.type === "pcb_component"), copper })
  console.log(`${name}: ${copper.length} pads/holes, ${errors.length} diagnostics`)
}
console.log(`Verified all ${reports.length} footprints against source-derived geometry.`)
export const verification = reports