astra/f1c100s

This code defines and renders a four-layer, top-mounted F1C100S module with detailed pin assignments, schematic annotations, and layout profiles, facilitating design, validation, and routing of the hardware including support for decoupling capacitors, crystal oscillators, and external connectors.

Version
0.11.0
License
unset
Stars
0

scripts/verify-site.ts

import { checkPreviewPours } from "./check-preview-pours";
import { checkCapacitorOrientation } from "./check-capacitor-orientation";
import { checkPlatedExits } from "./check-plated-exits";
import { checkConventionalRouting } from "./check-conventions";
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg";
import { Resvg } from "@resvg/resvg-js";
import { LAYOUT_PROFILES } from "../src/profiles";
import { validateCircuit } from "./validate";
for (const profile of ["index", ...LAYOUT_PROFILES]) {
	const json = await Bun.file(`dist/${profile}/circuit.json`).json();
	const errors = [
		...json.filter(
			(e: any) =>
				e.type.endsWith("_error") ||
				e.type === "schematic_element_outside_sheet_warning",
		),
		...(await validateCircuit(json)),
		...checkConventionalRouting(json),
		...checkCapacitorOrientation(json),
		...checkPlatedExits(json),
		...checkPreviewPours(json),
	];
	const capacitors = json.filter(
		(e: any) => e.type === "source_component" && e.ftype === "simple_capacitor",
	);
	if (
		capacitors.length !== 32 ||
		capacitors.some(
			(c: any) =>
				!json.some(
					(e: any) =>
						e.type === "pcb_component" &&
						e.source_component_id === c.source_component_id &&
						e.layer === "top",
				),
		)
	)
		throw Error(`${profile}: all 32 capacitors must be on top`);
	const sheets = json.filter((e: any) => e.type === "schematic_sheet");
	const traces = json.filter((e: any) => e.type === "pcb_trace");
	const vias = json.filter((e: any) => e.type === "pcb_via");
	const uniqueVias = new Set(
		vias.map((v: any) => `${v.x.toFixed(6)}:${v.y.toFixed(6)}`),
	);
	if (
		errors.length ||
		sheets.length !== 2 ||
		uniqueVias.size !== vias.length ||
		traces.length !== 176 ||
		traces.some((t: any) => !t.pcb_trace_id.startsWith("saved_fanout_"))
	)
		throw Error(
			`${profile}: invalid site circuit ${JSON.stringify(errors.slice(0, 3))}`,
		);
	if (profile !== "index") {
		const svg = convertCircuitJsonToPcbSvg(json, { width: 1400, height: 1400 });
		await Bun.write(`previews/${profile}.svg`, svg);
		const png = new Resvg(svg).render().asPng();
		await Bun.write(`previews/${profile}.png`, png);
		if (profile === "lcd_top_storage_right")
			await Bun.write("previews/pcb.png", png);
	}
	console.log(
		`${profile}: native saved paths, ${vias.length} unique vias, 2 sheets, 0 DRC errors`,
	);
}
const html = await Bun.file("dist/index.html").text();
for (const alias of [
	"fanout-profiles",
	"schematic-preview",
	"schematic-sections",
	"compact-schematic",
	"smooth-traces",
	"top-capacitors",
	"conventional-routing",
	"plated-exits",
	"oriented-capacitors",
	"copper-pours",
])
	await Bun.write(`dist/${alias}.html`, html);