"""No-lead small-outline IC package (WSON, VSON, DFN) by TI package outline. Centred on the origin with the seating plane on the XY plane, pins 1 to n/2 on the -Y side running +X, the others on +Y running back, and the exposed thermal pad in the middle. Dimensions from the TI outline named by `package`; see the README.""" from steve import Model package = "DSQ0010A" # TI package outline detail = "full" # full: body, pin-1 mark, terminals and thermal pad; simple: the body only # outline: (kind, pins, pitch, body length along the pin rows, body width across them, height, standoff, terminal length, terminal width, thermal pad # across the rows, thermal pad along them, terminal thickness), ranges as (min, max), single values as drawn (thickness is the outline's reference), mm. # TI package outlines, https://www.ti.com/lit/pdf/: DSQ0010A mpds335 (4218906/A 04/2019), NGQ0008A mpds403 (4214922/A 03/2018), DNT0012B mpds48 # (4214928/C 10/2021), NHR0016B mpds42 (4214932/B 08/2025), DRM0008A mpds160 (4218889/A 01/2025). Thermal pads are drawn as nominal +/-0.1. OUTLINES = { "DSQ0010A": ("WSON", 10, 0.4, (1.9, 2.1), (1.9, 2.1), (0.7, 0.8), (0.0, 0.05), (0.2, 0.4), (0.15, 0.25), 0.9, 1.5, 0.2), "NGQ0008A": ("WSON", 8, 0.5, (2.9, 3.1), (2.9, 3.1), (0.7, 0.8), (0.0, 0.05), (0.3, 0.5), (0.2, 0.3), 1.6, 2.0, 0.1), "DNT0012B": ("WSON", 12, 0.5, (3.9, 4.1), (3.9, 4.1), (0.7, 0.8), (0.0, 0.05), (0.3, 0.5), (0.2, 0.3), 2.6, 3.0, 0.1), "NHR0016B": ("WSON", 16, 0.5, (4.9, 5.1), (3.9, 4.1), (0.7, 0.8), (0.0, 0.05), (0.3, 0.5), (0.2, 0.3), 2.6, 4.0, 0.1), "DRM0008A": ("VSON", 8, 0.8, (3.9, 4.1), (3.9, 4.1), (0.8, 1.0), (0.0, 0.05), (0.3, 0.5), (0.23, 0.38), 2.45, 3.38, 0.1), } # The pin-1 mark is a proportion, for looks. def mid(pair): return (pair[0] + pair[1]) / 2 kind, pins, pitch, L, W, H, standoff, term_l, term_w, pad_x, pad_y, thick = OUTLINES[package] length, width, top, standoff, term_l, term_w = mid(L), mid(W), mid(H), mid(standoff), mid(term_l), mid(term_w) per_row = pins // 2 first = -(per_row - 1) * pitch / 2 model = Model() model.plane("body_plane", on="XY", offset=standoff, name="Body") with model.sketch("body_sketch", on="body_plane", name="Body") as sk: sk.rect("body_rect", (-length / 2, -width / 2), (length / 2, width / 2)) model.extrude("body", "body_sketch", distance=top - standoff, name="Body") if detail == "full": model.plane("top_plane", on="XY", offset=top, name="Top") with model.sketch("mark_sketch", on="top_plane", name="Pin-1 mark") as sk: sk.circle("mark_circle", (-length / 2 + 0.15 * width, -width / 2 + 0.15 * width), 0.05 * width) model.extrude("mark", "mark_sketch", distance=-0.03, op="cut", name="Pin-1 mark") for tag, side in (("low", -1), ("high", 1)): y_out, y_in = side * width / 2, side * (width / 2 - term_l) with model.sketch(f"terms_{tag}", on="XY", name="Terminals") as sk: for i in range(per_row): x = first + i * pitch sk.rect(f"term_{tag}_{i}", (x - term_w / 2, min(y_in, y_out)), (x + term_w / 2, max(y_in, y_out))) model.extrude(f"terms_{tag}_body", f"terms_{tag}", distance=thick, name="Terminals") # the thermal pad's across-the-rows size runs along Y, its along-the-rows size along X with model.sketch("pad_sketch", on="XY", name="Thermal pad") as sk: sk.rect("pad_rect", (-pad_y / 2, -pad_x / 2), (pad_y / 2, pad_x / 2)) model.extrude("pad", "pad_sketch", distance=thick, name="Thermal pad") model.material("pla", color="#26282b") result = model.result()