diff --git a/src/fn/index.ts b/src/fn/index.ts index 94c0370e..75131465 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 { utdfn } from "./utdfn" diff --git a/src/fn/utdfn.ts b/src/fn/utdfn.ts new file mode 100644 index 00000000..2026eeec --- /dev/null +++ b/src/fn/utdfn.ts @@ -0,0 +1,42 @@ +import type { AnyCircuitElement } from "circuit-json" +import { length } from "circuit-json" +import { base_def } from "src/helpers/zod/base_def" +import { z } from "zod" +import { vson } from "./vson" + +export const utdfn_def = base_def.extend({ + fn: z.string(), + num_pins: z.number().optional().default(4), + w: z.string().default("1mm"), + h: z.string().default("1mm"), + p: z.string().default("0.5mm"), + pl: z.string().default("0.3mm"), + pw: z.string().default("0.25mm"), + ep: z.boolean().optional().default(false), + epw: z.string().default("0.4mm"), + eph: z.string().default("0.5mm"), +}) + +export const utdfn = ( + rawParams: z.input, +): { + circuitJson: AnyCircuitElement[] + parameters: z.infer +} => { + const parameters = utdfn_def.parse(rawParams) + const bodyWidth = length.parse(parameters.w) + const padLength = length.parse(parameters.pl) + const pinRowCenterSpacing = `${bodyWidth - padLength / 2}mm` + + const { circuitJson } = vson({ + ...parameters, + fn: "vson", + w: pinRowCenterSpacing, + grid: `${parameters.w}x${parameters.h}`, + ep: parameters.ep ? `${parameters.epw}x${parameters.eph}` : "0x0mm", + pinw: parameters.pl, + pinh: parameters.pw, + }) + + return { circuitJson, parameters } +} diff --git a/src/footprinter.ts b/src/footprinter.ts index fa51a3b4..2bfd9815 100644 --- a/src/footprinter.ts +++ b/src/footprinter.ts @@ -182,6 +182,11 @@ export type Footprinter = { ) => FootprinterParamsBuilder< "p" | "w" | "grid" | "ep" | "epx" | "pinw" | "pinh" > + utdfn: ( + num_pins?: number, + ) => FootprinterParamsBuilder< + "w" | "h" | "p" | "pl" | "pw" | "ep" | "epw" | "eph" + > vssop: ( num_pins?: number, ) => FootprinterParamsBuilder<"w" | "h" | "p" | "pl" | "pw"> @@ -273,6 +278,10 @@ const normalizeDefinition = (def: string): string => { .replace(/^pinheader(?=[\d_]|$)/i, "pinrow") .replace(/^sot23-(\d+)(?=_|$)/i, "sot23_$1") .replace(/^sot-223-(\d+)(?=_|$)/i, "sot223_$1") + .replace( + /^utdfn-(\d+)-ep\(([\d.]+)x([\d.]+)\)(?=_|$)/i, + "utdfn$1_w$2mm_h$3mm_ep", + ) .replace(/^to-220f-(\d+)(?=_|$)/i, "to220f_$1") .replace(/^jst_(ph|sh|zh)_(\d+)(?=_|$)/i, "jst$2_$1") } diff --git a/src/helpers/zod/AnyFootprinterDefinitionOutput.ts b/src/helpers/zod/AnyFootprinterDefinitionOutput.ts index 96e51153..a0cf108b 100644 --- a/src/helpers/zod/AnyFootprinterDefinitionOutput.ts +++ b/src/helpers/zod/AnyFootprinterDefinitionOutput.ts @@ -1,4 +1,3 @@ -import { z } from "zod" import { axial_def } from "src/fn/axial" import { bga_def } from "src/fn/bga" import { dfn_def } from "src/fn/dfn" @@ -9,20 +8,22 @@ import { ms013_def } from "src/fn/ms013" import { pinrow_def } from "src/fn/pinrow" import { qfn_def } from "src/fn/qfn" import { qfp_def } from "src/fn/qfp" -import { tqfp_def } from "src/fn/tqfp" import { quad_def } from "src/fn/quad" import { sod_def } from "src/fn/sod123" import { soic_def } from "src/fn/soic" import { sot23_def } from "src/fn/sot23" import { sot363_def } from "src/fn/sot363" -import { sot886_def } from "src/fn/sot886" import { sot563_def } from "src/fn/sot563" import { sot723_def } from "src/fn/sot723" +import { sot886_def } from "src/fn/sot886" import { ssop_def } from "src/fn/ssop" +import { tqfp_def } from "src/fn/tqfp" import { tssop_def } from "src/fn/tssop" -import { passive_def } from "../passive-fn" +import { z } from "zod" import { pad_def } from "../../fn/pad" import { smtpad_def } from "../../fn/smtpad" +import { utdfn_def } from "../../fn/utdfn" +import { passive_def } from "../passive-fn" export const any_footprinter_def = z.union([ axial_def, @@ -49,6 +50,7 @@ export const any_footprinter_def = z.union([ passive_def, pad_def, smtpad_def, + utdfn_def, ]) export type AnyFootprinterDefinitionOutput = z.infer diff --git a/tests/__snapshots__/utdfn4_w1mm_h1mm_ep.snap.svg b/tests/__snapshots__/utdfn4_w1mm_h1mm_ep.snap.svg new file mode 100644 index 00000000..f2bca1d2 --- /dev/null +++ b/tests/__snapshots__/utdfn4_w1mm_h1mm_ep.snap.svg @@ -0,0 +1 @@ +{REF} diff --git a/tests/utdfn.test.ts b/tests/utdfn.test.ts new file mode 100644 index 00000000..96cd8783 --- /dev/null +++ b/tests/utdfn.test.ts @@ -0,0 +1,18 @@ +import { expect, test } from "bun:test" +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" +import { fp } from "../src/footprinter" + +test("UTDFN-4-EP(1x1) alias", () => { + const circuitJson = fp.string("UTDFN-4-EP(1x1)").circuitJson() + const pads = circuitJson.filter((element) => element.type === "pcb_smtpad") + + expect(pads).toHaveLength(5) + expect(circuitJson).toEqual(fp.string("utdfn4_w1mm_h1mm_ep").circuitJson()) +}) + +test("utdfn4_w1mm_h1mm_ep", () => { + const circuitJson = fp.string("utdfn4_w1mm_h1mm_ep").circuitJson() + const svgContent = convertCircuitJsonToPcbSvg(circuitJson) + + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "utdfn4_w1mm_h1mm_ep") +})