krishnax12/tensa-zangetsu-keychain-nfc

Summary: Calculates target inductance and estimated resonance for a 14.5 MHz square antenna using chip, interturn, bridge, and connection capacitances.

Version
0.0.13
License
unset
Stars
1

scripts/check-build.mjs

import assert from "node:assert/strict"
import { readFileSync } from "node:fs"
import { checkAntennaClearance } from "./check-antenna-clearance.mjs"

const circuitJson = JSON.parse(readFileSync("dist/index/circuit.json", "utf8"))
const solverRecords = JSON.parse(readFileSync("dist/solver-debug/index/solver-inputs.json", "utf8"))
const routerTraces = JSON.parse(readFileSync("dist/autorouter-debug/phase-0.output.traces.json", "utf8"))
const source = ["index.tsx", "nfc-circuit.tsx", "square-antenna.ts"].map((path) => readFileSync(path, "utf8")).join("\n")
const routerSummary = JSON.parse(readFileSync("dist/autorouter-debug/board.meta.json", "utf8"))
const solverNames = [...solverRecords.solvers.map((solver) => solver.solver_name), ...routerSummary.phases.map((phase) => phase.solverName)]
assert(routerSummary.phases.every((phase) => phase.errorCount === 0 && phase.outputTraceCount === 2))
for (const solverName of ["LayoutPipelineSolver", "SchematicTracePipelineSolver", "AutoroutingPipelineSolver9_PreloadedTraceGraph"]) {
  assert(solverNames.includes(solverName), `Missing solver: ${solverName}`)
}
for (const manualSetting of ["pcbPath=", "pcbRouteHints=", "pcbRouteCache=", "routeRemaining={false}", "schX=", "schY="]) {
  assert(!source.includes(manualSetting), `Unexpected manual setting: ${manualSetting}`)
}
const errors = circuitJson.filter((element) => element.type.includes("error"))
assert.equal(errors.length, 0, JSON.stringify(errors))
const sourceTraces = circuitJson.filter((element) => element.type === "source_trace")
const pcbPorts = new Map(circuitJson.filter((element) => element.type === "pcb_port").map((port) => [port.pcb_port_id, port]))
assert.equal(sourceTraces.length, 2)
assert.equal(routerTraces.length, 2)
for (const sourceTrace of sourceTraces) {
  const pcbTraces = circuitJson.filter((element) => element.type === "pcb_trace" && element.source_trace_id === sourceTrace.source_trace_id)
  assert.equal(pcbTraces.length, 1)
  const pcbTrace = pcbTraces[0]
  assert(routerTraces.some((trace) => trace.pcb_trace_id === pcbTrace.pcb_trace_id))
  const first = pcbTrace.route[0]
  const last = pcbTrace.route.at(-1)
  const connectedPorts = [pcbPorts.get(first.start_pcb_port_id), pcbPorts.get(last.end_pcb_port_id)]
  assert.deepEqual(connectedPorts.map((port) => port.source_port_id).sort(), [...sourceTrace.connected_source_port_ids].sort())
  for (const [point, port] of [[first, connectedPorts[0]], [last, connectedPorts[1]]]) {
    assert(Math.hypot(point.x - port.x, point.y - port.y) < 1e-5)
    assert(port.layers.includes(point.layer))
  }
  for (const point of pcbTrace.route.filter((point) => point.route_type === "wire")) assert(point.width >= 0.2)
  const schematicTraces = circuitJson.filter((element) => element.type === "schematic_trace" && element.subcircuit_connectivity_map_key === sourceTrace.subcircuit_connectivity_map_key)
  assert.equal(schematicTraces.length, 1)
  assert(schematicTraces[0].edges.length > 0)
}
const sheets = circuitJson.filter((element) => element.type === "schematic_sheet")
assert.equal(sheets.length, 1)
for (const component of circuitJson.filter((element) => element.type === "schematic_component")) assert.equal(component.schematic_sheet_id, sheets[0].schematic_sheet_id)
const coil = circuitJson.find((element) => element.type === "source_component" && element.name === "L1")
const coilFootprint = circuitJson.find((element) => element.type === "pcb_component" && element.source_component_id === coil.source_component_id)
assert.equal(coilFootprint.do_not_place, true)
const paste = circuitJson.filter((element) => element.type === "pcb_solder_paste")
assert.equal(paste.length, 5)
assert(paste.every((pad) => pad.layer === "bottom"))
const antennaClearance = checkAntennaClearance(circuitJson)
console.log(`RF connection to winding clearance: ${antennaClearance.minimum_rf_trace_to_winding_gap_mm.toFixed(3)} mm`)
console.log("Verified: 2 autorouted PCB connections, Matchpack layout, schematic trace solver, no circuit errors.")