-
Notifications
You must be signed in to change notification settings - Fork 63
feat: add SPDIP and UTDFN footprints #570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { dip } from "./dip" | ||
| import { z } from "zod" | ||
|
|
||
| const SPDIP_PITCH = 1.778 // mm (shrink pitch: 0.070") | ||
| const SPDIP_WIDTH = 7.62 // mm (narrow body: 0.3") | ||
|
|
||
| export const spdip = ( | ||
| raw_params: { fn?: string; num_pins?: number; p?: number; w?: number; string?: string; [key: string]: any }, | ||
| ): ReturnType<typeof dip> => { | ||
| // Extract num_pins from string if not provided | ||
| const numPinsFromString = typeof raw_params.string === "string" | ||
| ? Number.parseInt(raw_params.string.match(/^spdip(\d+)/)?.[1] ?? "") | ||
| : NaN | ||
|
|
||
| const num_pins = raw_params.num_pins ?? (Number.isNaN(numPinsFromString) ? 28 : numPinsFromString) | ||
| const p = raw_params.p ?? SPDIP_PITCH | ||
| const w = raw_params.w ?? SPDIP_WIDTH | ||
|
|
||
| return dip({ ...raw_params, num_pins, p, w }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import { dfn } from "./dfn" | ||
|
|
||
| const UTDFN4_W = 1.0 // mm | ||
| const UTDFN4_H = 0.6 // mm | ||
| const UTDFN4_P = 0.5 // mm pitch | ||
| const UTDFN4_THERMALPAD_X = 0.6 // mm | ||
| const UTDFN4_THERMALPAD_Y = 0.4 // mm | ||
|
|
||
| export const utdfn = ( | ||
| raw_params: { fn?: string; num_pins?: number; w?: number; h?: number; p?: number; thermalpad?: { x?: number; y?: number }; string?: string; [key: string]: any }, | ||
| ): ReturnType<typeof dfn> => { | ||
| // Extract num_pins from string if not provided | ||
| const numPinsFromString = typeof raw_params.string === "string" | ||
| ? Number.parseInt(raw_params.string.match(/^utdfn(\d+)/)?.[1] ?? "") | ||
| : NaN | ||
| const num_pins = raw_params.num_pins ?? (Number.isNaN(numPinsFromString) ? 4 : numPinsFromString) | ||
|
|
||
| // Build params object - only include optional params if explicitly set | ||
| const params: any = { fn: "utdfn", num_pins } | ||
| if (raw_params.w !== undefined) params.w = raw_params.w | ||
| if (raw_params.h !== undefined) params.h = raw_params.h | ||
| if (raw_params.p !== undefined) params.p = raw_params.p | ||
| if (raw_params.thermalpad !== undefined) params.thermalpad = raw_params.thermalpad | ||
| if (raw_params.num_pins !== undefined) params.num_pins = raw_params.num_pins | ||
|
|
||
| // Apply UTDFN-4-EP(1x1) defaults | ||
| if (raw_params.w === undefined) params.w = UTDFN4_W | ||
| if (raw_params.h === undefined) params.h = UTDFN4_H | ||
| if (raw_params.p === undefined) params.p = UTDFN4_P | ||
| if (raw_params.thermalpad === undefined) { | ||
| params.thermalpad = { x: UTDFN4_THERMALPAD_X, y: UTDFN4_THERMALPAD_Y } | ||
| } | ||
|
|
||
| return dfn(params) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { test, expect } from "bun:test" | ||
| import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" | ||
| import { fp } from "../src/footprinter" | ||
| import type { AnyCircuitElement } from "circuit-json" | ||
|
|
||
| test("spdip28", () => { | ||
| const circuitJson = fp | ||
| .string("spdip28") | ||
| .circuitJson() as AnyCircuitElement[] | ||
| const svgContent = convertCircuitJsonToPcbSvg(circuitJson) | ||
| expect(svgContent).toMatchSvgSnapshot(import.meta.path, "spdip28") | ||
| }) | ||
|
|
||
| test("SPDIP-28 (alias)", () => { | ||
| const aliasSvg = convertCircuitJsonToPcbSvg( | ||
| fp.string("SPDIP-28").circuitJson(), | ||
| ) | ||
| const canonicalSvg = convertCircuitJsonToPcbSvg( | ||
| fp.string("spdip28").circuitJson(), | ||
| ) | ||
| expect(aliasSvg).toEqual(canonicalSvg) | ||
| }) | ||
|
|
||
| test("spdip8", () => { | ||
| const circuitJson = fp | ||
| .string("spdip8") | ||
| .circuitJson() as AnyCircuitElement[] | ||
| const svgContent = convertCircuitJsonToPcbSvg(circuitJson) | ||
| expect(svgContent).toMatchSvgSnapshot(import.meta.path, "spdip8") | ||
| }) | ||
|
|
||
| test("spdip default params", () => { | ||
| const json = fp.string("spdip28").json() | ||
| // SPDIP defaults: pitch = 1.778mm (shrink), width = 7.62mm (narrow body) | ||
| expect(json.fn).toBe("spdip") | ||
| expect(json.num_pins).toBe(28) | ||
| expect(json.w).toBe(7.62) | ||
| expect(json.p).toBe(1.778) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { test, expect } from "bun:test" | ||
| import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" | ||
| import { fp } from "../src/footprinter" | ||
| import type { AnyCircuitElement } from "circuit-json" | ||
|
|
||
| test("utdfn4", () => { | ||
| const circuitJson = fp | ||
| .string("utdfn4") | ||
| .circuitJson() as AnyCircuitElement[] | ||
| const svgContent = convertCircuitJsonToPcbSvg(circuitJson) | ||
| expect(svgContent).toMatchSvgSnapshot(import.meta.path, "utdfn4") | ||
| }) | ||
|
|
||
| test("UTDFN-4-EP(1x1) alias", () => { | ||
| const aliasSvg = convertCircuitJsonToPcbSvg( | ||
| fp.string("UTDFN-4-EP(1x1)").circuitJson(), | ||
| ) | ||
| const canonicalSvg = convertCircuitJsonToPcbSvg( | ||
| fp.string("utdfn4").circuitJson(), | ||
| ) | ||
| expect(aliasSvg).toEqual(canonicalSvg) | ||
| }) | ||
|
|
||
| test("utdfn4 default params", () => { | ||
| const json = fp.string("utdfn4").json() | ||
| // UTDFN-4-EP(1x1) defaults: w=1.0mm, p=0.5mm | ||
| // Note: h is computed from pin layout, not passed as param | ||
| expect(json.fn).toBe("utdfn") | ||
| expect(json.num_pins).toBe(4) | ||
| expect(json.w).toBe(1) | ||
| expect(json.p).toBe(0.5) | ||
| }) | ||
|
Comment on lines
+1
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test file contains 3 test() calls, which violates the rule that a *.test.ts file may have AT MOST one test(...). The file should be split into multiple numbered files like utdfn1.test.ts, utdfn2.test.ts, and utdfn3.test.ts, with each file containing only one test() call. Spotted by Graphite (based on custom rule: Custom rule) |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test file contains 4 test() calls, which violates the rule that a *.test.ts file may have AT MOST one test(...). The file should be split into multiple numbered files like spdip1.test.ts, spdip2.test.ts, spdip3.test.ts, and spdip4.test.ts, with each file containing only one test() call.
Spotted by Graphite (based on custom rule: Custom rule)

Is this helpful? React 👍 or 👎 to let us know.