diff --git a/src/fn/index.ts b/src/fn/index.ts index 94c0370e..68b274d0 100644 --- a/src/fn/index.ts +++ b/src/fn/index.ts @@ -81,3 +81,4 @@ export { sot343 } from "./sot343" export { m2host } from "./m2host" export { mountedpcbmodule } from "./mountedpcbmodule" export { to92l } from "./to92l" +export { spdip } from "./spdip" diff --git a/src/fn/spdip.ts b/src/fn/spdip.ts new file mode 100644 index 00000000..750f0110 --- /dev/null +++ b/src/fn/spdip.ts @@ -0,0 +1,16 @@ +import type { AnyCircuitElement } from "circuit-json" +import { dip, extendDipDef } from "./dip" + +export const spdip_def = extendDipDef({ w: "300mil", p: "1.778mm" }) + +export const spdip = ( + raw_params: any, +): { circuitJson: AnyCircuitElement[]; parameters: any } => { + const parameters = spdip_def.parse(raw_params) + // Standard SDIP/SPDIP packages have smaller pad sizes to prevent overlap. + if (raw_params.id === undefined && raw_params.od === undefined) { + parameters.id = 0.7 + parameters.od = 1.3 + } + return dip({ ...parameters, dip: true } as any) +} diff --git a/src/footprinter.ts b/src/footprinter.ts index fa51a3b4..835d01ff 100644 --- a/src/footprinter.ts +++ b/src/footprinter.ts @@ -40,6 +40,12 @@ export type Footprinter = { dip: ( num_pins?: number, ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> + pdip: ( + num_pins?: number, + ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> + spdip: ( + num_pins?: number, + ) => FootprinterParamsBuilder<"w" | "p" | "id" | "od" | "wide" | "narrow"> cap: () => FootprinterParamsBuilder res: () => FootprinterParamsBuilder diode: () => FootprinterParamsBuilder diff --git a/tests/__snapshots__/spdip28.snap.svg b/tests/__snapshots__/spdip28.snap.svg new file mode 100644 index 00000000..a72ab018 --- /dev/null +++ b/tests/__snapshots__/spdip28.snap.svg @@ -0,0 +1 @@ +{REF}{pin1}{pin2}{pin3}{pin4}{pin5}{pin6}{pin7}{pin8}{pin9}{pin10}{pin11}{pin12}{pin13}{pin14}{pin15}{pin16}{pin17}{pin18}{pin19}{pin20}{pin21}{pin22}{pin23}{pin24}{pin25}{pin26}{pin27}{pin28} \ No newline at end of file diff --git a/tests/spdip.test.ts b/tests/spdip.test.ts new file mode 100644 index 00000000..08c9386f --- /dev/null +++ b/tests/spdip.test.ts @@ -0,0 +1,34 @@ +import { expect, test } from "bun:test" +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" +import { fp } from "../src/footprinter" + +test("spdip28", () => { + const circuitJson = fp.string("spdip28").circuitJson() + + // Exclude silkscreen path and courtyard to find only plated holes + const holes = circuitJson.filter((e: any) => e.type === "pcb_plated_hole") + expect(holes.length).toBe(28) + + // Verify that row spacing is 300mil (7.62mm) + // Pin 1 (left row) and Pin 28 (right row) should have x-distance of 7.62mm + const pin1 = holes.find((h: any) => h.port_hints?.includes("1")) + const pin28 = holes.find((h: any) => h.port_hints?.includes("28")) + expect(pin1).toBeDefined() + expect(pin28).toBeDefined() + expect(Math.abs(pin28.x - pin1.x)).toBeCloseTo(7.62, 3) + + // Verify that pin pitch is 1.778mm + // Pin 1 and Pin 2 (adjacent pins on same side) should have y-distance of 1.778mm + const pin2 = holes.find((h: any) => h.port_hints?.includes("2")) + expect(pin2).toBeDefined() + expect(Math.abs(pin2.y - pin1.y)).toBeCloseTo(1.778, 3) + + const svgContent = convertCircuitJsonToPcbSvg(circuitJson) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "spdip28") +}) + +test("spdip (default 6 pins)", () => { + const circuitJson = fp.string("spdip").circuitJson() + const holes = circuitJson.filter((e: any) => e.type === "pcb_plated_hole") + expect(holes.length).toBe(6) +})