Root/
Source at commit a3b3ed4925927211fbb2a114cf183678bfc30346 created 13 years 5 months ago. By Xiangfu Liu, use the new version rules. | |
---|---|
1 | /* |
2 | * layer.c - PCB layers on a pad |
3 | * |
4 | * Written 2009, 2010 by Werner Almesberger |
5 | * Copyright 2009, 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 | * We don't reject solder paste pads that don't cover anything yet. |
15 | * That way, things can be constructed step by step without getting blue |
16 | * screens all the time. |
17 | */ |
18 | |
19 | |
20 | #include <stdlib.h> |
21 | |
22 | #include "error.h" |
23 | #include "overlap.h" |
24 | #include "inst.h" |
25 | #include "obj.h" |
26 | #include "layer.h" |
27 | |
28 | |
29 | /* |
30 | * Shorthands for the layers we use in a general sense. |
31 | */ |
32 | |
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) |
39 | |
40 | |
41 | /* ----- Conversion between pad types and layer sets ----------------------- */ |
42 | |
43 | |
44 | layer_type pad_type_to_layers(enum pad_type type) |
45 | { |
46 | layer_type layers = 0; |
47 | |
48 | switch (type) { |
49 | case pt_normal: |
50 | layers = LAYER_PASTE_TOP; |
51 | /* fall through */ |
52 | case pt_bare: |
53 | layers |= LAYER_COPPER_TOP | LAYER_MASK_TOP; |
54 | break; |
55 | case pt_paste: |
56 | layers = LAYER_PASTE_TOP; |
57 | break; |
58 | case pt_mask: |
59 | layers = LAYER_MASK_TOP; |
60 | break; |
61 | default: |
62 | abort(); |
63 | } |
64 | return layers; |
65 | } |
66 | |
67 | |
68 | enum pad_type layers_to_pad_type(layer_type layers) |
69 | { |
70 | if (layers & LAYER_COPPER_TOP) { |
71 | if (layers & LAYER_PASTE_TOP) |
72 | return pt_normal; |
73 | return pt_bare; |
74 | } else { |
75 | if (layers & LAYER_PASTE_TOP) |
76 | return pt_paste; |
77 | if (layers & LAYER_MASK_TOP) |
78 | return pt_mask; |
79 | abort(); |
80 | } |
81 | } |
82 | |
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 | |
94 | /* ----- Refine layers after instantiation --------------------------------- */ |
95 | |
96 | |
97 | static int refine_overlapping(struct inst *copper, struct inst *other) |
98 | { |
99 | if (other->u.pad.layers & LAYER_PASTE_TOP) { |
100 | copper->u.pad.layers &= ~LAYER_PASTE_TOP; |
101 | if (!inside(other, copper)) { |
102 | fail("solder paste without copper underneath " |
103 | "(\"%s\" line %d, \"%s\" line %d)", |
104 | copper->u.pad.name, copper->obj->lineno, |
105 | other->u.pad.name, other->obj->lineno); |
106 | instantiation_error = other->obj; |
107 | return 0; |
108 | } |
109 | } |
110 | if (other->u.pad.layers & LAYER_MASK_TOP) |
111 | copper->u.pad.layers &= ~LAYER_MASK_TOP; |
112 | return 1; |
113 | } |
114 | |
115 | |
116 | static int refine_copper(const struct pkg *pkg_copper, struct inst *copper, |
117 | enum allow_overlap allow) |
118 | { |
119 | const struct pkg *pkg; |
120 | struct inst *other; |
121 | |
122 | for (pkg = pkgs; pkg; pkg = pkg->next) { |
123 | /* |
124 | * Pads in distinct packages can happily coexist. |
125 | */ |
126 | if (pkg != pkgs && pkg_copper != pkgs && pkg_copper != pkg) |
127 | continue; |
128 | for (other = pkg->insts[ip_pad_copper]; other; |
129 | other = other->next) |
130 | if (copper != other && overlap(copper, other, allow)) { |
131 | fail("overlapping copper pads " |
132 | "(\"%s\" line %d, \"%s\" line %d)", |
133 | copper->u.pad.name, copper->obj->lineno, |
134 | other->u.pad.name, other->obj->lineno); |
135 | instantiation_error = copper->obj; |
136 | return 0; |
137 | } |
138 | for (other = pkg->insts[ip_pad_special]; other; |
139 | other = other->next) |
140 | if (overlap(copper, other, ao_none)) |
141 | if (!refine_overlapping(copper, other)) |
142 | return 0; |
143 | } |
144 | return 1; |
145 | } |
146 | |
147 | |
148 | static void mirror_layers(layer_type *layers) |
149 | { |
150 | if (*layers & LAYER_COPPER_TOP) |
151 | *layers |= LAYER_COPPER_BOTTOM; |
152 | if (*layers & LAYER_PASTE_TOP) |
153 | *layers |= LAYER_PASTE_BOTTOM; |
154 | if (*layers & LAYER_MASK_TOP) |
155 | *layers |= LAYER_MASK_BOTTOM; |
156 | } |
157 | |
158 | |
159 | int refine_layers(enum allow_overlap allow) |
160 | { |
161 | const struct pkg *pkg; |
162 | struct inst *copper; |
163 | |
164 | for (pkg = pkgs; pkg; pkg = pkg->next) |
165 | for (copper = pkg->insts[ip_pad_copper]; copper; |
166 | copper = copper->next) { |
167 | if (!refine_copper(pkg, copper, allow)) |
168 | return 0; |
169 | if (copper->u.pad.hole) |
170 | mirror_layers(&copper->u.pad.layers); |
171 | } |
172 | return 1; |
173 | } |
174 |
Branches:
master