"""Ball grid array IC package (DSBGA die-size BGA, MicroStar Junior and plastic BGA) by TI package outline. Centred on the origin with the seating plane on the XY plane, seen from above: ball A1 at the -X, +Y corner, columns 1, 2, ... running +X and rows A, B, ... running -Y. Each solder ball is its own solid. Dimensions from the TI outline named by `package`; see the README.""" from steve import Model package = "YZP0010" # TI package outline # outline: (kind, balls, columns, rows, pitch, body along the rows (D, Y), body along the columns (E, X), overall height (min, max) or (None, max), # body thickness above the balls (min, max) or None, ball standoff A1 (min, max), ball diameter (min, max), balls left out of the grid), all mm. # Rows are lettered A, B, C ... without I, O, Q and S, as TI letters them. # TI package outlines, https://www.ti.com/lit/...: # ZAV lit/pdf/mpbg777, ZAV (S-PBGA-N289), 4208156/A 08/06 # ZQW lit/pdf/mpbg674, ZQW (S-PBGA-N113), 4204599-3/D 08/12 (MicroStar Junior) # GQE lit/ds/symlink/tlv320aic23b.pdf, SLWS106H, Appendix A page A-1, GQE/ZQE (S-PBGA-N80), 4200461/C 10/00 (MicroStar Junior) # YZP0010 lit/ds/symlink/ts3a24159.pdf, SCDS238H, page 34, 4219350/B 11/2017 (D and E from its table) # YZP0008 lit/ds/symlink/txb0102.pdf, SCES641E, page 36, 4223082/A 07/2016 (D and E from its table) # YKA0006 lit/ds/symlink/tps62843.pdf, SLVSFU8C, page 36, 4223607/B 06/2023 (D and E from its table) # The DSBGA outlines give the height as a maximum only (YKA0006 as 0.35 to 0.40) and no die thickness: the die is drawn from the standoff to that height. OUTLINES = { "YKA0006": ("DSBGA", 6, 2, 3, 0.35, (0.98, 1.04), (0.727, 0.787), (0.35, 0.40), None, (0.13, 0.18), (0.19, 0.24), ()), "YZP0008": ("DSBGA", 8, 2, 4, 0.5, (1.858, 1.918), (0.858, 0.918), (None, 0.5), None, (0.15, 0.19), (0.21, 0.25), ()), "YZP0010": ("DSBGA", 10, 3, 4, 0.5, (1.83, 1.89), (1.33, 1.39), (None, 0.5), None, (0.15, 0.19), (0.21, 0.25), ("B2", "C2")), "GQE": ("MicroStar Junior BGA", 80, 9, 9, 0.5, (4.9, 5.1), (4.9, 5.1), (None, 1.0), (0.62, 0.68), (0.11, 0.21), (0.25, 0.35), ("C3",)), "ZQW": ("MicroStar Junior BGA", 113, 12, 12, 0.5, (6.9, 7.1), (6.9, 7.1), (None, 1.0), (0.71, 0.77), (0.15, 0.25), (0.25, 0.35), ("C4", "C5", "C6", "C7", "C8", "C9", "C10", "D3", "D10", "E3", "E10", "F3", "F6", "F7", "F10", "G3", "G6", "G7", "G10", "H3", "H10", "J3", "J10", "K3", "K4", "K5", "K6", "K7", "K8", "K9", "K10")), "ZAV": ("BGA", 289, 17, 17, 0.8, (14.9, 15.1), (14.9, 15.1), (None, 1.4), (0.84, 0.96), (0.35, 0.45), (0.45, 0.55), ()), } ROW_LETTERS = "ABCDEFGHJKLMNPRTUVWY" # The pin-1 mark on top is a proportion, for looks. def mid(pair): return (pair[0] + pair[1]) / 2 kind, balls, cols, rows, pitch, D, E, H, BODY, A1, BALL, missing = OUTLINES[package] length, width, standoff, ball = mid(D), mid(E), mid(A1), mid(BALL) if BODY: top = standoff + mid(BODY) elif H[0] is None: top = H[1] else: top = mid(H) r = ball / 2 x0 = -(cols - 1) * pitch / 2 y0 = (rows - 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", (-width / 2, -length / 2), (width / 2, length / 2)) model.extrude("body", "body_sketch", distance=top - standoff, op="new", body="body_body", name="Body") model.plane("top_plane", on="XY", offset=top, name="Top") with model.sketch("mark_sketch", on="top_plane", name="Ball A1 mark") as sk: sk.circle("mark_circle", (-width / 2 + 0.12 * min(width, length), length / 2 - 0.12 * min(width, length)), 0.05 * min(width, length)) model.extrude("mark", "mark_sketch", distance=-min(0.03, (top - standoff) / 4), op="cut", body="body_body", name="Ball A1 mark") # The balls, row by row: each run of balls with no gap is one sphere repeated along +X. A ball stands on the seating plane and is cut flat where it # meets the body, at the standoff. first = True for j in range(rows): run = [] for i in range(cols + 1): here = i < cols and f"{ROW_LETTERS[j]}{i + 1}" not in missing if here: run.append(i) continue if run and first: # the very first ball makes the balls body on its own, so that the patterns after it join that body model.sphere("ball_first", r, at=(x0 + run[0] * pitch, y0 - j * pitch, r), op="new", body="balls_body", name="Balls") first = False run = run[1:] if run: start = f"ball_{ROW_LETTERS[j].lower()}{run[0] + 1}" model.sphere(start, r, at=(x0 + run[0] * pitch, y0 - j * pitch, r), op="join", body="balls_body", name="Balls") if len(run) > 1: model.linear_pattern(f"{start}_run", direction=(1, 0, 0), count=len(run), spacing=pitch, features=[start], name="Balls") run = [] with model.sketch("trim_sketch", on="body_plane", name="Balls") as sk: sk.rect("trim_rect", (-width, -length), (width, length)) model.extrude("trim", "trim_sketch", distance=ball, op="cut", body="balls_body", name="Balls") # Materials, for looks and a rough mass: a DSBGA is the bare silicon die; a moulded BGA's body is epoxy compound on a laminate substrate, mostly silica # filler (density about 1.9 to 2.0), and ptfe (2.2) is the nearest in the material list; the balls are tin-silver-copper solder, tin. model.material("silicon" if kind == "DSBGA" else "ptfe", bodies=["body_body"], color="#2b2d31" if kind == "DSBGA" else "#26282b") model.material("tin", bodies=["balls_body"], color="#c9ccd1") result = model.result()