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