ShiboSoftwareDev/am625sip-linux-board
This code defines the physical footprint and pin layout for an AM625 System-in-Package (SIP) component, detailing pad positions, pin labels, and package outline for hardware integration.
- Version
- 1.0.24
- License
- unset
- Stars
- 0
scripts/build-microsd-cache.tsx
import { mkdirSync, writeFileSync } from "node:fs"
import { Circuit } from "@tscircuit/core"
import type { AnyCircuitElement } from "circuit-json"
import { MicroSdBlock } from "../subcircuits/microsd"
import { namespaceCachePcbTraceIds } from "./namespace-cache-pcb-trace-ids"
const CACHE_PATH = "subcircuits/cache/microsd.circuit.json"
const INTERNAL_TRACE_COUNT = 20
const LinkPad = ({ name, pcbY }: { name: string; pcbY: number }) => (
<chip
name={name}
pcbX={-16}
pcbY={pcbY}
noSchematicRepresentation
footprint={
<footprint>
<smtpad
portHints={["pin1"]}
shape="rect"
width="0.8mm"
height="0.8mm"
/>
</footprint>
}
/>
)
const getErrors = (circuitJson: AnyCircuitElement[]) =>
circuitJson.filter(
(element) =>
element.type.endsWith("_error") || element.type === "pcb_placement_error",
)
const main = async () => {
const sourceCircuit = new Circuit()
sourceCircuit.on("autorouting:start", (event: any) => {
console.log(
`source autorouting start: ${event.phaseName ?? "unphased"} (${event.simpleRouteJson.connections.length} connections)`,
)
})
sourceCircuit.on("autorouting:end", (event: any) => {
console.log(`source autorouting end: ${event.phaseName ?? "unphased"}`)
})
sourceCircuit.add(
<board
width="34mm"
height="34mm"
layers={4}
defaultTraceWidth="0.08128mm"
minTraceWidth="0.08128mm"
minTraceToPadEdgeClearance="0.05mm"
minPadEdgeToPadEdgeClearance="0.08128mm"
minViaEdgeToPadEdgeClearance="0.08128mm"
minViaHoleEdgeToViaHoleEdgeClearance="0.1016mm"
minViaHoleDiameter="0.1mm"
minViaPadDiameter="0.24mm"
pcbStyle={{
viaHoleDiameter: "0.1mm",
viaPadDiameter: "0.24mm",
}}
autorouter="default"
>
<MicroSdBlock />
</board>,
)
await sourceCircuit.renderUntilSettled()
const sourceJson = sourceCircuit.getCircuitJson()
const sourceErrors = getErrors(sourceJson)
const sourceTraceCount = sourceJson.filter(
(element) => element.type === "pcb_trace",
).length
const cacheJson = namespaceCachePcbTraceIds(sourceJson.filter((element) => {
const type = element.type
return (
(!type.startsWith("schematic_") || type === "schematic_component") &&
!type.startsWith("cad_") &&
!type.endsWith("_warning") &&
type !== "pcb_debug_object" &&
type !== "source_project_metadata"
)
}), "microsd")
if (sourceErrors.length > 0 || sourceTraceCount !== INTERNAL_TRACE_COUNT) {
writeFileSync(
"/private/tmp/microsd-source-cache-failure.circuit.json",
JSON.stringify(sourceJson),
)
console.error(
JSON.stringify(
{
error: "microSD source-cache validation failed",
sourceTraceCount,
sourceErrors,
},
null,
2,
),
)
process.exitCode = 1
return
}
if (process.argv.includes("--source-only")) {
mkdirSync("subcircuits/cache", { recursive: true })
writeFileSync(CACHE_PATH, `${JSON.stringify(cacheJson, null, 2)}\n`)
console.log(
JSON.stringify(
{
cachePath: CACHE_PATH,
sourceTraceCount,
sourceElementCount: sourceJson.length,
cacheElementCount: cacheJson.length,
validation: "source-only",
},
null,
2,
),
)
return
}
const parentCircuit = new Circuit()
let parentAutoroutingConnectionCount = 0
parentCircuit.on("autorouting:start", (event: any) => {
parentAutoroutingConnectionCount += event.simpleRouteJson.connections.length
console.log(
`parent autorouting start: ${event.phaseName ?? "unphased"} (${event.simpleRouteJson.connections.length} connections)`,
)
})
parentCircuit.on("autorouting:end", (event: any) => {
console.log(`parent autorouting end: ${event.phaseName ?? "unphased"}`)
})
parentCircuit.add(
<board
width="44mm"
height="36mm"
layers={4}
autorouter="default"
schematicDisabled
minTraceWidth="0.08128mm"
minTraceToPadEdgeClearance="0.05mm"
minPadEdgeToPadEdgeClearance="0.08128mm"
minViaEdgeToPadEdgeClearance="0.08128mm"
minViaHoleEdgeToViaHoleEdgeClearance="0.1016mm"
minViaHoleDiameter="0.1mm"
minViaPadDiameter="0.24mm"
>
<subcircuit
name="MICROSD"
circuitJson={cacheJson}
pcbX={0}
pcbY={0}
schTraceAutoLabelEnabled
/>
<LinkPad name="L_CMD" pcbY={9} />
<LinkPad name="L_DAT0" pcbY={7} />
<LinkPad name="L_CLK" pcbY={5} />
<LinkPad name="L_VDD" pcbY={11.5} />
<LinkPad name="L_GND" pcbY={-11} />
<trace from=".L_CMD > .pin1" to=".MICROSD .X_SOC_CMD > .pin1" />
<trace from=".L_DAT0 > .pin1" to=".MICROSD .X_SOC_DAT0 > .pin1" />
<trace from=".L_CLK > .pin1" to=".MICROSD .X_SOC_CLK > .pin1" />
<trace from=".L_VDD > .pin1" to=".MICROSD .X_VDD > .pin1" />
<trace from=".L_GND > .pin1" to=".MICROSD .X_GND > .pin1" />
</board>,
)
await parentCircuit.renderUntilSettled()
const parentJson = parentCircuit.getCircuitJson()
const parentErrors = getErrors(parentJson)
const parentTraceCount = parentJson.filter(
(element) => element.type === "pcb_trace",
).length
const importedCenters = ["J1", "X_CMD", "X_DAT0", "X_CLK", "X_SOC_CMD", "X_SOC_DAT0", "X_SOC_CLK", "X_VDD", "X_GND"].map(
(name) => {
const sourceComponent = parentJson.find(
(element) => element.type === "source_component" && element.name === name,
)
const pcbComponent = parentJson.find(
(element) =>
element.type === "pcb_component" &&
sourceComponent?.type === "source_component" &&
element.source_component_id === sourceComponent.source_component_id,
)
return {
name,
center: pcbComponent?.type === "pcb_component" ? pcbComponent.center : null,
}
},
)
if (
parentErrors.length > 0 ||
parentTraceCount !== INTERNAL_TRACE_COUNT + 5 ||
parentAutoroutingConnectionCount !== 5
) {
console.error(
JSON.stringify(
{
error: "microSD imported-cache validation failed",
parentTraceCount,
parentAutoroutingConnectionCount,
importedCenters,
parentErrors,
},
null,
2,
),
)
process.exitCode = 1
return
}
mkdirSync("subcircuits/cache", { recursive: true })
writeFileSync(CACHE_PATH, `${JSON.stringify(cacheJson, null, 2)}\n`)
console.log(
JSON.stringify(
{
cachePath: CACHE_PATH,
sourceTraceCount,
parentLinkTraceCount: 5,
parentAutoroutingConnectionCount,
importedCenters,
sourceElementCount: sourceJson.length,
cacheElementCount: cacheJson.length,
},
null,
2,
),
)
}
main().catch((error) => {
console.error(error)
process.exitCode = 1
})