diff --git a/src/fn/dfn.ts b/src/fn/dfn.ts index c0cb5652..af564412 100644 --- a/src/fn/dfn.ts +++ b/src/fn/dfn.ts @@ -12,9 +12,10 @@ import { CORNERS } from "src/helpers/corner" import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef" import { function_call } from "src/helpers/zod/function-call" import { createThermalPad } from "src/helpers/create-thermal-pad" +import { addThermalVias, thermalViaDef } from "src/helpers/create-thermal-vias" import { polygonpad } from "src/helpers/polygonpad" -export const dfn_def = extendSoicDef({}) +export const dfn_def = extendSoicDef({}).and(thermalViaDef) export type DfnInput = z.input & { /** Replace the four rectangular DFN pads with chamfered corner pads. */ cornerpads?: boolean @@ -214,13 +215,15 @@ export const dfn = ( layer: "top", } + const circuitJson = [ + ...pads, + silkscreenRefText, + ...silkscreenPaths, + courtyard, + ] as AnyCircuitElement[] + return { - circuitJson: [ - ...pads, - silkscreenRefText, - ...silkscreenPaths, - courtyard, - ] as AnyCircuitElement[], + circuitJson: addThermalVias(circuitJson, parameters), parameters, } } diff --git a/src/footprinter.ts b/src/footprinter.ts index 40ef3ea1..45733149 100644 --- a/src/footprinter.ts +++ b/src/footprinter.ts @@ -205,6 +205,10 @@ export type Footprinter = { | "thermalpad" | "thermalpadcenteroffsetx" | "thermalpadcenteroffsety" + | "thermalvias" + | "thermalviapitch" + | "thermalviaid" + | "thermalviaod" | "cornerpads" | "cornerpadcutlength" > diff --git a/tests/__snapshots__/dfn8_thermalpad_2x3_thermalvias.snap.svg b/tests/__snapshots__/dfn8_thermalpad_2x3_thermalvias.snap.svg new file mode 100644 index 00000000..faefdb63 --- /dev/null +++ b/tests/__snapshots__/dfn8_thermalpad_2x3_thermalvias.snap.svg @@ -0,0 +1 @@ +{REF} \ No newline at end of file diff --git a/tests/dfn.test.ts b/tests/dfn.test.ts index 492061a4..cccba33a 100644 --- a/tests/dfn.test.ts +++ b/tests/dfn.test.ts @@ -46,3 +46,31 @@ test("dfn6 can omit its second nominal pad position", () => { const svgContent = convertCircuitJsonToPcbSvg(soup) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "dfn6_missing2") }) + +test("dfn thermal pad supports a configurable via grid", () => { + const soup = fp + .string( + "dfn8_w5.3mm_p1.27mm_thermalpad2.4x3mm_thermalvias2x3_thermalviapitch0.8mm_thermalviaid0.25mm_thermalviaod0.5mm", + ) + .circuitJson() + const vias = soup.filter((element) => element.type === "pcb_via") + + expect(vias).toHaveLength(6) + expect(vias.map(({ x, y }) => [x, y])).toEqual( + [-0.8, 0, 0.8].flatMap((y) => [-0.4, 0.4].map((x) => [x, y])), + ) + expect( + vias.every( + (via) => + via.hole_diameter === 0.25 && + via.outer_diameter === 0.5 && + via.layers[0] === "top" && + via.layers[1] === "bottom", + ), + ).toBe(true) + + expect(convertCircuitJsonToPcbSvg(soup)).toMatchSvgSnapshot( + import.meta.path, + "dfn8_thermalpad_2x3_thermalvias", + ) +})