AnasSarkiz/usb-c-pd-brushed-motor
USB-C PD-powered motor controller with protected input, selectable 5/9/12 V buck supply, MCU qualification, PWM H-bridge drive, overvoltage sensing, regenerative energy-dump resistors, and safety interlocks.
- Version
- 0.0.1-a48-cloud-pipeline9-unrouted-c41d79a-305b1e7a
- License
- unset
- Stars
- 0
scripts/audit-spdt-imports.ts
import { readFile, writeFile } from "node:fs/promises"
import {
any_circuit_element,
pcb_solder_paste,
type AnyCircuitElement,
} from "circuit-json"
import { z } from "zod"
const failures: string[] = []
const circuitJson: AnyCircuitElement[] = []
const rawElements = z
.array(z.unknown())
.parse(
JSON.parse(
await readFile("dist/tests/spdt-import-probe/circuit.json", "utf8"),
),
)
for (const [elementIndex, rawElement] of rawElements.entries()) {
const result = any_circuit_element.safeParse(rawElement)
if (result.success) {
circuitJson.push(result.data)
continue
}
const header = z.object({ type: z.string() }).safeParse(rawElement)
const elementType = header.success ? header.data.type : "unknown"
const specific =
elementType === "pcb_solder_paste"
? pcb_solder_paste.safeParse(rawElement)
: result
failures.push(
`Element ${elementIndex} ${elementType}: ${
specific.success
? "element union mismatch"
: specific.error.issues
.map((issue) => `${issue.path.join(".")}: ${issue.message}`)
.join("; ")
}`,
)
}
const pinReports = []
for (const componentName of ["SW_DEFAULT", "SW_SPDT"]) {
const component = circuitJson.find(
(element) =>
element.type === "source_component" && element.name === componentName,
)
if (!component || component.type !== "source_component") {
failures.push(`${componentName}: source component missing`)
continue
}
const sourcePorts = circuitJson.filter(
(element) =>
element.type === "source_port" &&
element.source_component_id === component.source_component_id,
)
if (sourcePorts.length !== 3)
failures.push(`${componentName}: expected exactly three source ports`)
for (const pinNumber of [1, 2, 3]) {
const sourcePort = sourcePorts.find(
(element) =>
element.type === "source_port" && element.pin_number === pinNumber,
)
if (!sourcePort || sourcePort.type !== "source_port") {
failures.push(`${componentName} pin${pinNumber}: source port missing`)
continue
}
const schematicPort = circuitJson.find(
(element) =>
element.type === "schematic_port" &&
element.source_port_id === sourcePort.source_port_id,
)
const pcbPort = circuitJson.find(
(element) =>
element.type === "pcb_port" &&
element.source_port_id === sourcePort.source_port_id,
)
const pad =
pcbPort?.type === "pcb_port"
? circuitJson.find(
(element) =>
element.type === "pcb_plated_hole" &&
element.pcb_port_id === pcbPort.pcb_port_id,
)
: undefined
if (!schematicPort)
failures.push(`${componentName} pin${pinNumber}: schematic port missing`)
if (!pad)
failures.push(`${componentName} pin${pinNumber}: footprint pad missing`)
// This native right-facing SPDT symbol has its moving contact on the left.
// The manufacturer specifies physical pin 2 as common; no remapping is made.
if (
componentName === "SW_SPDT" &&
pinNumber === 2 &&
schematicPort?.type === "schematic_port" &&
schematicPort.facing_direction !== "left"
) {
failures.push(
`${componentName}: physical common pin 2 is drawn as a throw; native common is pin 1`,
)
}
if (
pad?.type === "pcb_plated_hole" &&
pinNumber === 1 &&
"hole_width" in pad &&
"hole_height" in pad &&
typeof pad.hole_width === "number" &&
typeof pad.hole_height === "number" &&
Math.max(pad.hole_width, pad.hole_height) < 1.27
) {
failures.push(
`${componentName} pin1: hole ${pad.hole_width} × ${pad.hole_height} mm cannot fit nominal 1.27 mm-wide terminal`,
)
}
pinReports.push({
componentName,
pinNumber,
sourcePort,
schematicPort,
pcbPort,
pad,
})
}
}
const pcbTraceCount = circuitJson.filter(
(element) => element.type === "pcb_trace",
).length
if (pcbTraceCount !== 0)
failures.push("Import probe unexpectedly contains routing")
const report = {
revision: "A3 C221539 exact-footprint import probe",
supplierCode: "C221539",
approved: failures.length === 0,
failures,
pcbTraceCount,
pinReports,
manufacturerReference: "https://www.ckswitches.com/media/1429/1000.pdf",
manufacturerCommonPin: 2,
manufacturerStates: ["1–2", "open", "2–3"],
manufacturerBodyMm: [12.7, 6.6],
manufacturerPitchMm: 4.7,
manufacturerRecommendedRoundDrillMm: 1.85,
mechanicalMountingFeatures:
"M2 has no mounting tabs; all three plated pads are electrical",
}
await writeFile(
"evidence/spdt-pin-pad-check-A3.json",
`${JSON.stringify(report, null, 2)}\n`,
)
console.log(JSON.stringify({ ...report, pinReports: undefined }, null, 2))
if (failures.length > 0) process.exitCode = 1