Date: | 2010-04-25 17:27:27 (9 years 7 months ago) |
---|---|
Author: | werner |
Commit: | e047cc074dbb55a57c011636447ef75deaca22b7 |
Message: | Holes can now also be output as KiCad modules. - gui_style.c (gc_rim): slightly increased brightness when inactive - kicad.c (kicad_pad): move coordinate transform to new function kicad_centric - kicad.c: added pads with holes and mechanical holes - inst.h (struct inst.u.hole), inst.c (inst_hole): added "layers" field, like for pads - layer.c (LAYER_COPPER, LAYER_PASTE, LAYER_MASK): renamed to LAYER_*_TOP and added macros for corresponding bottom layers - layer.c (refine_layers): mirror top layers of through-hole pads - layer.h, layer.c (mech_hole_layers): return the layer set for mechanical layers git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5941 99fdad57-331a-0410-800a-d7fa5415bdb3 |
Files: |
gui_style.c (1 diff) inst.c (1 diff) inst.h (1 diff) kicad.c (5 diffs) layer.c (7 diffs) layer.h (2 diffs) |
Change Details
gui_style.c | ||
---|---|---|
71 | 71 | style(gc_pad_mask, "#000040", "#0000ff", "#ffff80", 2); |
72 | 72 | style(gc_ptext, "#404040", "#ffffff", "#ffffff", 1); |
73 | 73 | style(gc_hole, "#000000", "#000000", "#000000", 0); |
74 | style(gc_rim, "#202020", "#606060", "#ffff80", 3); | |
74 | style(gc_rim, "#303030", "#606060", "#ffff80", 3); | |
75 | 75 | style(gc_meas, "#280040", "#ff00ff", "#ffff80", 1); |
76 | 76 | style(gc_frame, "#005000", "#009000", "#ffff80", 1); |
77 | 77 |
inst.c | ||
---|---|---|
933 | 933 | inst = add_inst(&hole_ops, ip_hole, a); |
934 | 934 | inst->obj = obj; |
935 | 935 | inst->u.hole.other = b; |
936 | inst->u.pad.layers = mech_hole_layers(); | |
936 | 937 | find_inst(inst); |
937 | 938 | update_bbox(&inst->bbox, b); |
938 | 939 | propagate_bbox(inst); |
inst.h | ||
---|---|---|
102 | 102 | } pad; |
103 | 103 | struct { |
104 | 104 | struct coord other; |
105 | layer_type layers; /* bit-set of layers (mech only) */ | |
105 | 106 | struct inst *pad; /* through-hole pad of NULL */ |
106 | 107 | } hole; |
107 | 108 | struct { |
kicad.c | ||
---|---|---|
1 | 1 | /* |
2 | 2 | * kicad.c - Dump objects in the KiCad board/module format |
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 |
... | ... | |
20 | 20 | #include "kicad.h" |
21 | 21 | |
22 | 22 | |
23 | static void kicad_pad(FILE *file, const struct inst *inst) | |
23 | static unit_type zeroize(unit_type n) | |
24 | { | |
25 | return n == -1 || n == 1 ? 0 : n; | |
26 | } | |
27 | ||
28 | ||
29 | static void kicad_centric(struct coord a, struct coord b, | |
30 | struct coord *center, struct coord *size) | |
24 | 31 | { |
25 | 32 | struct coord min, max; |
26 | 33 | unit_type tmp; |
27 | 34 | |
28 | min.x = units_to_kicad(inst->base.x); | |
29 | min.y = units_to_kicad(inst->base.y); | |
30 | max.x = units_to_kicad(inst->u.pad.other.x); | |
31 | max.y = units_to_kicad(inst->u.pad.other.y); | |
35 | min.x = units_to_kicad(a.x); | |
36 | min.y = units_to_kicad(a.y); | |
37 | max.x = units_to_kicad(b.x); | |
38 | max.y = units_to_kicad(b.y); | |
32 | 39 | |
33 | 40 | if (min.x > max.x) { |
34 | 41 | tmp = min.x; |
... | ... | |
41 | 48 | max.y = tmp; |
42 | 49 | } |
43 | 50 | |
51 | size->x = max.x-min.x; | |
52 | size->y = max.y-min.y; | |
53 | center->x = (min.x+max.x)/2; | |
54 | center->y = -(min.y+max.y)/2; | |
55 | } | |
56 | ||
57 | ||
58 | static void do_drill(FILE *file, const struct inst *pad, struct coord *ref) | |
59 | { | |
60 | const struct inst *hole = pad->u.pad.hole; | |
61 | struct coord center, size; | |
62 | ||
63 | if (!hole) | |
64 | return; | |
65 | ||
66 | kicad_centric(hole->base, hole->u.hole.other, ¢er, &size); | |
67 | ||
68 | /* Allow for rounding errors */ | |
69 | ||
70 | fprintf(file, "Dr %d %d %d", size.x, | |
71 | -zeroize(center.x-ref->x), -zeroize(center.y-ref->y)); | |
72 | if (size.x < size.y-1 || size.x > size.y+1) | |
73 | fprintf(file, " O %d %d", size.x, size.y); | |
74 | fprintf(file, "\n"); | |
75 | *ref = center; | |
76 | } | |
77 | ||
78 | ||
79 | static void kicad_pad(FILE *file, const struct inst *inst) | |
80 | { | |
81 | struct coord center, size; | |
82 | ||
83 | kicad_centric(inst->base, inst->u.pad.other, ¢er, &size); | |
84 | ||
44 | 85 | fprintf(file, "$PAD\n"); |
45 | 86 | |
46 | 87 | /* |
... | ... | |
48 | 89 | */ |
49 | 90 | fprintf(file, "Sh \"%s\" %c %d %d 0 0 0\n", |
50 | 91 | inst->u.pad.name, inst->obj->u.pad.rounded ? 'O' : 'R', |
51 | max.x-min.x, max.y-min.y); | |
92 | size.x, size.y); | |
93 | ||
94 | /* | |
95 | * Drill hole | |
96 | */ | |
97 | do_drill(file, inst, ¢er); | |
52 | 98 | |
53 | 99 | /* |
54 | 100 | * Attributes: pad type, N, layer mask |
55 | 101 | */ |
56 | fprintf(file, "At SMD N %8.8X\n", (unsigned) inst->u.pad.layers); | |
102 | fprintf(file, "At %s N %8.8X\n", | |
103 | inst->u.pad.hole ? "STD" : "SMD", (unsigned) inst->u.pad.layers); | |
57 | 104 | |
58 | 105 | /* |
59 | 106 | * Position: Xpos, Ypos |
60 | 107 | */ |
61 | fprintf(file, "Po %d %d\n", (min.x+max.x)/2, -(min.y+max.y)/2); | |
108 | fprintf(file, "Po %d %d\n", center.x, center.y); | |
109 | ||
110 | fprintf(file, "$EndPAD\n"); | |
111 | } | |
112 | ||
113 | ||
114 | static void kicad_hole(FILE *file, const struct inst *inst) | |
115 | { | |
116 | struct coord center, size; | |
62 | 117 | |
118 | if (inst->u.hole.pad) | |
119 | return; | |
120 | kicad_centric(inst->base, inst->u.hole.other, ¢er, &size); | |
121 | fprintf(file, "$PAD\n"); | |
122 | if (size.x < size.y-1 || size.x > size.y+1) { | |
123 | fprintf(file, "Sh \"HOLE\" O %d %d 0 0 0\n", size.x, size.y); | |
124 | fprintf(file, "Dr %d 0 0 O %d %d\n", size.x, size.x, size.y); | |
125 | } else { | |
126 | fprintf(file, "Sh \"HOLE\" C %d %d 0 0 0\n", size.x, size.x); | |
127 | fprintf(file, "Dr %d 0 0\n", size.x); | |
128 | } | |
129 | fprintf(file, "At HOLE N %8.8X\n", (unsigned) inst->u.hole.layers); | |
130 | fprintf(file, "Po %d %d\n", center.x, center.y); | |
63 | 131 | fprintf(file, "$EndPAD\n"); |
64 | 132 | } |
65 | 133 | |
... | ... | |
152 | 220 | case ip_pad_special: |
153 | 221 | kicad_pad(file, inst); |
154 | 222 | break; |
223 | case ip_hole: | |
224 | kicad_hole(file, inst); | |
225 | break; | |
155 | 226 | case ip_line: |
156 | 227 | kicad_line(file, inst); |
157 | 228 | break; |
layer.c | ||
---|---|---|
1 | 1 | /* |
2 | 2 | * layer.c - PCB layers on a pad |
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 |
... | ... | |
30 | 30 | * Shorthands for the layers we use in a general sense. |
31 | 31 | */ |
32 | 32 | |
33 | #define LAYER_COPPER (1 << layer_top) | |
34 | #define LAYER_PASTE (1 << layer_paste_top) | |
35 | #define LAYER_MASK (1 << layer_mask_top) | |
33 | #define LAYER_COPPER_TOP (1 << layer_top) | |
34 | #define LAYER_PASTE_TOP (1 << layer_paste_top) | |
35 | #define LAYER_MASK_TOP (1 << layer_mask_top) | |
36 | #define LAYER_COPPER_BOTTOM (1 << layer_bottom) | |
37 | #define LAYER_PASTE_BOTTOM (1 << layer_paste_bottom) | |
38 | #define LAYER_MASK_BOTTOM (1 << layer_mask_bottom) | |
36 | 39 | |
37 | 40 | |
38 | 41 | /* ----- Conversion between pad types and layer sets ----------------------- */ |
... | ... | |
44 | 47 | |
45 | 48 | switch (type) { |
46 | 49 | case pt_normal: |
47 | layers = LAYER_PASTE; | |
50 | layers = LAYER_PASTE_TOP; | |
48 | 51 | /* fall through */ |
49 | 52 | case pt_bare: |
50 | layers |= LAYER_COPPER | LAYER_MASK; | |
53 | layers |= LAYER_COPPER_TOP | LAYER_MASK_TOP; | |
51 | 54 | break; |
52 | 55 | case pt_paste: |
53 | layers = LAYER_PASTE; | |
56 | layers = LAYER_PASTE_TOP; | |
54 | 57 | break; |
55 | 58 | case pt_mask: |
56 | layers = LAYER_MASK; | |
59 | layers = LAYER_MASK_TOP; | |
57 | 60 | break; |
58 | 61 | default: |
59 | 62 | abort(); |
... | ... | |
64 | 67 | |
65 | 68 | enum pad_type layers_to_pad_type(layer_type layers) |
66 | 69 | { |
67 | if (layers & LAYER_COPPER) { | |
68 | if (layers & LAYER_PASTE) | |
70 | if (layers & LAYER_COPPER_TOP) { | |
71 | if (layers & LAYER_PASTE_TOP) | |
69 | 72 | return pt_normal; |
70 | 73 | return pt_bare; |
71 | 74 | } else { |
72 | if (layers & LAYER_PASTE) | |
75 | if (layers & LAYER_PASTE_TOP) | |
73 | 76 | return pt_paste; |
74 | if (layers & LAYER_MASK) | |
77 | if (layers & LAYER_MASK_TOP) | |
75 | 78 | return pt_mask; |
76 | 79 | abort(); |
77 | 80 | } |
78 | 81 | } |
79 | 82 | |
80 | 83 | |
84 | /* ----- layers in mechanical holes ---------------------------------------- */ | |
85 | ||
86 | ||
87 | layer_type mech_hole_layers(void) | |
88 | { | |
89 | return LAYER_PASTE_TOP | LAYER_PASTE_BOTTOM | | |
90 | LAYER_MASK_TOP | LAYER_MASK_BOTTOM; | |
91 | } | |
92 | ||
93 | ||
81 | 94 | /* ----- Refine layers after instantiation --------------------------------- */ |
82 | 95 | |
83 | 96 | |
84 | 97 | static int refine_overlapping(struct inst *copper, struct inst *other) |
85 | 98 | { |
86 | if (other->u.pad.layers & LAYER_PASTE) { | |
87 | copper->u.pad.layers &= ~LAYER_PASTE; | |
99 | if (other->u.pad.layers & LAYER_PASTE_TOP) { | |
100 | copper->u.pad.layers &= ~LAYER_PASTE_TOP; | |
88 | 101 | if (!inside(other, copper)) { |
89 | 102 | fail("solder paste without copper underneath " |
90 | 103 | "(\"%s\" line %d, \"%s\" line %d)", |
... | ... | |
94 | 107 | return 0; |
95 | 108 | } |
96 | 109 | } |
97 | if (other->u.pad.layers & LAYER_MASK) | |
98 | copper->u.pad.layers &= ~LAYER_MASK; | |
110 | if (other->u.pad.layers & LAYER_MASK_TOP) | |
111 | copper->u.pad.layers &= ~LAYER_MASK_TOP; | |
99 | 112 | return 1; |
100 | 113 | } |
101 | 114 | |
... | ... | |
131 | 144 | } |
132 | 145 | |
133 | 146 | |
147 | static void mirror_layers(layer_type *layers) | |
148 | { | |
149 | if (*layers & LAYER_COPPER_TOP) | |
150 | *layers |= LAYER_COPPER_BOTTOM; | |
151 | if (*layers & LAYER_PASTE_TOP) | |
152 | *layers |= LAYER_PASTE_BOTTOM; | |
153 | if (*layers & LAYER_MASK_TOP) | |
154 | *layers |= LAYER_MASK_BOTTOM; | |
155 | } | |
156 | ||
157 | ||
134 | 158 | int refine_layers(void) |
135 | 159 | { |
136 | 160 | const struct pkg *pkg; |
... | ... | |
138 | 162 | |
139 | 163 | for (pkg = pkgs; pkg; pkg = pkg->next) |
140 | 164 | for (copper = pkg->insts[ip_pad_copper]; copper; |
141 | copper = copper->next) | |
165 | copper = copper->next) { | |
142 | 166 | if (!refine_copper(pkg, copper)) |
143 | 167 | return 0; |
168 | if (copper->u.pad.hole) | |
169 | mirror_layers(&copper->u.pad.layers); | |
170 | } | |
144 | 171 | return 1; |
145 | 172 | } |
layer.h | ||
---|---|---|
1 | 1 | /* |
2 | 2 | * layer.h - PCB layers on a pad |
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 |
... | ... | |
73 | 73 | layer_type pad_type_to_layers(enum pad_type type); |
74 | 74 | enum pad_type layers_to_pad_type(layer_type layers); |
75 | 75 | |
76 | layer_type mech_hole_layers(void); | |
77 | ||
76 | 78 | int refine_layers(void); |
77 | 79 | |
78 | 80 | #endif /* !LAYER_H */ |
Branches:
master