1 /*
2 * Copyright 2019 Martin Åberg
3 *
4 * This file is part of Footag.
5 *
6 * Footag is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
10 *
11 * Footag is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "priv.h"
21 #include <footag/ipc7351b.h>
22
23 static const struct footag_typeinfo info = {
24 .type = FOOTAG_TYPE_BGA,
25 .name = "BGA",
26 .brief = "Ball grid array",
27 };
28
29 static const struct footag_param temp[] = {
30 PARAM_TOPIC("Body"),
31 PARAM_L(BODY_L, "Length", "-", 23.00),
32 PARAM_L(BODY_W, "Width", "-", 23.00),
33 PARAM_I(BODY_R, "Rows", "-", 22, 1, 2, 64),
34 PARAM_I(BODY_C, "Columns", "-", 22, 1, 2, 64),
35 PARAM_I(BODY_PR, "Perimeter rows", "-", 11, 1, 0, 64),
36 PARAM_I(BODY_PC, "Perimeter columns", "-", 11, 1, 0, 64),
37
38 PARAM_TOPIC("Terminal"),
39 PARAM_L(LEAD_P, "Pitch", "-", 1.00),
40 PARAM_L(LEAD_D, "Ball diameter", "-", 0.60),
41 PARAM_E(CUSTOM, "Solder ball", "-", 1, 2, \
42 "Non-collapsing", "Collapsing", \
43 ),
44 PARAM_M(NAME_ROW, "Skip row", "-", 0x0000003f, 6, \
45 "I", "O", "Q", "S", "X", "Z" \
46 ), \
47 PARAM_TOPIC("Generate"), \
48 PARAM_E(CALC_ROUND, "Round-off", "-", 3, 4, \
49 "None", "0.01 mm", "0.02 mm", "0.05 mm" \
50 ),
51 PARAM_E(CALC_STACK, "Padstack", "-", 2, 3, \
52 "Rectangular", "Rounded rectangular", "Circular" \
53 ),
54 PARAM_TERM,
55 };
56
calc(struct footag_ctx * ctx)57 static int calc(
58 struct footag_ctx *ctx
59 )
60 {
61 struct footag_spec *const s = &ctx->spec;
62 struct ipcb_bgaspec spec;
63 double diam = GETID(ctx, LEAD_D)->l;
64 const int rows = intmax(2, GETID(ctx, BODY_R)->i.val);
65 const int cols = intmax(2, GETID(ctx, BODY_C)->i.val);
66 const int npads = rows * cols;
67 int ret;
68
69 ret = footag_realloc_pads(ctx, npads);
70 if (ret) { return ret; }
71
72 ret = ipcb_get_bga(&spec, diam, GETID(ctx, CUSTOM)->e.val);
73 if (ret) { return ret; }
74
75 footag_gengrid(
76 s->pads,
77 spec.diam, spec.diam,
78 GETID(ctx, LEAD_P)->l,
79 rows, cols,
80 GETID(ctx, BODY_PR)->i.val,
81 GETID(ctx, BODY_PC)->i.val,
82 GETID(ctx, CALC_STACK)->e.val
83 );
84 for (int i = 0; i < npads; i++) {
85 struct footag_pad *p = &s->pads[i];
86 p->diam = spec.diam;
87 }
88 footag_gridnames(
89 ctx->spec.pads,
90 &GETID(ctx, NAME_ROW)->m,
91 rows,
92 cols
93 );
94 s->body = footag_crlimit(
95 GETID(ctx, BODY_W)->l,
96 GETID(ctx, BODY_L)->l
97 );
98 footag_ipc7351b_setrrectpads(&ctx->spec);
99 footag_snap(s, ROUNDOFF_TO_GRID[GETID(ctx, CALC_ROUND)->e.val]);
100 /* NOTE: this is probably wrong */
101 footag_setcourtyard(s, 1.0);
102 footag_setref_ipc7351b(s, &spec.ref);
103
104 return 0;
105 }
106
107 const struct footag_op footag_op_bga = {
108 .size = sizeof (struct footag_ctx),
109 .init = footag_init_default,
110 .fini = footag_fini_default,
111 .calc = calc,
112 .info = &info,
113 .temp = &temp[0],
114 };
115
116