Date: | 2010-04-25 15:09:36 (9 years 7 months ago) |
---|---|
Author: | werner |
Commit: | 6db067a90fd85c72e6b2d9d6337ea49a76e8783c |
Message: | More work on holes: added documentation and Postscript output. - overlap.c (inside, test_overlap): check for instance type - overlap.c (inside, test_overlap): support hole instances - README: put a pointer to the GUI description at the beginning - README, gui.html: documented role and creation of holes - inst.h: holes can now link to pads and vice versa - hole.c, obj.c (instantiate): connect holes with pads and apply consistency checks - postscript.c: added output for holes - icons/hole.fig: make hatched surroundings of hole look more round git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5940 99fdad57-331a-0410-800a-d7fa5415bdb3 |
Files: |
Makefile (1 diff) README (2 diffs) gui.html (1 diff) hole.c (1 diff) hole.h (1 diff) icons/hole.fig (2 diffs) inst.h (1 diff) obj.c (2 diffs) overlap.c (5 diffs) postscript.c (4 diffs) |
Change Details
Makefile | ||
---|---|---|
16 | 16 | |
17 | 17 | OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \ |
18 | 18 | unparse.o file.o dump.o kicad.o postscript.o meas.o \ |
19 | layer.o overlap.o \ | |
19 | layer.o overlap.o hole.o \ | |
20 | 20 | cpp.o lex.yy.o y.tab.o \ |
21 | 21 | gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \ |
22 | 22 | gui_tool.o gui_over.o gui_meas.o gui_frame.o gui_frame_drag.o |
README | ||
---|---|---|
9 | 9 | the textual definition also has a straightforward equivalent operation |
10 | 10 | that can be performed through the GUI. |
11 | 11 | |
12 | This README describes only the footprint definition language. A | |
13 | description of the GUI can be found here: | |
14 | ||
15 | http://people.openmoko.org/werner/fped/gui.html | |
16 | ||
12 | 17 | This work is distributed under the terms of the GNU GENERAL PUBLIC |
13 | 18 | LICENSE, Version 2: |
14 | 19 | |
... | ... | |
251 | 256 | rpad "<name>" <point-a> <point-b> [<type>] |
252 | 257 | |
253 | 258 | |
259 | Holes | |
260 | - - - | |
261 | ||
262 | Holes can be used for through-hole pins or for mechanical support. | |
263 | In the former case, the hole must be placed inside a pad. Only one | |
264 | hole per pad is allowed. Mechanical holes must be outside any pads. | |
265 | ||
266 | Through-hole pads are always present on both sides of the board, i.e., | |
267 | when fped generates a KiCad module, the surface layers of a pad | |
268 | containing a hole are propagated to the opposite side of the board. | |
269 | ||
270 | Holes have the same shape as a rounded pad and their geometry is | |
271 | defined in the same way: | |
272 | ||
273 | hole <point-a> <point-b> | |
274 | ||
275 | ||
254 | 276 | Measurements |
255 | 277 | - - - - - - |
256 | 278 |
gui.html | ||
---|---|---|
222 | 222 | containing the pad. Move the mouse cursor to the first point, then |
223 | 223 | drag to the second point. The pad's name can be edited after selecting |
224 | 224 | the pad. |
225 | <DT><IMG src="manual/hole.png"> | |
226 | <DD> Add a hole. There are two purposes for holes: | |
227 | <UL> | |
228 | <LI> Pins of through-hole components. In this case, the hole has to be | |
229 | inside a pad. | |
230 | <LI> Mechanical support. In this case, the hole has to be outside any | |
231 | pads. | |
232 | </UL> | |
233 | The construction of holes is the same as for pads. | |
225 | 234 | <DT><IMG src="manual/line.png"> <IMG src="manual/rect.png"> |
226 | 235 | <DD> Add a line or a rectangle. Similar to pads, lines and rectangles |
227 | 236 | are defined by two points. The width of the line can be edited after |
hole.c | ||
---|---|---|
1 | /* | |
2 | * hole.c - Classify holes and connect them with pads | |
3 | * | |
4 | * Written 2010 by Werner Almesberger | |
5 | * Copyright 2010 by Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | ||
14 | #include "error.h" | |
15 | #include "inst.h" | |
16 | #include "overlap.h" | |
17 | #include "hole.h" | |
18 | ||
19 | ||
20 | static int check_through_hole(struct inst *pad, struct inst *hole) | |
21 | { | |
22 | if (!overlap(pad, hole)) | |
23 | return 1; | |
24 | if (!inside(hole, pad)) { | |
25 | fail("hole (line %d) not completely inside " | |
26 | "pad \"%s\" (line %d)", hole->obj->lineno, | |
27 | pad->u.pad.name, pad->obj->lineno); | |
28 | instantiation_error = pad->obj; | |
29 | return 0; | |
30 | } | |
31 | if (hole->u.hole.pad) { | |
32 | /* | |
33 | * A hole can only be on several pads if the pads themselves | |
34 | * overlap. We'll catch this error in refine_copper. | |
35 | */ | |
36 | return 1; | |
37 | } | |
38 | if (pad->u.pad.hole) { | |
39 | fail("pad \"%s\" (line %d) has multiple holes (lines %d, %d)", | |
40 | pad->u.pad.name, pad->obj->lineno, | |
41 | hole->obj->lineno, pad->u.pad.hole->obj->lineno); | |
42 | instantiation_error = pad->obj; | |
43 | return 0; | |
44 | } | |
45 | pad->u.pad.hole = hole; | |
46 | hole->u.hole.pad = pad; | |
47 | return 1; | |
48 | } | |
49 | ||
50 | ||
51 | static int connect_holes(const struct pkg *pkg) | |
52 | { | |
53 | struct inst *pad, *hole; | |
54 | ||
55 | for (pad = pkg->insts[ip_pad_copper]; pad; pad = pad->next) | |
56 | for (hole = pkg->insts[ip_hole]; hole; hole = hole->next) | |
57 | if (!check_through_hole(pad, hole)) | |
58 | return 0; | |
59 | return 1; | |
60 | } | |
61 | ||
62 | ||
63 | static void clear_links(const struct pkg *pkg) | |
64 | { | |
65 | struct inst *pad, *hole; | |
66 | ||
67 | for (pad = pkg->insts[ip_pad_copper]; pad; pad = pad->next) | |
68 | pad->u.pad.hole = NULL; | |
69 | for (pad = pkg->insts[ip_pad_special]; pad; pad = pad->next) | |
70 | pad->u.pad.hole = NULL; | |
71 | for (hole = pkg->insts[ip_hole]; hole; hole = hole->next) | |
72 | hole->u.hole.pad = NULL; | |
73 | } | |
74 | ||
75 | ||
76 | int link_holes(void) | |
77 | { | |
78 | const struct pkg *pkg; | |
79 | ||
80 | for (pkg = pkgs; pkg; pkg = pkg->next) { | |
81 | clear_links(pkg); | |
82 | if (!connect_holes(pkg)) | |
83 | return 0; | |
84 | } | |
85 | return 1; | |
86 | } |
hole.h | ||
---|---|---|
1 | /* | |
2 | * hole.h - Classify holes and connect them with pads | |
3 | * | |
4 | * Written 2010 by Werner Almesberger | |
5 | * Copyright 2010 by Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | #ifndef HOLE_H | |
14 | #define HOLE_H | |
15 | ||
16 | int link_holes(void); | |
17 | ||
18 | #endif /* !HOLE_H */ |
icons/hole.fig | ||
---|---|---|
7 | 7 | Single |
8 | 8 | -2 |
9 | 9 | 1200 2 |
10 | 6 3600 2400 6000 4800 | |
11 | 10 | 1 3 0 8 0 7 45 -1 20 0.000 1 0.0000 4800 3600 600 600 4800 3600 5400 3600 |
12 | 11 | 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 |
13 | 12 | 3600 2400 6000 2400 6000 4800 3600 4800 3600 2400 |
14 | 13 | 2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2 |
15 | 3900 4500 5700 2700 | |
14 | 4050 4350 5550 2850 | |
16 | 15 | 2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2 |
17 | 16 | 3900 3900 5100 2700 |
18 | 17 | 2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2 |
... | ... | |
21 | 20 | 4500 4500 5700 3300 |
22 | 21 | 2 1 0 5 0 7 50 -1 20 0.000 0 1 -1 0 0 2 |
23 | 22 | 5100 4500 5700 3900 |
24 | -6 |
inst.h | ||
---|---|---|
98 | 98 | char *name; |
99 | 99 | struct coord other; |
100 | 100 | layer_type layers; /* bit-set of layers */ |
101 | struct inst *hole; /* through-hole or NULL */ | |
101 | 102 | } pad; |
102 | 103 | struct { |
103 | 104 | struct coord other; |
105 | struct inst *pad; /* through-hole pad of NULL */ | |
104 | 106 | } hole; |
105 | 107 | struct { |
106 | 108 | unit_type r; |
obj.c | ||
---|---|---|
20 | 20 | #include "expr.h" |
21 | 21 | #include "meas.h" |
22 | 22 | #include "inst.h" |
23 | #include "hole.h" | |
23 | 24 | #include "layer.h" |
24 | 25 | #include "delete.h" |
25 | 26 | #include "obj.h" |
... | ... | |
476 | 477 | find_vec = NULL; |
477 | 478 | find_obj = NULL; |
478 | 479 | if (ok) |
480 | ok = link_holes(); | |
481 | if (ok) | |
479 | 482 | ok = refine_layers(); |
480 | 483 | if (ok) |
481 | 484 | ok = instantiate_meas(); |
overlap.c | ||
---|---|---|
1 | 1 | /* |
2 | 2 | * overlap.c - Test for overlaps |
3 | 3 | * |
4 | * Written 2009 by Werner Almesberger | |
5 | * Copyright 2009 by Werner Almesberger | |
4 | * Written 2009, 2010 by Werner Almesberger | |
5 | * Copyright 2009, 2010 by Werner Almesberger | |
6 | 6 | * |
7 | 7 | * This program is free software; you can redistribute it and/or modify |
8 | 8 | * it under the terms of the GNU General Public License as published by |
... | ... | |
11 | 11 | */ |
12 | 12 | |
13 | 13 | |
14 | #include <stdlib.h> | |
15 | ||
14 | 16 | #include "coord.h" |
15 | 17 | #include "obj.h" |
16 | 18 | #include "inst.h" |
... | ... | |
18 | 20 | |
19 | 21 | |
20 | 22 | /* |
21 | * @@@ result may be too optimistic if "b" is arounded pad. | |
23 | * @@@ result may be too optimistic if "b" is a rounded pad | |
22 | 24 | */ |
23 | 25 | |
24 | 26 | int inside(const struct inst *a, const struct inst *b) |
... | ... | |
27 | 29 | struct coord min_b, max_b; |
28 | 30 | |
29 | 31 | min_a = a->base; |
30 | max_a = a->u.pad.other; | |
32 | switch (a->obj->type) { | |
33 | case ot_pad: | |
34 | max_a = a->u.pad.other; | |
35 | break; | |
36 | case ot_hole: | |
37 | max_a = a->u.hole.other; | |
38 | break; | |
39 | default: | |
40 | abort(); | |
41 | } | |
31 | 42 | sort_coord(&min_a, &max_a); |
32 | 43 | |
33 | 44 | min_b = b->base; |
34 | max_b = b->u.pad.other; | |
45 | switch (b->obj->type) { | |
46 | case ot_pad: | |
47 | max_b = b->u.pad.other; | |
48 | break; | |
49 | case ot_hole: | |
50 | max_b = b->u.hole.other; | |
51 | break; | |
52 | default: | |
53 | abort(); | |
54 | } | |
35 | 55 | sort_coord(&min_b, &max_b); |
36 | 56 | |
37 | 57 | return min_a.x >= min_b.x && max_a.x <= max_b.x && |
... | ... | |
142 | 162 | { |
143 | 163 | struct coord min, max; |
144 | 164 | unit_type h, w, r; |
165 | int rounded; | |
145 | 166 | |
146 | 167 | min = a->base; |
147 | max = a->u.pad.other; | |
168 | switch (a->obj->type) { | |
169 | case ot_pad: | |
170 | max = a->u.pad.other; | |
171 | rounded = a->obj->u.pad.rounded; | |
172 | break; | |
173 | case ot_hole: | |
174 | max = a->u.hole.other; | |
175 | rounded = 1; | |
176 | break; | |
177 | default: | |
178 | abort(); | |
179 | } | |
148 | 180 | sort_coord(&min, &max); |
149 | 181 | |
150 | 182 | h = max.y-min.y; |
151 | 183 | w = max.x-min.x; |
152 | 184 | |
153 | if (!a->obj->u.pad.rounded) | |
185 | if (!rounded) | |
154 | 186 | return do_rect(b, other, min.x, min.y, w, h); |
155 | 187 | |
156 | 188 | if (h > w) { |
postscript.c | ||
---|---|---|
64 | 64 | #define PS_HATCH mm_to_units(0.1) |
65 | 65 | #define PS_HATCH_LINE mm_to_units(0.015) |
66 | 66 | |
67 | #define PS_RIM_LINE mm_to_units(0.02) | |
68 | ||
67 | 69 | #define PS_FONT_OUTLINE mm_to_units(0.025) |
68 | 70 | |
69 | 71 | #define PS_VEC_LINE mm_to_units(0.02) |
... | ... | |
220 | 222 | fprintf(file, " closepath gsave %s grestore stroke\n", |
221 | 223 | hatch(inst->u.pad.layers)); |
222 | 224 | |
223 | if (show_name) | |
225 | if (show_name && !inst->u.pad.hole) | |
224 | 226 | ps_pad_name(file, inst); |
225 | 227 | } |
226 | 228 | |
227 | 229 | |
228 | static void ps_rpad(FILE *file, const struct inst *inst, int show_name) | |
230 | static void ps_rounded_rect(FILE *file, struct coord a, struct coord b) | |
229 | 231 | { |
230 | struct coord a = inst->base; | |
231 | struct coord b = inst->u.pad.other; | |
232 | 232 | unit_type h, w, r; |
233 | 233 | |
234 | 234 | sort_coord(&a, &b); |
235 | 235 | h = b.y-a.y; |
236 | 236 | w = b.x-a.x; |
237 | fprintf(file, "0 setgray %d setlinewidth\n", PS_HATCH_LINE); | |
237 | ||
238 | 238 | if (h > w) { |
239 | 239 | r = w/2; |
240 | 240 | fprintf(file, " %d %d moveto\n", b.x, b.y-r); |
... | ... | |
248 | 248 | fprintf(file, " %d %d lineto\n", a.x+r, b.y); |
249 | 249 | fprintf(file, " %d %d %d 90 270 arc\n", a.x+r, a.y+r, r); |
250 | 250 | } |
251 | } | |
252 | ||
253 | ||
254 | static void ps_rpad(FILE *file, const struct inst *inst, int show_name) | |
255 | { | |
256 | fprintf(file, "0 setgray %d setlinewidth\n", PS_HATCH_LINE); | |
257 | ps_rounded_rect(file, inst->base, inst->u.pad.other); | |
251 | 258 | fprintf(file, " closepath gsave %s grestore stroke\n", |
252 | 259 | hatch(inst->u.pad.layers)); |
253 | 260 | |
254 | if (show_name) | |
261 | if (show_name && !inst->u.pad.hole) | |
255 | 262 | ps_pad_name(file, inst); |
256 | 263 | } |
257 | 264 | |
258 | 265 | |
266 | static void ps_hole(FILE *file, const struct inst *inst, int show_name) | |
267 | { | |
268 | fprintf(file, "1 setgray %d setlinewidth\n", PS_RIM_LINE); | |
269 | ps_rounded_rect(file, inst->base, inst->u.hole.other); | |
270 | fprintf(file, " closepath gsave fill grestore\n"); | |
271 | fprintf(file, " 0 setgray stroke\n"); | |
272 | ||
273 | if (show_name && inst->u.hole.pad) | |
274 | ps_pad_name(file, inst->u.hole.pad); | |
275 | } | |
276 | ||
277 | ||
259 | 278 | static void ps_line(FILE *file, const struct inst *inst) |
260 | 279 | { |
261 | 280 | struct coord a = inst->base; |
... | ... | |
485 | 504 | else |
486 | 505 | ps_pad(file, inst, active_params.show_pad_names); |
487 | 506 | break; |
507 | case ip_hole: | |
508 | ps_hole(file, inst, active_params.show_pad_names); | |
509 | break; | |
488 | 510 | case ip_vec: |
489 | 511 | if (active_params.show_stuff) |
490 | 512 | ps_vec(file, inst); |
Branches:
master