Horizon
Loading...
Searching...
No Matches
priv.h
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 <footag/footag.h>
21#include <math.h>
22#include <stdlib.h>
23#include <string.h>
24
25#ifndef UNUSED
26 #define UNUSED(i) (void) (sizeof (i))
27#endif
28
29#ifndef NELEM
30 #define NELEM(a) ((sizeof a) / (sizeof (a[0])))
31#endif
32
33struct footag_op {
34 size_t size;
35 int (*init)(struct footag_ctx *ctx);
36 int (*fini)(struct footag_ctx *ctx);
37 int (*calc)(struct footag_ctx *ctx);
38 const char * (*hint)(
39 struct footag_ctx *ctx,
40 const struct footag_param *p
41 );
42 /* Description of component type, for use by application. */
43 const struct footag_typeinfo *info;
44 /* Parameter template, terminated with */
45 const struct footag_param *temp;
46};
47
48struct footag_ctx {
49 const struct footag_op *op;
50 struct footag_param *param;
51 struct footag_spec spec;
52};
53
54#define ITEM_NONE { \
55 .type = FOOTAG_DATA_NONE, \
56}
57
58#define ITEM_BOOL(_val) { \
59 .type = FOOTAG_DATA_BOOL, \
60 .data = { \
61 .b = (_val), \
62 }, \
63}
64
65#define ITEM_INTEGER(_val, _step, _min, _max) { \
66 .type = FOOTAG_DATA_INTEGER, \
67 .data = { \
68 .i = { \
69 .val = (_val), \
70 .step = (_step), \
71 .min = (_min), \
72 .max = (_max), \
73 }, \
74 }, \
75}
76
77#define ITEM_FLOAT(_val) { \
78 .type = FOOTAG_DATA_FLOAT, \
79 .data = { \
80 .f = (_val), \
81 }, \
82}
83
84#define ITEM_LENGTH(_val) { \
85 .type = FOOTAG_DATA_LENGTH, \
86 .data = { \
87 .l = (_val), \
88 }, \
89}
90
91/* nom, plus minus */
92#define ITEM_TOL_PM(_nom, _pm) { \
93 .type = FOOTAG_DATA_TOL, \
94 .data = { \
95 .t = { \
96 .nom = (_nom), \
97 .min = (_nom - _pm), \
98 .max = (_nom + _pm), \
99 } \
100 }, \
101}
102
103/* min, max */
104#define ITEM_TOL_MM(_min, _max) { \
105 .type = FOOTAG_DATA_TOL, \
106 .data = { \
107 .t = { \
108 .nom = ((_min + _max) / 2.0), \
109 .min = (_min), \
110 .max = (_max), \
111 } \
112 }, \
113}
114
115#define ITEM_TOL_DATA(a, b) { \
116 .nom = (a) <= (b) ? ((a + b) / 2.0) : (a), \
117 .min = (a) <= (b) ? (a) : (a - b), \
118 .max = (a) <= (b) ? (b) : (a + b), \
119}
120
121#define ITEM_TOL(_a, _b) { \
122 .type = FOOTAG_DATA_TOL, \
123 .data = { \
124 .t = ITEM_TOL_DATA(_a, _b), \
125 }, \
126}
127
128#define ITEM_ENUM(_val, _num, ...) { \
129 .type = FOOTAG_DATA_ENUM, \
130 .data = { \
131 .e = { \
132 .val = _val, \
133 .num = _num, \
134 .strs = (const char *const []) { __VA_ARGS__ }, \
135 }, \
136 }, \
137}
138
139#define ITEM_BITMASK(_val, _num, ...) { \
140 .type = FOOTAG_DATA_BITMASK, \
141 .data = { \
142 .m = { \
143 .val = _val, \
144 .num = _num, \
145 .strs = (const char *const []) { __VA_ARGS__ }, \
146 }, \
147 }, \
148}
149
150#define PARAM_HEADER(_id, _name, _abbr) \
151 .id = PARAM_ ## _id, \
152 .name = _name, \
153 .abbr = _abbr
154
155#define PARAM_TERM { \
156 PARAM_HEADER(DONE, "done", "done"), \
157 .item = ITEM_NONE, \
158}
159
160#define PARAM_TOPIC(_name) { \
161 .id = PARAM_TOPIC, \
162 .name = _name, \
163 .abbr = "", \
164 .item = ITEM_NONE, \
165}
166
167#define PARAM_B(_id, _name, _abbr, _val) { \
168 PARAM_HEADER(_id, _name, _abbr), \
169 .item = ITEM_BOOL(_val), \
170}
171
172#define PARAM_I(_id, _name, _abbr, _val, _step, _min, _max) { \
173 PARAM_HEADER(_id, _name, _abbr), \
174 .item = ITEM_INTEGER(_val, _step, _min, _max), \
175}
176
177#define PARAM_F(_id, _name, _abbr, _val) { \
178 PARAM_HEADER(_id, _name, _abbr), \
179 .item = ITEM_FLOAT(_val), \
180}
181
182#define PARAM_L(_id, _name, _abbr, _val) { \
183 PARAM_HEADER(_id, _name, _abbr), \
184 .item = ITEM_LENGTH(_val), \
185}
186
187#define PARAM_TPM(_id, _name, _abbr, _nom, _pm) { \
188 PARAM_HEADER(_id, _name, _abbr), \
189 .item = ITEM_TOL_PM(_nom, _pm), \
190}
191
192#define PARAM_TMM(_id, _name, _abbr, _min, _max) { \
193 PARAM_HEADER(_id, _name, _abbr), \
194 .item = ITEM_TOL_MM(_min, _max), \
195}
196
197/*
198 * interprets _a and _b, based on their values, as one of the following:
199 * 1. _a: nominal, _b: plus/minus
200 * 2. _a: min, _b: max
201 */
202#define PARAM_T(_id, _name, _abbr, _a, _b) { \
203 PARAM_HEADER(_id, _name, _abbr), \
204 .item = ITEM_TOL(_a, _b), \
205}
206
207#define PARAM_E(_id, _name, _abbr, _val, _num, ...) { \
208 PARAM_HEADER(_id, _name, _abbr), \
209 .item = ITEM_ENUM(_val, _num, __VA_ARGS__), \
210}
211
212#define PARAM_M(_id, _name, _abbr, _val, _num, ...) { \
213 PARAM_HEADER(_id, _name, _abbr), \
214 .item = ITEM_BITMASK(_val, _num, __VA_ARGS__), \
215}
216
217#define PARAM_CALC_IPC7351B \
218 PARAM_TOPIC("Calc"), \
219 PARAM_E(CALC_D, "Density", "-", FOOTAG_LEVEL_N, FOOTAG_LEVEL_NUM, \
220 "Most", "Nominal", "Least" \
221 ), \
222 PARAM_L(CALC_F, "Fabrication", "-", 0.10), \
223 PARAM_L(CALC_P, "Placement", "-", 0.10), \
224 PARAM_TOPIC("Generate"), \
225 PARAM_E(CALC_ROUND, "Round-off", "-", 3, 4, \
226 "None", "0.01 mm", "0.02 mm", "0.05 mm" \
227 )
228
229#define PARAM_CALC_IPC7351B_HIRES \
230 PARAM_TOPIC("Calc"), \
231 PARAM_E(CALC_D, "Density", "-", FOOTAG_LEVEL_N, FOOTAG_LEVEL_NUM, \
232 "Most", "Nominal", "Least" \
233 ), \
234 PARAM_L(CALC_F, "Fabrication", "-", 0.05), \
235 PARAM_L(CALC_P, "Placement", "-", 0.05), \
236 PARAM_TOPIC("Generate"), \
237 PARAM_E(CALC_ROUND, "Round-off", "-", 1, 4, \
238 "None", "0.01 mm", "0.02 mm", "0.05 mm" \
239 )
240
241#define PARAM_CALC_IPC7251DRAFT1 \
242 PARAM_TOPIC("Calc"), \
243 PARAM_E(CALC_D, "Level", "-", FOOTAG_LEVEL_N, FOOTAG_LEVEL_NUM, \
244 "A (Maximum)", "B (Nominal)", "C (Least)" \
245 ), \
246 PARAM_TOPIC("Generate"), \
247 PARAM_E(CALC_ROUND, "Round-off", "-", 3, 4, \
248 "None", "0.01 mm", "0.02 mm", "0.05 mm" \
249 )
250
251#define PARAM_PADSTACK_SMD_RECTS \
252 PARAM_E(CALC_STACK, "Padstack", "-", 1, 2, \
253 "Rectangular", "Rounded rectangular" \
254 )
255
256int footag_init_from_template(
257 struct footag_ctx *ctx,
258 const struct footag_param *temp
259);
260
261int footag_init_default(
262 struct footag_ctx *ctx
263);
264
265int footag_init_twopin(
266 struct footag_ctx *ctx
267);
268
269int footag_fini_default(
270 struct footag_ctx *ctx
271);
272
273const union footag_data *footag_data_by_name(
274 struct footag_ctx *ctx,
275 const char *topic,
276 const char *name
277);
278
279const union footag_data *footag_data_by_id(
280 struct footag_ctx *ctx,
281 int id
282);
283
284#define GETID(_ctx, _id) footag_data_by_id(_ctx, PARAM_ ## _id)
285
286enum {
287 PARAM_DONE = FOOTAG_PARAM_DONE,
288 PARAM_IGNORE = FOOTAG_PARAM_IGNORE,
289 PARAM_TOPIC = FOOTAG_PARAM_TOPIC,
290 PARAM_BODY_L,
291 PARAM_BODY_W,
292 PARAM_BODY_H,
293 /* number of pins */
294 PARAM_BODY_N,
295 PARAM_BODY_Nx,
296 /* rows */
297 PARAM_BODY_R,
298 /* columns */
299 PARAM_BODY_C,
300 /* perimeter rows and columns */
301 PARAM_BODY_PR,
302 PARAM_BODY_PC,
303 /* polarized */
304 PARAM_BODY_POL,
305 PARAM_LEAD_L,
306 PARAM_LEAD_W,
307 PARAM_LEAD_W1,
308 /* diameter */
309 PARAM_LEAD_D,
310 /* pullback */
311 PARAM_LEAD_PB,
312 /* span */
313 PARAM_LEAD_S,
314 PARAM_LEAD_Sx,
315 /* pitch: spacing between leads or castellations */
316 PARAM_LEAD_P,
317 PARAM_CALC_D,
318 PARAM_CALC_F,
319 PARAM_CALC_P,
320 PARAM_CALC_STACK,
321 PARAM_CALC_ROUND,
322 PARAM_NAME_ROW,
323 PARAM_CUSTOM,
324};
325
326/* translate from PARAM_CALC_D to FOOTAG_LEVEL_ */
327static inline int footag_get_density(
328 const struct footag_enum *e
329)
330{
331 return e->val;
332}
333
334/*
335 * IPC-7351B seems to say 0.05
336 */
337static const double ROUNDOFF_TO_GRID[4] = {
338 [0] = 0.00,
339 [1] = 0.01,
340 [2] = 0.02,
341 [3] = 0.05,
342};
343
344/* NOTE: snap is an operation and grid is a property */
345static inline double snap(double v, double grid)
346{
347 if (!grid) { return v; }
348 return round(v / grid) * grid;
349}
350
351/*
352 * round to grid:
353 * - placement
354 * - dimensions
355 * - parameter (radius)
356 */
357void footag_snap(
358 struct footag_spec *s,
359 double grid
360);
361
362void footag_setcourtyard(
363 struct footag_spec *s,
364 double cyexc
365);
366
367static inline double footag_padypos(double pitch, int rows, int row)
368{
369 double y;
370 y = - 1 * ((rows / 2.0) - 1.0 / 2);
371 y += row;
372 y *= pitch;
373 return y;
374}
375
376void footag_gridnames(
377 struct footag_pad *p,
378 const struct footag_bitmask *const skipmask,
379 int rows,
380 int cols
381);
382
383void footag_gennames(
384 struct footag_pad *p,
385 int npads,
386 int startnum,
387 int deltanum
388);
389
390void footag_genrow(
391 struct footag_pad *p,
392 double addx, double addy,
393 double pitch,
394 /* start positions */
395 int x, int y,
396 int dx, int dy,
397 int rows,
398 long angle
399);
400
401void footag_gentworow(
402 struct footag_pad *p,
403 double dist,
404 double w, double h,
405 double pitch,
406 int npads,
407 enum footag_padstack stack
408);
409
410void footag_genquad(
411 struct footag_pad *p,
412 double distrow,
413 double wrow, double hrow,
414 double distcol,
415 double wcol, double hcol,
416 double pitch,
417 int rows, int cols,
418 enum footag_padstack stack
419);
420
421void footag_gengrid(
422 struct footag_pad *p,
423 double w, double h,
424 double pitch,
425 int rows, int cols,
426 int prows, int pcols,
427 enum footag_padstack stack
428);
429
430void footag_genlrow(
431 struct footag_pad *p,
432 double dist,
433 double w, double h,
434 double pitch,
435 int npads,
436 enum footag_padstack stack
437);
438
439void footag_genrrow(
440 struct footag_pad *p,
441 double dist,
442 double w, double h,
443 double pitch,
444 int npads,
445 enum footag_padstack stack
446);
447
448void footag_gentwopin(
449 struct footag_pad *p,
450 double dist,
451 double w, double h,
452 enum footag_padstack stack
453);
454
455void footag_ipc7351b_setrrectpad(
456 struct footag_pad *p
457);
458
459void footag_ipc7351b_setrrectpads(
460 const struct footag_spec *s
461);
462
463int footag_realloc_pads(
464 struct footag_ctx *ctx,
465 int npads
466);
467
468static inline int intmin(int a, int b) { return a < b ? a : b; }
469static inline int intmax(int a, int b) { return a < b ? b : a; }
470
471static inline struct footag_rlimit footag_crlimit(
472 double w,
473 double h
474)
475{
476 return (const struct footag_rlimit) {
477 .minx = - w / 2.0,
478 .maxx = w / 2.0,
479 .miny = - h / 2.0,
480 .maxy = h / 2.0,
481 };
482}
483
484const char *footag_hint_ipc7251draft1(
485 struct footag_ctx *ctx,
486 const struct footag_param *p
487);
488
489struct ipcb_ref;
490void footag_setref_ipc7351b(
491 struct footag_spec *s,
492 const struct ipcb_ref *ref
493);
494
495struct ipc7251_ref;
496void footag_setref_ipc7251draft1(
497 struct footag_spec *s,
498 const struct ipc7251_ref *ref
499);
500
Definition footag.h:51
Definition priv.h:48
Definition footag.h:45
Definition priv.h:33
Definition footag.h:109
Definition footag.h:85
Definition footag.h:122
Definition footag.h:139
Definition footag.h:184
Definition ipc7251draft1.h:52
Definition ipc7351b.h:111
Definition footag.h:64