"""Quad flat package (LQFP, TQFP) with gull-wing leads on four sides, by TI package outline. Centred on the origin with the seating plane on the XY plane. Seen from above, pin 1 is the top pin of the -X side and the pins count counter-clockwise: down the -X side, left to right along the -Y side, up the +X side and right to left along the +Y side. Dimensions from the TI outline named by `package`; see the README.""" from steve import Model package = "PM0064A" # TI package outline detail = "full" # full: body, pin-1 mark and gull-wing leads; simple: the body only # outline: (kind, pins, pitch, body (min, max), lead tip to tip (min, max), height max, standoff (min, max), lead width (min, max), # foot length (min, max)), in mm. Where an outline gives only the standoff's minimum (0.05 MIN), that value is used. # TI package outlines, https://www.ti.com/lit/pdf/, page 1 "PACKAGE OUTLINE": # VF0032A mtqf002 (4219769/A 04/2019), PT0048A mtqf003 (4215159/B 11/2023), PM0064A mtqf008 (4215162/A 03/2017), # PN0080A mtqf010 (4215166/A 08/2022), PZ0100A mtqf013 (4215169/A 03/2017): LQFP, 1.6 mm max height; # PFB0048A mtqf019 (4215157/A 03/2024), PFC0080A mtqf009 (4215165/B 06/2017): TQFP, 1.2 mm max height. # Older "MECHANICAL DATA" sheets, comma decimals, which name the package by its letters (S-PQFP-G) and say "Falls within JEDEC # MS-026": PGE (S-PQFP-G144) MTQF017A rev. December 1996 (4040147/C 10/96) and PBL (S-PQFP-G***, the 176-pin row) MTQF018C rev. May 1999 # (4040154/C 06/96), 1,60 max, the LQFP height; PAG (S-PQFP-G64) MTQF006A rev. December 1996 (4040282/C 11/96) and PZT (S-PQFP-G100) # MTQF012B rev. December 1996 (4073179/B 11/96), 1,20 max, the TQFP height. OUTLINES = { "VF0032A": ("LQFP", 32, 0.8, (6.8, 7.2), (8.8, 9.2), 1.6, (0.05, 0.15), (0.25, 0.45), (0.45, 0.75)), "PT0048A": ("LQFP", 48, 0.5, (6.8, 7.2), (8.8, 9.2), 1.6, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PM0064A": ("LQFP", 64, 0.5, (9.8, 10.2), (11.8, 12.2), 1.6, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PN0080A": ("LQFP", 80, 0.5, (11.8, 12.2), (13.8, 14.2), 1.6, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PZ0100A": ("LQFP", 100, 0.5, (13.8, 14.2), (15.8, 16.2), 1.6, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PFB0048A": ("TQFP", 48, 0.5, (6.8, 7.2), (8.8, 9.2), 1.2, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PFC0080A": ("TQFP", 80, 0.5, (11.8, 12.2), (13.8, 14.2), 1.2, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PGE": ("LQFP", 144, 0.5, (19.8, 20.2), (21.8, 22.2), 1.6, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PBL": ("LQFP", 176, 0.4, (19.8, 20.2), (21.8, 22.2), 1.6, (0.05, 0.05), (0.13, 0.23), (0.45, 0.75)), "PAG": ("TQFP", 64, 0.5, (9.8, 10.2), (11.8, 12.2), 1.2, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), "PZT": ("TQFP", 100, 0.5, (13.8, 14.2), (15.8, 16.2), 1.2, (0.05, 0.05), (0.17, 0.27), (0.45, 0.75)), } LEAD_T = 0.13 # lead thickness, the outlines' (0.13) TYP reference # Proportions, for looks (drawn but not dimensioned): the body's corners are chamfered 0.06 x the body; the gull wing leaves the body at # half its height; the pin-1 mark is a dimple of radius 0.04 x the body, 0.1 x the body in from the pin-1 corner. CORNER = 0.06 if package not in OUTLINES: raise ValueError(f"no outline {package!r}: {', '.join(OUTLINES)}") def mid(pair): return (pair[0] + pair[1]) / 2 kind, pins, pitch, B, SPAN, top, STANDOFF, BW, FOOT = OUTLINES[package] body, span, standoff, lead_w, foot = mid(B), mid(SPAN), mid(STANDOFF), mid(BW), mid(FOOT) per_side = pins // 4 first = (per_side - 1) * pitch / 2 h = body / 2 c = CORNER * body 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.polyline("body_outline", [(-h + c, -h), (h - c, -h), (h, -h + c), (h, h - c), (h - c, h), (-h + c, h), (-h, h - c), (-h, -h + c)], closed=True) model.extrude("body", "body_sketch", distance=top - standoff, op="new", body="body_body", name="Body") bodies = ["body_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", (-h + 0.1 * body, h - 0.1 * body), 0.04 * body) model.extrude("mark", "mark_sketch", distance=-0.05, op="cut", body="body_body", name="Pin-1 mark") arm_z = (top + standoff) / 2 out, bend = span / 2, span / 2 - foot T = LEAD_T # One lead: the gull wing seen along its side (u out from the centre, z), extruded by the lead's width. The arm leaves the body at arm_z, # the leg drops at the foot's inner end, and the foot runs out to the tip. All leads are in one leads body, one solid per lead. wing = [(h, arm_z + T), (bend + T / 2, arm_z + T), (bend + T / 2, T), (out, T), (out, 0.0), (bend - T / 2, 0.0), (bend - T / 2, arm_z), (h, arm_z)] # Each side's first pin (YZ planes, normal +X, are sketched as (y, z); XZ planes, normal -Y, as (x, z)), repeated along the side in the # counter-clockwise direction: -X side down from its top pin (pin 1), -Y side left to right, +X side upward, +Y side right to left. row = first + lead_w / 2 # (plane, the plane's x (YZ) or y (XZ), outward normal, step along the side) sides = (("XZ", row, (-1, 0), (0, -1, 0)), ("YZ", -row, (0, -1), (1, 0, 0)), ("XZ", -row + lead_w, (1, 0), (0, 1, 0)), ("YZ", row - lead_w, (0, 1), (-1, 0, 0))) for k, (plane, at, (nx, ny), step) in enumerate(sides): model.plane(f"lead_{k}_plane", on=plane, offset=at if plane == "YZ" else -at, name="Leads") with model.sketch(f"lead_{k}_sketch", on=f"lead_{k}_plane", name="Leads") as sk: sk.polyline(f"lead_{k}_wing", [((nx or ny) * u, z) for u, z in wing], closed=True) # YZ planes extrude along +X and XZ planes along -Y, from the side's first pin. start = f"lead_{k}" model.extrude(start, f"lead_{k}_sketch", distance=lead_w, op="new" if k == 0 else "join", body="leads_body", name="Leads") model.linear_pattern(f"lead_{k}_row", direction=step, count=per_side, spacing=pitch, features=[start], name="Leads") bodies.append("leads_body") # Materials, for looks and a rough mass: the moulding is epoxy compound, mostly silica filler (density about 1.9 to 2.0), and ptfe (2.2) is the # nearest in the material list; the leads are tin-plated copper alloy, copper. model.material("ptfe", bodies=["body_body"], color="#26282b") if detail == "full": model.material("copper", bodies=["leads_body"], color="#c9ccd1") result = model.result()