astra/f1c100s
The code defines the physical pin layout, labels, and footprint for the F1C100S system-on-chip (SoC) component used in electronic devices.
- Version
- 0.9.2
- License
- unset
- Stars
- 0
scripts/check-conventions.ts
import type { CircuitJson } from "circuit-json";
/** Inspect emitted copper, rather than relying on router settings. */
export function checkConventionalRouting(json: CircuitJson): string[] {
const errors: string[] = [];
for (const t of json as any[])
if (t.type === "pcb_trace") {
for (let i = 1; i < t.route.length; i++) {
const a = t.route[i - 1],
b = t.route[i];
// Include wire-to-via approaches as well as wire-to-wire runs.
// A layer change at one via has zero XY length.
const dx = Math.abs(b.x - a.x),
dy = Math.abs(b.y - a.y);
if (Math.min(dx, dy, Math.abs(dx - dy)) > 1e-6)
errors.push(`${t.pcb_trace_id}[${i}]: non-45-degree segment`);
}
}
for (const e of json as any[]) {
if (
(e.type === "pcb_component" || e.type === "pcb_smtpad") &&
e.layer !== "top"
)
errors.push(`${e.type}: component copper is not on top`);
}
const nets = (json as any[]).filter(
(e) => e.type === "source_trace" && /^N_HOSC[IO]$/.test(e.name),
);
for (const net of nets) {
const routes = (json as any[]).filter(
(e) =>
e.type === "pcb_trace" && e.source_trace_id === net.source_trace_id,
);
if (
routes.some((t) =>
t.route.some((p: any) => p.route_type !== "wire" || p.layer !== "top"),
)
)
errors.push(
`${net.name}: crystal signal must remain on top without vias`,
);
for (const t of routes) {
const length = t.route.reduce(
(sum: number, b: any, i: number) =>
i
? sum + Math.hypot(b.x - t.route[i - 1].x, b.y - t.route[i - 1].y)
: sum,
0,
);
if (length > 10) errors.push(`${net.name}: crystal route exceeds 10 mm`);
}
}
return errors;
}