├── .gitignore
├── README.md
├── cam
├── README.md
├── STENCILcam-GTP_GBP_ONLY.cam
├── sfe-gerb274x-2layer.cam
├── sfe-gerb274x-4layer.cam
└── sfe-gerb274x-6layer.cam
├── dru
├── Old
│ ├── SparkFun-2-layer-ALC.dru
│ ├── SparkFun-2-layer-FAB-LIMIT.dru
│ ├── SparkFun-2-layer-PCBWay-LIMIT.dru
│ ├── SparkFun-2-layer-STANDARD.dru
│ ├── SparkFun-2-layer-TIGHT.dru
│ ├── SparkFun-4-layer-BGA-Extreme.dru
│ ├── SparkFun-4-layer-FAB-LIMIT.dru
│ ├── SparkFun-4-layer-MicroMod.dru
│ ├── SparkFun-4-layer-PCBWAY-LIMIT.dru
│ └── SparkFun-4-layer-TIGHT.dru
├── README.md
├── SparkFun-2-Layer-General-JLCPCB.dru
├── SparkFun-2-Layer-Minimum-JLCPCB.dru
├── SparkFun-4-Layer-General-JLCPCB.dru
├── SparkFun-4-Layer-MicroMod-JLCPCB.dru
├── SparkFun-4-Layer-Minimum-Blind-Vias-PCBWay.dru
├── SparkFun-4-Layer-Minimum-JLCPCB.dru
└── SparkFun-6-Layer-Minimum-JLCPCB.dru
├── scr
└── eagle.scr
└── ulp
├── 7za.exe
├── Include_String.ulp
├── SparkFun-BOM_Generator.flt
├── SparkFun-BOM_Generator.ulp
├── SparkFun-CAMmer-linux.ulp
├── SparkFun-CAMmer.ulp
├── SparkFun-Flip.ulp
├── SparkFun-Panelizer.ulp
├── SparkFun-PartCreator.ulp
├── SparkFunConfig.ulp
├── Trace-Length.ulp
├── Unrouted.ulp
├── add+mod-attributes.ulp
├── adimv4_0mm.ulp
├── autodim_in.ulp
├── autodim_mil.ulp
├── board_default.ulp
├── bom_with_library.ulp
├── drill-exactsize.ulp
├── eagleUp_export.ulp
├── eagle_to_3d.ulp
├── eagle_to_3d_3_4.ulp
├── exp-lbrs.ulp
├── exp-project-lbr.ulp
├── gerbv.exe
├── help-images
├── PartCreator-Axis-Indicators.bmp
├── PartCreator-Center-Pad.bmp
├── PartCreator-Pad-Distances.bmp
└── PartCreator-Pin-Size.bmp
├── import-bmp.ulp
├── import-gerber.ulp
├── mirror-board.ulp
├── oshw-logo.ulp
├── readme.md
├── set-all-devices-attribute.ulp
└── z_Include_SF_BOM.ulp
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## SparkFun Useful stuff
3 | #################
4 |
5 | ## AVR Development
6 | *.eep
7 | *.elf
8 | *.lst
9 | *.lss
10 | *.sym
11 | *.d
12 | *.o
13 | *.srec
14 | *.map
15 |
16 | ## Notepad++ backup files
17 | *.bak
18 |
19 | ## BOM files
20 | #*bom*
21 |
22 | ## Configure files from ULPs
23 | *.cfg
24 |
25 | ## Script files generated from ULPs in ULP directory
26 | ulp/*.scr
27 |
28 | ## VScode files
29 | .vscode/*
30 |
31 | #################
32 | ## Eclipse
33 | #################
34 |
35 | *.pydevproject
36 | .project
37 | .metadata
38 | bin/
39 | tmp/
40 | *.tmp
41 | *.bak
42 | *.swp
43 | *~.nib
44 | local.properties
45 | .classpath
46 | .settings/
47 | .loadpath
48 |
49 | # External tool builders
50 | .externalToolBuilders/
51 |
52 | # Locally stored "Eclipse launch configurations"
53 | *.launch
54 |
55 | # CDT-specific
56 | .cproject
57 |
58 | # PDT-specific
59 | .buildpath
60 |
61 |
62 | #############
63 | ## Eagle
64 | #############
65 |
66 | # Ignore the board and schematic backup files
67 | *.b#?
68 | *.s#?
69 |
70 |
71 | #################
72 | ## Visual Studio
73 | #################
74 |
75 | ## Ignore Visual Studio temporary files, build results, and
76 | ## files generated by popular Visual Studio add-ons.
77 |
78 | # User-specific files
79 | *.suo
80 | *.user
81 | *.sln.docstates
82 |
83 | # Build results
84 | [Dd]ebug/
85 | [Rr]elease/
86 | *_i.c
87 | *_p.c
88 | *.ilk
89 | *.meta
90 | *.obj
91 | *.pch
92 | *.pdb
93 | *.pgc
94 | *.pgd
95 | *.rsp
96 | *.sbr
97 | *.tlb
98 | *.tli
99 | *.tlh
100 | *.tmp
101 | *.vspscc
102 | .builds
103 | *.dotCover
104 |
105 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
106 | #packages/
107 |
108 | # Visual C++ cache files
109 | ipch/
110 | *.aps
111 | *.ncb
112 | *.opensdf
113 | *.sdf
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 |
119 | # ReSharper is a .NET coding add-in
120 | _ReSharper*
121 |
122 | # Installshield output folder
123 | [Ee]xpress
124 |
125 | # DocProject is a documentation generator add-in
126 | DocProject/buildhelp/
127 | DocProject/Help/*.HxT
128 | DocProject/Help/*.HxC
129 | DocProject/Help/*.hhc
130 | DocProject/Help/*.hhk
131 | DocProject/Help/*.hhp
132 | DocProject/Help/Html2
133 | DocProject/Help/html
134 |
135 | # Click-Once directory
136 | publish
137 |
138 | # Others
139 | [Bb]in
140 | [Oo]bj
141 | sql
142 | TestResults
143 | *.Cache
144 | ClientBin
145 | stylecop.*
146 | ~$*
147 | *.dbmdl
148 | Generated_Code #added for RIA/Silverlight projects
149 |
150 | # Backup & report files from converting an old project file to a newer
151 | # Visual Studio version. Backup files are not needed, because we have git ;-)
152 | _UpgradeReport_Files/
153 | Backup*/
154 | UpgradeLog*.XML
155 |
156 |
157 | ############
158 | ## Windows
159 | ############
160 |
161 | # Windows image file caches
162 | Thumbs.db
163 |
164 | # Folder config file
165 | Desktop.ini
166 |
167 |
168 | #############
169 | ## Python
170 | #############
171 |
172 | *.py[co]
173 |
174 | # Packages
175 | *.egg
176 | *.egg-info
177 | dist
178 | build
179 | eggs
180 | parts
181 | bin
182 | var
183 | sdist
184 | develop-eggs
185 | .installed.cfg
186 |
187 | # Installer logs
188 | pip-log.txt
189 |
190 | # Unit test / coverage reports
191 | .coverage
192 | .tox
193 |
194 | #Translations
195 | *.mo
196 |
197 | #Mr Developer
198 | .mr.developer.cfg
199 |
200 | # Mac crap
201 | .DS_Store
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SparkFun Eagle Settings
2 | =======================
3 | These are the commonly used keyboard shortcuts, CAM and DRU configuration files for SparkFun board design. We use these files at SparkFun for all our design work.
4 |
5 | For more information about using Eagle to make a PCB see these tutorials:
6 |
7 | * [How to Install and Setup EAGLE](https://learn.sparkfun.com/tutorials/how-to-install-and-setup-eagle)
8 | * [Using EAGLE: Board Layout](https://learn.sparkfun.com/tutorials/using-eagle-board-layout)
9 | * [Using EAGLE: Schematic](https://learn.sparkfun.com/tutorials/using-eagle-schematic)
10 |
11 | Be sure to checkout [SparkFun's footprints for Eagle](https://github.com/sparkfun/SparkFun-Eagle-Libraries).
12 |
13 | Repository Contents
14 | -------------------
15 | * **/cam** - Job files to output your 2 and 4 layer designs to [Gerber](http://en.wikipedia.org/wiki/Gerber_format) files
16 | * **/dru** - Design rules for 2 and 4 layer designs
17 | * **/scr** - Scripts for assigning keyboard shortcuts, grid sizes and layer colors
18 | * **/ulp** - Commonly used user language programs for BOM generation and library export
19 |
20 |
--------------------------------------------------------------------------------
/cam/README.md:
--------------------------------------------------------------------------------
1 | CAM files
2 | =======================
3 | The cam files allow you to define which layers are assigned to each gerber file.
4 | For example, the gerber file GTL (Gerber Top Layer) usually is defined as layer 1 (or top copper).
5 | If you are using the 4-layer cam, make sure your middle layers are properly assigned.
6 |
--------------------------------------------------------------------------------
/cam/STENCILcam-GTP_GBP_ONLY.cam:
--------------------------------------------------------------------------------
1 | [CAM Processor Job]
2 | Description[en]="Generates Extended Gerber Format
\nThis CAM job consists of five sections that generate data for a two layer board.
\nYou will get five gerber files that contain data for:
\ncomponent side *.cmp
\nsolder side *.sol
\nsilkscreen component side *.plc
\nsolder stop component side *.stc
\nsolder stop solder sid *.sts
"
3 | Section=Sec_1
4 | Section=Sec_2
5 |
6 | [Sec_1]
7 | Name[en]="Top Paste"
8 | Prompt=""
9 | Device="GERBER_RS274X"
10 | Wheel=".whl"
11 | Rack=""
12 | Scale=1
13 | Output=".GTP"
14 | Flags="0 0 0 1 0 1 1"
15 | Emulate="0"
16 | Offset="0.0mil 0.0mil"
17 | Sheet=1
18 | Tolerance="0 0 0 0 0 0"
19 | Pen="0.0mil 0"
20 | Page="12000.0mil 8000.0mil"
21 | Layers=" 31"
22 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
23 |
24 | [Sec_2]
25 | Name[en]="Bottom Paste"
26 | Prompt=""
27 | Device="GERBER_RS274X"
28 | Wheel=".whl"
29 | Rack=""
30 | Scale=1
31 | Output=".GBP"
32 | Flags="0 0 0 1 0 1 1"
33 | Emulate="0"
34 | Offset="0.0mil 0.0mil"
35 | Sheet=1
36 | Tolerance="0 0 0 0 0 0"
37 | Pen="0.0mil 0"
38 | Page="12000.0mil 8000.0mil"
39 | Layers=" 32"
40 | Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
41 |
--------------------------------------------------------------------------------
/cam/sfe-gerb274x-2layer.cam:
--------------------------------------------------------------------------------
1 | {
2 | "author": {
3 | "email": "nathan@sparkfun.com",
4 | "name": "Nathan Seidle"
5 | },
6 | "description": {
7 | "EN": "SparkFun 2 layer CAM job. Compatible with EAGLE v8+ new CAM processor. Use with the SparkFun-CAMMER.ulp to automatically process, zip, and preview gerber output in one button click!"
8 | },
9 | "output_type": "directory",
10 | "outputs": [
11 | {
12 | "filename_prefix": "CAMOutputs/GerberFiles",
13 | "format_specifier": {
14 | "decimal": 4,
15 | "integer": 3
16 | },
17 | "generate_job_file": false,
18 | "output_type": "gerber",
19 | "outputs": [
20 | {
21 | "advanced_options": {
22 | "mirror": false,
23 | "offset_x": 0,
24 | "offset_y": 0,
25 | "rotate": false,
26 | "upside_down": false
27 | },
28 | "board_outline": false,
29 | "config": {
30 | "file_function": "Copper",
31 | "layer": 1,
32 | "layer_details": "mixed",
33 | "layer_type": "top"
34 | },
35 | "filename_format": "%N.GTL",
36 | "layers": [
37 | 1,
38 | 17,
39 | 18
40 | ],
41 | "name": "Top Copper",
42 | "polarity": "positive",
43 | "type": "gerber_layer"
44 | },
45 | {
46 | "advanced_options": {
47 | "mirror": false,
48 | "offset_x": 0,
49 | "offset_y": 0,
50 | "rotate": false,
51 | "upside_down": false
52 | },
53 | "board_outline": false,
54 | "config": {
55 | "file_function": "Copper",
56 | "layer": 2,
57 | "layer_details": "mixed",
58 | "layer_type": "bottom"
59 | },
60 | "filename_format": "%N.GBL",
61 | "layers": [
62 | 16,
63 | 17,
64 | 18
65 | ],
66 | "name": "Bottom Copper",
67 | "polarity": "positive",
68 | "type": "gerber_layer"
69 | },
70 | {
71 | "advanced_options": {
72 | "mirror": false,
73 | "offset_x": 0,
74 | "offset_y": 0,
75 | "rotate": false,
76 | "upside_down": false
77 | },
78 | "board_outline": true,
79 | "config": {
80 | "file_function": "Profile",
81 | "plating": "non-plated"
82 | },
83 | "filename_format": "%N.GKO",
84 | "layers": [
85 | 20,
86 | 46
87 | ],
88 | "milling": true,
89 | "polarity": "positive",
90 | "type": "gerber_layer"
91 | },
92 | {
93 | "advanced_options": {
94 | "mirror": false,
95 | "offset_x": 0,
96 | "offset_y": 0,
97 | "rotate": false,
98 | "upside_down": false
99 | },
100 | "board_outline": false,
101 | "config": {
102 | "file_function": "Soldermask",
103 | "index": 1,
104 | "layer_type": "top"
105 | },
106 | "filename_format": "%N.GTS",
107 | "layers": [
108 | 29
109 | ],
110 | "name": "Soldermask Top",
111 | "polarity": "positive",
112 | "type": "gerber_layer"
113 | },
114 | {
115 | "advanced_options": {
116 | "mirror": false,
117 | "offset_x": 0,
118 | "offset_y": 0,
119 | "rotate": false,
120 | "upside_down": false
121 | },
122 | "board_outline": false,
123 | "config": {
124 | "file_function": "Soldermask",
125 | "index": 1,
126 | "layer_type": "bottom"
127 | },
128 | "filename_format": "%N.GBS",
129 | "layers": [
130 | 30
131 | ],
132 | "name": "Soldermask Bottom",
133 | "polarity": "positive",
134 | "type": "gerber_layer"
135 | },
136 | {
137 | "advanced_options": {
138 | "mirror": false,
139 | "offset_x": 0,
140 | "offset_y": 0,
141 | "rotate": false,
142 | "upside_down": false
143 | },
144 | "board_outline": false,
145 | "config": {
146 | "file_function": "Paste",
147 | "layer_type": "top"
148 | },
149 | "filename_format": "%N.GTP",
150 | "layers": [
151 | 31
152 | ],
153 | "milling": false,
154 | "name": "Solderpaste Top",
155 | "polarity": "positive",
156 | "type": "gerber_layer"
157 | },
158 | {
159 | "advanced_options": {
160 | "mirror": false,
161 | "offset_x": 0,
162 | "offset_y": 0,
163 | "rotate": false,
164 | "upside_down": false
165 | },
166 | "board_outline": false,
167 | "config": {
168 | "file_function": "Paste",
169 | "layer_type": "bottom"
170 | },
171 | "filename_format": "%N.GBP",
172 | "layers": [
173 | 32
174 | ],
175 | "milling": false,
176 | "name": "Solderpaste Bottom",
177 | "polarity": "positive",
178 | "type": "gerber_layer"
179 | },
180 | {
181 | "advanced_options": {
182 | "mirror": false,
183 | "offset_x": 0,
184 | "offset_y": 0,
185 | "rotate": false,
186 | "upside_down": false
187 | },
188 | "board_outline": false,
189 | "config": {
190 | "file_function": "Legend",
191 | "index": 1,
192 | "layer_type": "top"
193 | },
194 | "filename_format": "%N.GTO",
195 | "layers": [
196 | 21
197 | ],
198 | "milling": false,
199 | "name": "Silkscreen Top",
200 | "polarity": "positive",
201 | "type": "gerber_layer"
202 | },
203 | {
204 | "advanced_options": {
205 | "mirror": false,
206 | "offset_x": 0,
207 | "offset_y": 0,
208 | "rotate": false,
209 | "upside_down": false
210 | },
211 | "board_outline": false,
212 | "config": {
213 | "file_function": "Legend",
214 | "index": 1,
215 | "layer_type": "bottom"
216 | },
217 | "filename_format": "%N.GBO",
218 | "layers": [
219 | 22
220 | ],
221 | "milling": false,
222 | "name": "Silkscreen Bottom",
223 | "polarity": "positive",
224 | "type": "gerber_layer"
225 | }
226 | ],
227 | "version": "RS274X"
228 | },
229 | {
230 | "filename_prefix": "CAMOutputs/DrillFiles",
231 | "format_specifier": {
232 | "decimal": 3,
233 | "integer": 3
234 | },
235 | "output_type": "drill",
236 | "outputs": [
237 | {
238 | "advanced_options": {
239 | "mirror": false,
240 | "offset_x": 0,
241 | "offset_y": 0,
242 | "rotate": false,
243 | "upside_down": false
244 | },
245 | "filename_format": "%N.TXT",
246 | "name": "Auto Drill",
247 | "type": "autodrills"
248 | }
249 | ]
250 | },
251 | {
252 | "filename_prefix": "CAMOutputs/Assembly",
253 | "output_type": "assembly",
254 | "outputs": [
255 | ]
256 | },
257 | {
258 | "filename_prefix": "CAMOutputs/DrawingFiles",
259 | "output_type": "drawing",
260 | "outputs": [
261 | ]
262 | }
263 | ],
264 | "timestamp": "2020-02-11T15:05:12",
265 | "type": "EAGLE CAM job",
266 | "units": "metric",
267 | "version": "9.2.0"
268 | }
269 |
--------------------------------------------------------------------------------
/cam/sfe-gerb274x-4layer.cam:
--------------------------------------------------------------------------------
1 | {
2 | "author": {
3 | "email": "nathan@sparkfun.com",
4 | "name": "Nathan Seidle"
5 | },
6 | "description": {
7 | "EN": "SparkFun 4 layer CAM job. Compatible with EAGLE v8+ new CAM processor. Use with the SparkFun-CAMMER.ulp to automatically process, zip, and preview gerber output in one button click!"
8 | },
9 | "output_type": "directory",
10 | "outputs": [
11 | {
12 | "filename_prefix": "CAMOutputs/GerberFiles",
13 | "format_specifier": {
14 | "decimal": 4,
15 | "integer": 3
16 | },
17 | "generate_job_file": false,
18 | "output_type": "gerber",
19 | "outputs": [
20 | {
21 | "advanced_options": {
22 | "mirror": false,
23 | "offset_x": 0,
24 | "offset_y": 0,
25 | "rotate": false,
26 | "upside_down": false
27 | },
28 | "board_outline": false,
29 | "config": {
30 | "file_function": "Copper",
31 | "layer": 1,
32 | "layer_details": "mixed",
33 | "layer_type": "top"
34 | },
35 | "filename_format": "%N.GTL",
36 | "layers": [
37 | 1,
38 | 17,
39 | 18
40 | ],
41 | "name": "Top Copper",
42 | "polarity": "positive",
43 | "type": "gerber_layer"
44 | },
45 | {
46 | "advanced_options": {
47 | "mirror": false,
48 | "offset_x": 0,
49 | "offset_y": 0,
50 | "rotate": false,
51 | "upside_down": false
52 | },
53 | "board_outline": false,
54 | "config": {
55 | "file_function": "Copper",
56 | "layer": 2,
57 | "layer_details": "mixed",
58 | "layer_type": "Inner"
59 | },
60 | "filename_format": "%N.GL2",
61 | "layers": [
62 | 17,
63 | 18,
64 | 2
65 | ],
66 | "name": "Inner Layer 2",
67 | "polarity": "positive",
68 | "type": "gerber_layer"
69 | },
70 | {
71 | "advanced_options": {
72 | "mirror": false,
73 | "offset_x": 0,
74 | "offset_y": 0,
75 | "rotate": false,
76 | "upside_down": false
77 | },
78 | "board_outline": false,
79 | "config": {
80 | "file_function": "Copper",
81 | "layer": 3,
82 | "layer_details": "mixed",
83 | "layer_type": "Inner"
84 | },
85 | "filename_format": "%N.GL3",
86 | "layers": [
87 | 17,
88 | 18,
89 | 15
90 | ],
91 | "name": "Inner Layer 15",
92 | "polarity": "positive",
93 | "type": "gerber_layer"
94 | },
95 | {
96 | "advanced_options": {
97 | "mirror": false,
98 | "offset_x": 0,
99 | "offset_y": 0,
100 | "rotate": false,
101 | "upside_down": false
102 | },
103 | "board_outline": false,
104 | "config": {
105 | "file_function": "Copper",
106 | "layer": 4,
107 | "layer_details": "mixed",
108 | "layer_type": "bottom"
109 | },
110 | "filename_format": "%N.GBL",
111 | "layers": [
112 | 16,
113 | 17,
114 | 18
115 | ],
116 | "name": "Bottom Copper",
117 | "polarity": "positive",
118 | "type": "gerber_layer"
119 | },
120 | {
121 | "advanced_options": {
122 | "mirror": false,
123 | "offset_x": 0,
124 | "offset_y": 0,
125 | "rotate": false,
126 | "upside_down": false
127 | },
128 | "board_outline": true,
129 | "config": {
130 | "file_function": "Profile",
131 | "plating": "non-plated"
132 | },
133 | "filename_format": "%N.GKO",
134 | "layers": [
135 | 20,
136 | 46
137 | ],
138 | "milling": true,
139 | "polarity": "positive",
140 | "type": "gerber_layer"
141 | },
142 | {
143 | "advanced_options": {
144 | "mirror": false,
145 | "offset_x": 0,
146 | "offset_y": 0,
147 | "rotate": false,
148 | "upside_down": false
149 | },
150 | "board_outline": false,
151 | "config": {
152 | "file_function": "Soldermask",
153 | "index": 1,
154 | "layer_type": "top"
155 | },
156 | "filename_format": "%N.GTS",
157 | "layers": [
158 | 29
159 | ],
160 | "name": "Soldermask Top",
161 | "polarity": "positive",
162 | "type": "gerber_layer"
163 | },
164 | {
165 | "advanced_options": {
166 | "mirror": false,
167 | "offset_x": 0,
168 | "offset_y": 0,
169 | "rotate": false,
170 | "upside_down": false
171 | },
172 | "board_outline": false,
173 | "config": {
174 | "file_function": "Soldermask",
175 | "index": 1,
176 | "layer_type": "bottom"
177 | },
178 | "filename_format": "%N.GBS",
179 | "layers": [
180 | 30
181 | ],
182 | "name": "Soldermask Bottom",
183 | "polarity": "positive",
184 | "type": "gerber_layer"
185 | },
186 | {
187 | "advanced_options": {
188 | "mirror": false,
189 | "offset_x": 0,
190 | "offset_y": 0,
191 | "rotate": false,
192 | "upside_down": false
193 | },
194 | "board_outline": false,
195 | "config": {
196 | "file_function": "Paste",
197 | "layer_type": "top"
198 | },
199 | "filename_format": "%N.GTP",
200 | "layers": [
201 | 31
202 | ],
203 | "milling": false,
204 | "name": "Solderpaste Top",
205 | "polarity": "positive",
206 | "type": "gerber_layer"
207 | },
208 | {
209 | "advanced_options": {
210 | "mirror": false,
211 | "offset_x": 0,
212 | "offset_y": 0,
213 | "rotate": false,
214 | "upside_down": false
215 | },
216 | "board_outline": false,
217 | "config": {
218 | "file_function": "Paste",
219 | "layer_type": "bottom"
220 | },
221 | "filename_format": "%N.GBP",
222 | "layers": [
223 | 32
224 | ],
225 | "milling": false,
226 | "name": "Solderpaste Bottom",
227 | "polarity": "positive",
228 | "type": "gerber_layer"
229 | },
230 | {
231 | "advanced_options": {
232 | "mirror": false,
233 | "offset_x": 0,
234 | "offset_y": 0,
235 | "rotate": false,
236 | "upside_down": false
237 | },
238 | "board_outline": false,
239 | "config": {
240 | "file_function": "Legend",
241 | "index": 1,
242 | "layer_type": "top"
243 | },
244 | "filename_format": "%N.GTO",
245 | "layers": [
246 | 21
247 | ],
248 | "milling": false,
249 | "name": "Silkscreen Top",
250 | "polarity": "positive",
251 | "type": "gerber_layer"
252 | },
253 | {
254 | "advanced_options": {
255 | "mirror": false,
256 | "offset_x": 0,
257 | "offset_y": 0,
258 | "rotate": false,
259 | "upside_down": false
260 | },
261 | "board_outline": false,
262 | "config": {
263 | "file_function": "Legend",
264 | "index": 1,
265 | "layer_type": "bottom"
266 | },
267 | "filename_format": "%N.GBO",
268 | "layers": [
269 | 22
270 | ],
271 | "milling": false,
272 | "name": "Silkscreen Bottom",
273 | "polarity": "positive",
274 | "type": "gerber_layer"
275 | }
276 | ],
277 | "version": "RS274X"
278 | },
279 | {
280 | "filename_prefix": "CAMOutputs/DrillFiles",
281 | "format_specifier": {
282 | "decimal": 3,
283 | "integer": 3
284 | },
285 | "output_type": "drill",
286 | "outputs": [
287 | {
288 | "advanced_options": {
289 | "mirror": false,
290 | "offset_x": 0,
291 | "offset_y": 0,
292 | "rotate": false,
293 | "upside_down": false
294 | },
295 | "filename_format": "%N.TXT",
296 | "name": "Auto Drill",
297 | "type": "autodrills"
298 | }
299 | ]
300 | },
301 | {
302 | "filename_prefix": "CAMOutputs/Assembly",
303 | "output_type": "assembly",
304 | "outputs": [
305 | ]
306 | },
307 | {
308 | "filename_prefix": "CAMOutputs/DrawingFiles",
309 | "output_type": "drawing",
310 | "outputs": [
311 | ]
312 | }
313 | ],
314 | "timestamp": "2020-02-11T15:27:02",
315 | "type": "EAGLE CAM job",
316 | "units": "metric",
317 | "version": "9.2.0"
318 | }
319 |
--------------------------------------------------------------------------------
/cam/sfe-gerb274x-6layer.cam:
--------------------------------------------------------------------------------
1 | {
2 | "author": {
3 | "email": "nathan@sparkfun.com",
4 | "name": "Nathan Seidle"
5 | },
6 | "description": {
7 | "EN": "SparkFun 6 layer CAM job. Compatible with EAGLE v8+ new CAM processor. Use with the SparkFun-CAMMER.ulp to automatically process, zip, and preview gerber output in one button click!"
8 | },
9 | "output_type": "directory",
10 | "outputs": [
11 | {
12 | "filename_prefix": "CAMOutputs/GerberFiles",
13 | "format_specifier": {
14 | "decimal": 4,
15 | "integer": 3
16 | },
17 | "generate_job_file": false,
18 | "output_type": "gerber",
19 | "outputs": [
20 | {
21 | "advanced_options": {
22 | "mirror": false,
23 | "offset_x": 0,
24 | "offset_y": 0,
25 | "rotate": false,
26 | "upside_down": false
27 | },
28 | "board_outline": false,
29 | "config": {
30 | "file_function": "Copper",
31 | "layer": 1,
32 | "layer_details": "mixed",
33 | "layer_type": "top"
34 | },
35 | "filename_format": "%N.GTL",
36 | "layers": [
37 | 1,
38 | 17,
39 | 18
40 | ],
41 | "name": "Top Copper",
42 | "polarity": "positive",
43 | "type": "gerber_layer"
44 | },
45 | {
46 | "advanced_options": {
47 | "mirror": false,
48 | "offset_x": 0,
49 | "offset_y": 0,
50 | "rotate": false,
51 | "upside_down": false
52 | },
53 | "board_outline": false,
54 | "config": {
55 | "file_function": "Copper",
56 | "layer": 2,
57 | "layer_details": "mixed",
58 | "layer_type": "Inner"
59 | },
60 | "filename_format": "%N.GL2",
61 | "layers": [
62 | 17,
63 | 18,
64 | 2
65 | ],
66 | "name": "Inner Layer 2",
67 | "polarity": "positive",
68 | "type": "gerber_layer"
69 | },
70 | {
71 | "advanced_options": {
72 | "mirror": false,
73 | "offset_x": 0,
74 | "offset_y": 0,
75 | "rotate": false,
76 | "upside_down": false
77 | },
78 | "board_outline": false,
79 | "config": {
80 | "file_function": "Copper",
81 | "layer": 3,
82 | "layer_details": "mixed",
83 | "layer_type": "Inner"
84 | },
85 | "filename_format": "%N.GL3",
86 | "layers": [
87 | 17,
88 | 18,
89 | 3
90 | ],
91 | "name": "Inner Layer 3",
92 | "polarity": "positive",
93 | "type": "gerber_layer"
94 | },
95 | {
96 | "advanced_options": {
97 | "mirror": false,
98 | "offset_x": 0,
99 | "offset_y": 0,
100 | "rotate": false,
101 | "upside_down": false
102 | },
103 | "board_outline": false,
104 | "config": {
105 | "file_function": "Copper",
106 | "layer": 4,
107 | "layer_details": "mixed",
108 | "layer_type": "Inner"
109 | },
110 | "filename_format": "%N.GL4",
111 | "layers": [
112 | 17,
113 | 18,
114 | 14
115 | ],
116 | "name": "Inner Layer 14",
117 | "polarity": "positive",
118 | "type": "gerber_layer"
119 | },
120 | {
121 | "advanced_options": {
122 | "mirror": false,
123 | "offset_x": 0,
124 | "offset_y": 0,
125 | "rotate": false,
126 | "upside_down": false
127 | },
128 | "board_outline": false,
129 | "config": {
130 | "file_function": "Copper",
131 | "layer": 5,
132 | "layer_details": "mixed",
133 | "layer_type": "Inner"
134 | },
135 | "filename_format": "%N.GL5",
136 | "layers": [
137 | 17,
138 | 18,
139 | 15
140 | ],
141 | "name": "Inner Layer 15",
142 | "polarity": "positive",
143 | "type": "gerber_layer"
144 | },
145 | {
146 | "advanced_options": {
147 | "mirror": false,
148 | "offset_x": 0,
149 | "offset_y": 0,
150 | "rotate": false,
151 | "upside_down": false
152 | },
153 | "board_outline": false,
154 | "config": {
155 | "file_function": "Copper",
156 | "layer": 6,
157 | "layer_details": "mixed",
158 | "layer_type": "bottom"
159 | },
160 | "filename_format": "%N.GBL",
161 | "layers": [
162 | 16,
163 | 17,
164 | 18
165 | ],
166 | "name": "Bottom Copper",
167 | "polarity": "positive",
168 | "type": "gerber_layer"
169 | },
170 | {
171 | "advanced_options": {
172 | "mirror": false,
173 | "offset_x": 0,
174 | "offset_y": 0,
175 | "rotate": false,
176 | "upside_down": false
177 | },
178 | "board_outline": true,
179 | "config": {
180 | "file_function": "Profile",
181 | "plating": "non-plated"
182 | },
183 | "filename_format": "%N.GKO",
184 | "layers": [
185 | 20,
186 | 46
187 | ],
188 | "milling": true,
189 | "polarity": "positive",
190 | "type": "gerber_layer"
191 | },
192 | {
193 | "advanced_options": {
194 | "mirror": false,
195 | "offset_x": 0,
196 | "offset_y": 0,
197 | "rotate": false,
198 | "upside_down": false
199 | },
200 | "board_outline": false,
201 | "config": {
202 | "file_function": "Soldermask",
203 | "index": 1,
204 | "layer_type": "top"
205 | },
206 | "filename_format": "%N.GTS",
207 | "layers": [
208 | 29
209 | ],
210 | "name": "Soldermask Top",
211 | "polarity": "positive",
212 | "type": "gerber_layer"
213 | },
214 | {
215 | "advanced_options": {
216 | "mirror": false,
217 | "offset_x": 0,
218 | "offset_y": 0,
219 | "rotate": false,
220 | "upside_down": false
221 | },
222 | "board_outline": false,
223 | "config": {
224 | "file_function": "Soldermask",
225 | "index": 1,
226 | "layer_type": "bottom"
227 | },
228 | "filename_format": "%N.GBS",
229 | "layers": [
230 | 30
231 | ],
232 | "name": "Soldermask Bottom",
233 | "polarity": "positive",
234 | "type": "gerber_layer"
235 | },
236 | {
237 | "advanced_options": {
238 | "mirror": false,
239 | "offset_x": 0,
240 | "offset_y": 0,
241 | "rotate": false,
242 | "upside_down": false
243 | },
244 | "board_outline": false,
245 | "config": {
246 | "file_function": "Paste",
247 | "layer_type": "top"
248 | },
249 | "filename_format": "%N.GTP",
250 | "layers": [
251 | 31
252 | ],
253 | "milling": false,
254 | "name": "Solderpaste Top",
255 | "polarity": "positive",
256 | "type": "gerber_layer"
257 | },
258 | {
259 | "advanced_options": {
260 | "mirror": false,
261 | "offset_x": 0,
262 | "offset_y": 0,
263 | "rotate": false,
264 | "upside_down": false
265 | },
266 | "board_outline": false,
267 | "config": {
268 | "file_function": "Paste",
269 | "layer_type": "bottom"
270 | },
271 | "filename_format": "%N.GBP",
272 | "layers": [
273 | 32
274 | ],
275 | "milling": false,
276 | "name": "Solderpaste Bottom",
277 | "polarity": "positive",
278 | "type": "gerber_layer"
279 | },
280 | {
281 | "advanced_options": {
282 | "mirror": false,
283 | "offset_x": 0,
284 | "offset_y": 0,
285 | "rotate": false,
286 | "upside_down": false
287 | },
288 | "board_outline": false,
289 | "config": {
290 | "file_function": "Legend",
291 | "index": 1,
292 | "layer_type": "top"
293 | },
294 | "filename_format": "%N.GTO",
295 | "layers": [
296 | 21
297 | ],
298 | "milling": false,
299 | "name": "Silkscreen Top",
300 | "polarity": "positive",
301 | "type": "gerber_layer"
302 | },
303 | {
304 | "advanced_options": {
305 | "mirror": false,
306 | "offset_x": 0,
307 | "offset_y": 0,
308 | "rotate": false,
309 | "upside_down": false
310 | },
311 | "board_outline": false,
312 | "config": {
313 | "file_function": "Legend",
314 | "index": 1,
315 | "layer_type": "bottom"
316 | },
317 | "filename_format": "%N.GBO",
318 | "layers": [
319 | 22
320 | ],
321 | "milling": false,
322 | "name": "Silkscreen Bottom",
323 | "polarity": "positive",
324 | "type": "gerber_layer"
325 | }
326 | ],
327 | "version": "RS274X"
328 | },
329 | {
330 | "filename_prefix": "CAMOutputs/DrillFiles",
331 | "format_specifier": {
332 | "decimal": 3,
333 | "integer": 3
334 | },
335 | "output_type": "drill",
336 | "outputs": [
337 | {
338 | "advanced_options": {
339 | "mirror": false,
340 | "offset_x": 0,
341 | "offset_y": 0,
342 | "rotate": false,
343 | "upside_down": false
344 | },
345 | "filename_format": "%N.TXT",
346 | "name": "Auto Drill",
347 | "type": "autodrills"
348 | }
349 | ]
350 | },
351 | {
352 | "filename_prefix": "CAMOutputs/Assembly",
353 | "output_type": "assembly",
354 | "outputs": [
355 | ]
356 | },
357 | {
358 | "filename_prefix": "CAMOutputs/DrawingFiles",
359 | "output_type": "drawing",
360 | "outputs": [
361 | ]
362 | }
363 | ],
364 | "timestamp": "2020-08-21T13:29:31",
365 | "type": "EAGLE CAM job",
366 | "units": "metric",
367 | "version": "9.2.0"
368 | }
369 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-2-layer-ALC.dru:
--------------------------------------------------------------------------------
1 | description[en] = SparkFun 2 Layer Design Rule Checks - Limits for PCBWay\n
\n If you're ordering from PCBWay, these are the 'free' minimums.
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 8mil
6 | mdWirePad = 8mil
7 | mdWireVia = 8mil
8 | mdPadPad = 7mil
9 | mdPadVia = 8mil
10 | mdViaVia = 8mil
11 | mdSmdPad = 7mil
12 | mdSmdVia = 7mil
13 | mdSmdSmd = 7mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 8mil
17 | mdDrill = 8mil
18 | mdSmdStop = 0mil
19 | msWidth = 7mil
20 | msDrill = 0.3mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 6mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 6mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 6mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 6mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 6mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 6mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 6mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-2-layer-FAB-LIMIT.dru:
--------------------------------------------------------------------------------
1 | description[en] = SparkFun 2 Layer Design Rule Checks - STANDARD/TIGHT/FAB-LIMIT\n
\nThese rules have been curated by SparkFuns DFM commitee. After doing much research, communicating with our multiple fab houses, and getting quotes of various designs, we have compiled three DRU files. \n
\nSTANDARD: This is more of a "best case scenario" set of limitations. If your design has the space, and/or you have the time to work within these parameters, please do. Larger trace width and clearance makes for easier visual inspection of the PCB while troubleshooting (useful in production and to the end user). It also allows for better ability to hack a trace (if you are crazy enough to scrape away the mask and solder to a trace). Another thing to keep in mind is that more metal is just more robust. \n
\nTIGHT: This is where cost comes into play. We have found that most fab houses begin to add extra charges when you go smaller than these specs. In some cases, going to less than 15 mil trace can increase the cost by 10%. (This is why we have set the min drill on this DRU to 15 mil) Same story for traces thinner than 7 mil. To avoid those extra charges, then stay within the rules of this DRU.\n
\nFAB-LIMIT: These set of rules are at the very limit of most fab houses capabilities. You will pay more for these specs, and it should be used on designs that have a darned good reason to need 4 mil vias and 4 mil traces.\n
\n**NOTE Clearance, Distance, Sizes, and Restring are all set to different limits in each of these three DRU files. Please compare the files within the CAM job editor window of eagle to see all the numbers.\n
\n***NOTE, Please set your Net Classes to default (0mil for all settings), so that it won't effect the DRC when you run it with these settings.
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 4mil
6 | mdWirePad = 4mil
7 | mdWireVia = 4mil
8 | mdPadPad = 4mil
9 | mdPadVia = 4mil
10 | mdViaVia = 4mil
11 | mdSmdPad = 4mil
12 | mdSmdVia = 4mil
13 | mdSmdSmd = 4mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 4mil
17 | mdDrill = 4mil
18 | mdSmdStop = 0mil
19 | msWidth = 4mil
20 | msDrill = 6mil
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 5mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 6mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 5mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 5mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 6mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkGrid = 0
64 | checkAngle = 1
65 | checkFont = 1
66 | checkRestrict = 1
67 | useDiameter = 13
68 | maxErrors = 50
69 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-2-layer-PCBWay-LIMIT.dru:
--------------------------------------------------------------------------------
1 | description[en] = SparkFun 2 Layer Design Rule Checks - Limits for PCBWay\n
\n If you're ordering from PCBWay, these are the 'free' minimums.
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 6mil
6 | mdWirePad = 6mil
7 | mdWireVia = 6mil
8 | mdPadPad = 6mil
9 | mdPadVia = 6mil
10 | mdViaVia = 6mil
11 | mdSmdPad = 6mil
12 | mdSmdVia = 6mil
13 | mdSmdSmd = 6mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 6mil
17 | mdDrill = 6mil
18 | mdSmdStop = 0mil
19 | msWidth = 6mil
20 | msDrill = 0.3mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 6mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 6mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 6mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 6mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 6mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 6mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 6mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | useDiameter = 13
69 | maxErrors = 50
70 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-2-layer-STANDARD.dru:
--------------------------------------------------------------------------------
1 | description[en] = SparkFun 2 Layer Design Rule Checks - STANDARD/TIGHT/FAB-LIMIT\n
\nThese rules have been curated by SparkFuns DFM commitee. After doing much research, communicating with our multiple fab houses, and getting quotes of various designs, we have compiled three DRU files. \n
\nSTANDARD: This is more of a "best case scenario" set of limitations. If your design has the space, and/or you have the time to work within these parameters, please do. Larger trace width and clearance makes for easier visual inspection of the PCB while troubleshooting (useful in production and to the end user). It also allows for better ability to hack a trace (if you are crazy enough to scrape away the mask and solder to a trace). Another thing to keep in mind is that more metal is just more robust. \n
\nTIGHT: This is where cost comes into play. We have found that most fab houses begin to add extra charges when you go smaller than these specs. In some cases, going to less than 15 mil trace can increase the cost by 10%. (This is why we have set the min drill on this DRU to 15 mil) Same story for traces thinner than 7 mil. To avoid those extra charges, then stay within the rules of this DRU.\n
\nFAB-LIMIT: These set of rules are at the very limit of most fab houses capabilities. You will pay more for these specs, and it should be used on designs that have a darned good reason to need 4 mil vias and 4 mil traces.\n
\n**NOTE Clearance, Distance, Sizes, and Restring are all set to different limits in each of these three DRU files. Please compare the files within the CAM job editor window of eagle to see all the numbers.\n
\n***NOTE, Please set your Net Classes to default (0mil for all settings), so that it won't effect the DRC when you run it with these settings.
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 10mil
6 | mdWirePad = 8mil
7 | mdWireVia = 10mil
8 | mdPadPad = 8mil
9 | mdPadVia = 10mil
10 | mdViaVia = 10mil
11 | mdSmdPad = 8mil
12 | mdSmdVia = 8mil
13 | mdSmdSmd = 8mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 8mil
17 | mdDrill = 8mil
18 | mdSmdStop = 0mil
19 | msWidth = 10mil
20 | msDrill = 20mil
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 10mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 10mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 10mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 10mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 10mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkGrid = 0
64 | checkAngle = 1
65 | checkFont = 1
66 | checkRestrict = 1
67 | useDiameter = 13
68 | maxErrors = 50
69 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-2-layer-TIGHT.dru:
--------------------------------------------------------------------------------
1 | description[en] = SparkFun 2 Layer Design Rule Checks - STANDARD/TIGHT/FAB-LIMIT\n
\nThese rules have been curated by SparkFuns DFM commitee. After doing much research, communicating with our multiple fab houses, and getting quotes of various designs, we have compiled three DRU files. \n
\nSTANDARD: This is more of a "best case scenario" set of limitations. If your design has the space, and/or you have the time to work within these parameters, please do. Larger trace width and clearance makes for easier visual inspection of the PCB while troubleshooting (useful in production and to the end user). It also allows for better ability to hack a trace (if you are crazy enough to scrape away the mask and solder to a trace). Another thing to keep in mind is that more metal is just more robust. \n
\nTIGHT: This is where cost comes into play. We have found that most fab houses begin to add extra charges when you go smaller than these specs. In some cases, going to less than 15 mil trace can increase the cost by 10%. (This is why we have set the min drill on this DRU to 15 mil) Same story for traces thinner than 7 mil. To avoid those extra charges, then stay within the rules of this DRU.\n
\nFAB-LIMIT: These set of rules are at the very limit of most fab houses capabilities. You will pay more for these specs, and it should be used on designs that have a darned good reason to need 4 mil vias and 4 mil traces.\n
\n**NOTE Clearance, Distance, Sizes, and Restring are all set to different limits in each of these three DRU files. Please compare the files within the CAM job editor window of eagle to see all the numbers.\n
\n***NOTE, Please set your Net Classes to default (0mil for all settings), so that it won't effect the DRC when you run it with these settings.
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 7mil
6 | mdWirePad = 7mil
7 | mdWireVia = 7mil
8 | mdPadPad = 7mil
9 | mdPadVia = 7mil
10 | mdViaVia = 7mil
11 | mdSmdPad = 7mil
12 | mdSmdVia = 7mil
13 | mdSmdSmd = 7mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 7mil
20 | msDrill = 15mil
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 7mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 7mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 7mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 7mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 7mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkGrid = 0
64 | checkAngle = 1
65 | checkFont = 1
66 | checkRestrict = 1
67 | useDiameter = 13
68 | maxErrors = 50
69 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-4-layer-BGA-Extreme.dru:
--------------------------------------------------------------------------------
1 | description[en] = EAGLE Design Rules\n
\nThe default Design Rules have been set to cover\na wide range of applications. Your particular design\nmay have different requirements, so please make the\nnecessary adjustments and save your customized\ndesign rules under a new name.
2 | layerSetup = ((1*2)+(15*16))
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 0.213359375mm 1.0161mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.213359375mm
5 | mdWireWire = 4mil
6 | mdWirePad = 4mil
7 | mdWireVia = 4mil
8 | mdPadPad = 4mil
9 | mdPadVia = 4mil
10 | mdViaVia = 4mil
11 | mdSmdPad = 0mil
12 | mdSmdVia = 0mil
13 | mdSmdSmd = 0mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 4mil
17 | mdDrill = 4mil
18 | mdSmdStop = 0mil
19 | msWidth = 4mil
20 | msDrill = 0.15mm
21 | msMicroVia = 0.15mm
22 | msBlindViaRatio = 10.000000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 3mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 3mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 3mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 3mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 3mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 3mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 3mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 0
70 | checkPolygonWidth = 1
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-4-layer-FAB-LIMIT.dru:
--------------------------------------------------------------------------------
1 | description[en] = EAGLE Design Rules\n
\nThe default Design Rules have been set to cover\na wide range of applications. Your particular design\nmay have different requirements, so please make the\nnecessary adjustments and save your customized\ndesign rules under a new name.
2 | layerSetup = (1*2*15*16)
3 | mtCopper = 0.035559375mm 0.035559375mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035559375mm 0.035559375mm
4 | mtIsolate = 0.47751875mm 0.47751875mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.47751875mm
5 | mdWireWire = 5mil
6 | mdWirePad = 5mil
7 | mdWireVia = 5mil
8 | mdPadPad = 5mil
9 | mdPadVia = 5mil
10 | mdViaVia = 5mil
11 | mdSmdPad = 5mil
12 | mdSmdVia = 5mil
13 | mdSmdSmd = 5mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 4mil
17 | mdDrill = 4mil
18 | mdSmdStop = 0mil
19 | msWidth = 4mil
20 | msDrill = 6mil
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 5mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 6mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 5mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 5mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 6mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkGrid = 0
64 | checkAngle = 1
65 | checkFont = 1
66 | checkRestrict = 1
67 | useDiameter = 13
68 | maxErrors = 50
69 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-4-layer-MicroMod.dru:
--------------------------------------------------------------------------------
1 | description[en] = \nSparkFun 4 Layer Design Rule Checks for MicroMods\n
\n
2 | layerSetup = (1+2*15+16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 4mil
6 | mdWirePad = 4mil
7 | mdWireVia = 4mil
8 | mdPadPad = 4mil
9 | mdPadVia = 4mil
10 | mdViaVia = 4mil
11 | mdSmdPad = 4mil
12 | mdSmdVia = 4mil
13 | mdSmdSmd = 4mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 6mil
17 | mdDrill = 6mil
18 | mdSmdStop = 0mil
19 | msWidth = 4mil
20 | msDrill = 0.2mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 3mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 3mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 3mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 3mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 3mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 3mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 3mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-4-layer-PCBWAY-LIMIT.dru:
--------------------------------------------------------------------------------
1 | description[en] = EAGLE Design Rules\n
\nThe default Design Rules have been set to cover\na wide range of applications. Your particular design\nmay have different requirements, so please make the\nnecessary adjustments and save your customized\ndesign rules under a new name.
2 | layerSetup = ([15:(1*2)+15*16])
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 0.213359375mm 1.0161mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.213359375mm
5 | mdWireWire = 5mil
6 | mdWirePad = 5mil
7 | mdWireVia = 5mil
8 | mdPadPad = 5mil
9 | mdPadVia = 5mil
10 | mdViaVia = 5mil
11 | mdSmdPad = 0mil
12 | mdSmdVia = 0mil
13 | mdSmdSmd = 0mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 5mil
17 | mdDrill = 5mil
18 | mdSmdStop = 0mil
19 | msWidth = 5mil
20 | msDrill = 0.2mm
21 | msMicroVia = 0.2mm
22 | msBlindViaRatio = 10.000000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 3mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 3mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 3mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 3mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 3mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 3mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 3mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 0
70 | checkPolygonWidth = 1
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/Old/SparkFun-4-layer-TIGHT.dru:
--------------------------------------------------------------------------------
1 | description[en] = EAGLE Design Rules\n
\nThe default Design Rules have been set to cover\na wide range of applications. Your particular design\nmay have different requirements, so please make the\nnecessary adjustments and save your customized\ndesign rules under a new name.
2 | layerSetup = (1*2*15*16)
3 | mtCopper = 0.035559375mm 0.035559375mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035559375mm 0.035559375mm
4 | mtIsolate = 0.47751875mm 0.47751875mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.47751875mm
5 | mdWireWire = 7mil
6 | mdWirePad = 7mil
7 | mdWireVia = 7mil
8 | mdPadPad = 7mil
9 | mdPadVia = 7mil
10 | mdViaVia = 7mil
11 | mdSmdPad = 7mil
12 | mdSmdVia = 7mil
13 | mdSmdSmd = 7mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 7mil
20 | msDrill = 15mil
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 7mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 7mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 7mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 7mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 7mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 4mil
52 | mlMaxStopFrame = 4mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 0mil
58 | srMaxRoundness = 0mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkGrid = 0
64 | checkAngle = 1
65 | checkFont = 1
66 | checkRestrict = 1
67 | useDiameter = 13
68 | maxErrors = 50
69 |
--------------------------------------------------------------------------------
/dru/README.md:
--------------------------------------------------------------------------------
1 | DRU files
2 | =======================
3 | These are the design rules files (.dru), which define the tollerances on the PCB (this includes everything from trace width to layer construction). The PCB fab house can only manufacture up to a specific tollerance and this file makes sure you fall within their constraints. The 2-layer and 4-layer dru files are based on the [BatchPCB](https://batchpcb.com/faq#question_2) design constraints.
--------------------------------------------------------------------------------
/dru/SparkFun-2-Layer-General-JLCPCB.dru:
--------------------------------------------------------------------------------
1 | description[en] = 2 Layer General Rules for JLCPCB\n
\nThese are the free and generally easy to produce 2-layer PCB design rules. You can certainly go smaller but if the design doesn't call for it, these rules provide good guidance.\n
\n- 2 Layer
\n- 7mil Trace/Space
\n- 7mil Annular Rings
\n- 12mil Vias
\n- 3mil Stop Mask
\n
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 7mil
6 | mdWirePad = 7mil
7 | mdWireVia = 7mil
8 | mdPadPad = 7mil
9 | mdPadVia = 7mil
10 | mdViaVia = 7mil
11 | mdSmdPad = 7mil
12 | mdSmdVia = 7mil
13 | mdSmdSmd = 7mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 7mil
20 | msDrill = 0.3mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 7mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 7mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 7mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 7mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 7mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 3mil
52 | mlMaxStopFrame = 3mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/SparkFun-2-Layer-Minimum-JLCPCB.dru:
--------------------------------------------------------------------------------
1 | description[en] = 2 Layer Minimum Rules for JLCPCB\n\nThese are the minimums quoted by JLCPCB to produce a 2-layer PCB design rules. These rules are "free" and generally low-cost. Going below these settings may cause the board to be not manufacturable or incur a price increase.\n
\n- 2 Layer
\n- 5mil Trace/Space
\n- 5mil Annular Rings
\n- 12mil Vias
\n- 2.5mil Stop Mask
\n
2 | layerSetup = (1*16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 5mil
6 | mdWirePad = 5mil
7 | mdWireVia = 5mil
8 | mdPadPad = 5mil
9 | mdPadVia = 5mil
10 | mdViaVia = 5mil
11 | mdSmdPad = 5mil
12 | mdSmdVia = 5mil
13 | mdSmdSmd = 5mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 5mil
20 | msDrill = 0.3mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 5mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 5mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 5mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 5mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 5mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 2.5mil
52 | mlMaxStopFrame = 2.5mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/SparkFun-4-Layer-General-JLCPCB.dru:
--------------------------------------------------------------------------------
1 | description[en] = 4 Layer General Rules for JLCPCB\n\nThese are the free and generally easy to produce 4-layer PCB design rules. You can certainly go smaller but if the design doesn't call for it, these rules provide good guidance.\n
\n- 4 Layer
\n- 7mil Trace/Space
\n- 7mil Annular Rings
\n- 12mil Vias
\n- 3mil Stop Mask
\n
2 | layerSetup = (1+2*15+16)
3 | mtCopper = 0.035559375mm 0.035559375mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035559375mm 0.035559375mm
4 | mtIsolate = 0.47751875mm 0.47751875mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.47751875mm
5 | mdWireWire = 7mil
6 | mdWirePad = 7mil
7 | mdWireVia = 7mil
8 | mdPadPad = 7mil
9 | mdPadVia = 7mil
10 | mdViaVia = 7mil
11 | mdSmdPad = 7mil
12 | mdSmdVia = 7mil
13 | mdSmdSmd = 7mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 7mil
20 | msDrill = 12mil
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 7mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 7mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 7mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 7mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 7mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 3mil
52 | mlMaxStopFrame = 3mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/SparkFun-4-Layer-MicroMod-JLCPCB.dru:
--------------------------------------------------------------------------------
1 | description[en] = \nSparkFun 4 Layer Design Rules for MicroMod for JLCPCB\n\nThese design rules are smaller than the published rules by JLCPCB to produce a 4-layer PCB. But we have needed these tolerances for some very tight layouts. These rules should be avoided unless absolutely necessary and will complicate the ordering process (including some orders being refused).\n
\n- 4 Layer
\n- 4mil Trace/Space
\n- 4mil Annular Rings
\n- 0.2mm/7.9mil Vias
\n- 2.5mil Stop Mask
\n
2 | layerSetup = (1+2*15+16)
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm
5 | mdWireWire = 4mil
6 | mdWirePad = 4mil
7 | mdWireVia = 4mil
8 | mdPadPad = 4mil
9 | mdPadVia = 4mil
10 | mdViaVia = 4mil
11 | mdSmdPad = 4mil
12 | mdSmdVia = 4mil
13 | mdSmdSmd = 4mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 6mil
17 | mdDrill = 6mil
18 | mdSmdStop = 0mil
19 | msWidth = 4mil
20 | msDrill = 0.2mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 3mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 3mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 3mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 3mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 3mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 3mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 3mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 2.5mil
52 | mlMaxStopFrame = 2.5mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/SparkFun-4-Layer-Minimum-Blind-Vias-PCBWay.dru:
--------------------------------------------------------------------------------
1 | description[en] = SparkFun 4 Layer Design Rules with Blind Vias for PCBWay\n\nThese are pretty extreme design rules reserved for 4-layer boards with blind vias. Primarily used on the Artemis module design, these rules have only been used with PCBWay (published rules by PBWay). These rules should be avoided unless absolutely necessary and will increase fab times and complicate the ordering process.\n
\n- 4 Layer
\n- 4mil Trace/Space
\n- 3mil Annular Rings
\n- 0.15mm/6mil Blind Vias
\n- 2.5mil Stop Mask
\n
2 | layerSetup = ([2:1+2*15+16:15])
3 | mtCopper = 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm
4 | mtIsolate = 0.213359375mm 1.0161mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.213359375mm
5 | mdWireWire = 4mil
6 | mdWirePad = 4mil
7 | mdWireVia = 4mil
8 | mdPadPad = 4mil
9 | mdPadVia = 4mil
10 | mdViaVia = 4mil
11 | mdSmdPad = 0mil
12 | mdSmdVia = 0mil
13 | mdSmdSmd = 0mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 5mil
17 | mdDrill = 4mil
18 | mdSmdStop = 0mil
19 | msWidth = 4mil
20 | msDrill = 0.15mm
21 | msMicroVia = 0.15mm
22 | msBlindViaRatio = 10.000000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 3mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 3mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 3mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 3mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 3mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 3mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 3mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 2.5mil
52 | mlMaxStopFrame = 2.5mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 0
70 | checkPolygonWidth = 1
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/SparkFun-4-Layer-Minimum-JLCPCB.dru:
--------------------------------------------------------------------------------
1 | description[en] = 4 Layer Minimum Rules for JLCPCB\n\nThese are the minimums quoted by JLCPCB to produce a 4-layer PCB design rules. These rules are "free" and generally low-cost. There is one DRC set that is smaller (see MicroMod rules) but boards designed with these rules should pass review without question.\n
\n- 4 Layer
\n- 5mil Trace/Space
\n- 5mil Annular Rings
\n- 0.2mm/7.9mil Vias
\n- 2.5mil Stop Mask
\n
2 | layerSetup = (1*2*15*16)
3 | mtCopper = 0.035559375mm 0.035559375mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035559375mm 0.035559375mm
4 | mtIsolate = 0.47751875mm 0.47751875mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.47751875mm
5 | mdWireWire = 5mil
6 | mdWirePad = 5mil
7 | mdWireVia = 5mil
8 | mdPadPad = 5mil
9 | mdPadVia = 5mil
10 | mdViaVia = 5mil
11 | mdSmdPad = 5mil
12 | mdSmdVia = 5mil
13 | mdSmdSmd = 5mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 5mil
20 | msDrill = 0.2mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 5mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 5mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 5mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 5mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 5mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 2.5mil
52 | mlMaxStopFrame = 2.5mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/dru/SparkFun-6-Layer-Minimum-JLCPCB.dru:
--------------------------------------------------------------------------------
1 | description[en] = 6 Layer JLC06161H-3313 Rules for JLCPCB\n\nThese are the rules quoted by JLCPCB to produce a 6-layer PCB design using JLC06161H-3313 stackup. These rules are the lowest cost controlled impedance rules for this many layers. \n
\n- 6 Layer
\n- 3.5mil Trace/Space
\n- 5mil Annular Rings
\n- 0.2mm/7.9mil Vias
\n- 2.5mil Stop Mask
\n
2 | layerSetup = (1+2*3+14*15+16)
3 | mtCopper = 0.035mm 0.0152mm 0.0152mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.0152mm 0.0152mm 0.035mm
4 | mtIsolate = 0.0994mm 0.55mm 0.1088mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.55mm 0.0994mm
5 | mdWireWire = 0.09mm
6 | mdWirePad = 5mil
7 | mdWireVia = 5mil
8 | mdPadPad = 5mil
9 | mdPadVia = 5mil
10 | mdViaVia = 5mil
11 | mdSmdPad = 5mil
12 | mdSmdVia = 5mil
13 | mdSmdSmd = 5mil
14 | mdViaViaSameLayer = 8mil
15 | mnLayersViaInSmd = 2
16 | mdCopperDimension = 7mil
17 | mdDrill = 7mil
18 | mdSmdStop = 0mil
19 | msWidth = 0.09mm
20 | msDrill = 0.2mm
21 | msMicroVia = 9.99mm
22 | msBlindViaRatio = 0.500000
23 | rvPadTop = 0.250000
24 | rvPadInner = 0.250000
25 | rvPadBottom = 0.250000
26 | rvViaOuter = 0.250000
27 | rvViaInner = 0.250000
28 | rvMicroViaOuter = 0.250000
29 | rvMicroViaInner = 0.250000
30 | rlMinPadTop = 5mil
31 | rlMaxPadTop = 20mil
32 | rlMinPadInner = 5mil
33 | rlMaxPadInner = 20mil
34 | rlMinPadBottom = 5mil
35 | rlMaxPadBottom = 20mil
36 | rlMinViaOuter = 5mil
37 | rlMaxViaOuter = 20mil
38 | rlMinViaInner = 5mil
39 | rlMaxViaInner = 20mil
40 | rlMinMicroViaOuter = 4mil
41 | rlMaxMicroViaOuter = 20mil
42 | rlMinMicroViaInner = 4mil
43 | rlMaxMicroViaInner = 20mil
44 | psTop = -1
45 | psBottom = -1
46 | psFirst = -1
47 | psElongationLong = 100
48 | psElongationOffset = 100
49 | mvStopFrame = 1.000000
50 | mvCreamFrame = 0.000000
51 | mlMinStopFrame = 2.5mil
52 | mlMaxStopFrame = 2.5mil
53 | mlMinCreamFrame = 0mil
54 | mlMaxCreamFrame = 0mil
55 | mlViaStopLimit = 25mil
56 | srRoundness = 0.000000
57 | srMinRoundness = 2mil
58 | srMaxRoundness = 2mil
59 | slThermalIsolate = 10mil
60 | slThermalsForVias = 0
61 | dpMaxLengthDifference = 10mm
62 | dpGapFactor = 2.500000
63 | checkAngle = 1
64 | checkFont = 1
65 | checkRestrict = 1
66 | checkStop = 0
67 | checkValues = 0
68 | checkNames = 1
69 | checkWireStubs = 1
70 | checkPolygonWidth = 0
71 | useDiameter = 13
72 | maxErrors = 50
73 |
--------------------------------------------------------------------------------
/scr/eagle.scr:
--------------------------------------------------------------------------------
1 | # Configuration Script
2 | #
3 | # This file can be used to configure the editor windows.
4 |
5 | Assign F3 'Delete';
6 | Assign AF3 'Grid inch 0.001 on; Grid alt inch 0.01;';
7 | Assign F4 'Name';
8 | Assign F5 'Value';
9 | Assign AF5 'Change Text';
10 | Assign F6 'Smash';
11 | Assign F7 'Move';
12 | Assign AF7 'Group';
13 | Assign F8 'Copy';
14 | Assign F10 'Grid inch 0.05 on; Grid alt inch 0.005;';
15 | Assign AF10 'Grid mm 1 on; Grid alt mm 0.1;';
16 | Assign CS+A 'run SparkFun-AutoChecklist.ulp;';
17 | Assign CS+S 'run SparkFun-AutoChecklist-Schematic.ulp;';
18 |
19 | Grid inch 0.05 on;
20 | Grid alt inch 0.005;
21 |
22 | BRD:
23 | #Menu Add Change Copy Delete Display Grid Group Move Name Quit Rect \
24 | # Route Script Show Signal Split Text Value Via Window ';' Wire Write Edit;
25 |
26 | #Setup SparkFun Defaults
27 | Grid inch 0.05 on;
28 | Grid alt inch 0.005;
29 | Set WIRE_BEND 1; #Route with 45 degree angles
30 | Set Drill 0.015; #Make vias 15mil by default
31 | Change Shape Round; #Make vias round
32 | Change Width 0.010; #Routing width default to 10mil
33 | Change Isolate 0.012; #BHW Change polygon isolate to 12mil
34 |
35 | Change Font Vector; #Make text on board in vector font
36 | Change Ratio 15;
37 |
38 | CHANGE DUNIT INCH OFF #BHW Change default units to inches [ON | OFF] [precision]
39 |
40 | #changes background color of board to black
41 | SET PALETTE BLACK;
42 |
43 | #Layer colors
44 | Set palette 1 0xB43232C8; #classic dark blue
45 | Set palette 2 0xB432C832; #classic green
46 | Set palette 4 0xB4C83232; #classic dark red
47 | Set palette 16 0xFFFFFFFF; #Super white
48 | Set palette 24 0xFFC0C0C0; #Grey - color used when text is selected (anti palette location 16)
49 | Set color_layer 1 4; #Set top layer to dark red
50 | Set color_layer 16 1; #Set bottom layer to dark blue
51 | Set color_layer 17 2; #Set pads to green
52 | Set color_layer 18 2; #Set vias to green
53 | Set color_layer 19 6; #Set unrouted to dark yellow
54 | #Set color_layer 20 15; #Set dimension to light gray - this changed in v9
55 | Set color_layer 20 24; #Set dimension to light gray
56 | Set color_layer 21 16; #Set tPlace to white
57 | Set color_layer 22 14; #Set bPlace to yellow
58 | Set color_layer 23 15; #Set tOrigins to light gray
59 | Set color_layer 24 15; #Set bOrigins to light gray
60 | Set color_layer 45 7; #Set Holes to dark gray
61 | Set color_layer 51 6; #Set tDocu to mellow yellow
62 | display none; display 1 16 17 18 19 20 21 22 23 24 45 51; display -25 -26 -27 -28;
63 |
64 | #Used for four layer routing
65 | Assign A+1 'Set Used_Layers 1 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52;' #2 layer stackup
66 | Assign A+2 'Set Used_Layers 1 2 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52;' #4 layer stackup
67 | Assign A+3 'Set Used_Layers 1 2 3 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52;' #6 layer stackup
68 |
69 | DISPLAY = TopOnly 1 17 18 19 20;
70 | DISPLAY = BottomOnly 16 17 18 19 20;
71 | DISPLAY = VerticalOnly 15 17 18 19 20;
72 | DISPLAY = HorizontalOnly 2 17 18 19 20;
73 | Assign A+7 'display none; display TopOnly;'
74 | Assign A+8 'display none; display BottomOnly;'
75 | Assign A+9 'display none; display HorizontalOnly;'
76 | Assign A+0 'display none; display VerticalOnly;'
77 |
78 |
79 | #Assign shortcuts
80 | Assign F8 ratsnest;
81 | Assign AF8 drc;
82 |
83 | Assign F9 'Route';
84 | Assign AF9 'Ripup';
85 |
86 | Assign F10 'Grid inch 0.05 on; Grid alt inch 0.005;';
87 | Assign AF10 'Grid mm 1 on; Grid alt mm 0.1;';
88 |
89 | Assign F11 'display none; display 1 16 17 18 19 20 21 22 23 24 45 49 51; display -25 -26 -27 -28;';
90 | Assign AF11 'display none; display 17 20 21 23 27 31 45 51; display -25 -26 -28;';
91 |
92 | Assign F12 'show';
93 | Assign AF12 'info';
94 |
95 | # Display the bottom side of board and what it will look like in a more human readable view. The "f" is for "flip".
96 | Assign C+F 'RUN SparkFun-Flip.ulp;';
97 |
98 | # Turn off everything but the unrouted airwires
99 | Assign C+H 'DISPLAY NONE; DISPLAY 19;';
100 |
101 |
102 | SCH:
103 | Grid Default; #BHW Reset the grid to the standard value
104 | Change Width 0.006; #BHW Set the 6mil rule
105 | Set XREF_LABEL_FORMAT %F%N/%S; #BHW Remove row & column from default
106 | Change XREF ON; #BHW Default to the labels we use (flag border)
107 | Change Size 0.05; #BHW Use 50mil flags (and text... exceeds minimum)
108 |
109 | Assign F9 'Net';
110 | Assign AF9 'Label';
111 |
112 | Assign F12 'show';
113 | Assign AF12 'info';
114 |
115 | Grid Default;
116 | Change Width 0.008;
117 |
118 | #Menu Add Bus Change Copy Delete Display Gateswap Grid Group Invoke Junction \
119 | # Label Move Name Net Pinswap Quit Script Show Split Value Window ';' \
120 | # Wire Write Edit;
121 |
122 | PAC:
123 | #Settings for editing footprints within a library
124 |
125 | #Set to two layer defaults
126 | SET USED_LAYERS 1 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 91 92 93 94 95 96;
127 |
128 | Grid inch 0.05 on;
129 | Grid alt inch 0.005;
130 | Set WIRE_BEND 1; #Route with 45 degree angles
131 | Set Drill 0.015; #Make vias 0.02"
132 |
133 | #Assign layer colors to match layer colors when routing
134 | Set palette 1 0xB43232C8; #classic dark blue
135 | Set palette 2 0xB432C832; #classic green
136 | Set palette 4 0xB4C83232; #classic dark red
137 | Set palette 16 0xFFFFFFFF; #Super white
138 | Set palette 24 0xFFC0C0C0; #Grey - color used when text is selected (anti palette location 16)
139 | Set color_layer 1 4; #Set top layer to dark red
140 | Set color_layer 16 1; #Set bottom layer to dark blue
141 | Set color_layer 17 2; #Set pads to green
142 | Set color_layer 18 2; #Set vias to green
143 | Set color_layer 19 6; #Set unrouted to dark yellow
144 | #Set color_layer 20 15; #Set dimension to light gray - this changed in v9
145 | Set color_layer 20 24; #Set dimension to light gray
146 | Set color_layer 21 16; #Set tPlace to white
147 | Set color_layer 22 14; #Set bPlace to yellow
148 | Set color_layer 23 15; #Set tOrigins to light gray
149 | Set color_layer 24 15; #Set bOrigins to light gray
150 | Set color_layer 45 7; #Set Holes to dark gray
151 | Set color_layer 51 6; #Set tDocu to mellow yellow
152 | display none; display 1 16 17 18 19 20 21 22 23 24 45 51; display -25 -26 -27 -28;
153 |
154 | Assign F10 'Grid inch 0.05 on; Grid alt inch 0.005;';
155 | Assign AF10 'Grid mm 1 on; Grid alt mm 0.1;';
156 |
157 | Assign F11 'display none; display 1 16 17 18 19 20 21 22 23 24 45 49 51; display -25 -26 -27 -28;';
158 | Assign AF11 'display none; display 17 20 21 23 27 31 45 51; display -25 -26 -28;';
159 |
160 | DEV:
161 | # Settings when editing a device in a library
162 |
163 | Grid Default;
164 | #Menu Add Change Copy Connect Delete Display Export Grid Move Name Package \
165 | # Prefix Quit Script Show Value Window ';' Write Edit;
166 |
167 | SYM:
168 | # Settings when editing a symbol in a library
169 |
170 | GRID Default OFF;
171 | Change Width 0.010;
172 | #Menu Arc Change Copy Cut Delete Display Export Grid Group Move Name Paste \
173 | # Pin Quit Script Show Split Text Value Window ';' Wire Write Edit;
174 |
--------------------------------------------------------------------------------
/ulp/7za.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/7za.exe
--------------------------------------------------------------------------------
/ulp/Include_String.ulp:
--------------------------------------------------------------------------------
1 | /* WILDCARD */
2 | string STRING_WILDCARD_STR = "%%";
3 |
4 | string stringFTrim(string str)
5 | {
6 | string str2;
7 | int trimmed = 0;
8 |
9 | for(int i = 0; str[i]; i++)
10 | {
11 | if(trimmed)
12 | {
13 | str2 += str[i];
14 | }
15 | else if(str[i] != ' ' && str[i] != '\n' && str[i] != '\t')
16 | {
17 | trimmed = 1;
18 | str2 += str[i];
19 | }
20 | }
21 |
22 | return str2;
23 | }
24 |
25 | string stringLTrim(string str)
26 | {
27 | string str2;
28 | int trimmed = 0;
29 |
30 | for(int i = strlen(str)-1; i >= 0; i--)
31 | {
32 | if(trimmed)
33 | {
34 | sprintf(str2, "%c%s", str[i], str2);
35 | }
36 | else if(str[i] != ' ' && str[i] != '\n' && str[i] != '\t')
37 | {
38 | trimmed = 1;
39 | sprintf(str2, "%c%s", str[i], str2);
40 | }
41 | }
42 |
43 | return str2;
44 | }
45 |
46 | string stringTrim(string str)
47 | {
48 | return stringLTrim(stringFTrim(str));
49 | }
50 |
51 | string stringReplace(string str, string search, string replace)
52 | {
53 | int offset = 0;
54 | while(strstr(str, search, offset) != -1)
55 | {
56 | int start = strstr(str, search, offset);
57 | int end = start + strlen(search);
58 | string str1 = strsub(str, 0, start);
59 | string str2 = strsub(str, end);
60 |
61 | offset = strlen(str1) + strlen(replace);
62 |
63 | str = str1 + replace + str2;
64 | }
65 |
66 | return str;
67 | }
68 |
69 | string stringConvertDotToComma(string str)
70 | {
71 | return str; //stringReplace(str, ".", ",");
72 | }
73 |
74 | // EAGLE ADDS A ":" to sprintf's real value, why?
75 | string stringFromReal(real value)
76 | {
77 | string tmp;
78 | sprintf(tmp, "%e", value);
79 |
80 | if(strchr(tmp, ':') != -1)
81 | {
82 | tmp[strchr(tmp, ':')] = '0';
83 | }
84 |
85 | return tmp;
86 | }
87 |
88 |
89 | int stringAdvancedMatch(string needle, string haystack)
90 | {
91 | string search[];
92 | int index = 0;
93 |
94 | int count = strsplit(search, needle, '*');
95 |
96 | if(stringTrim(haystack) == "" && needle != "")
97 | {
98 | return 0;
99 | }
100 |
101 | for(int i = 0; i < count; i++)
102 | {
103 | if(search[i] != "" && (index = strstr(haystack, search[i], index)) == -1)
104 | {
105 | return 0;
106 | }
107 | }
108 |
109 | return 1;
110 | }
111 |
112 | /* Parameters look like: grid 5 mm, outline 5 x 5 mm */
113 | string stringParameterValue(string parameter, string haystack)
114 | {
115 | string data = "";
116 |
117 | int start = strstr(haystack, parameter, 0);
118 | int len = strlen(parameter) + 1;
119 | int end = 0;
120 |
121 | if(start != -1)
122 | {
123 | end = strstr(haystack, ",", start);
124 | end = end==-1?strlen(haystack):end;
125 |
126 | data = strsub(haystack, start + len , end-(start+len));
127 | }
128 |
129 | return stringTrim(data);
130 | }
131 |
132 | int stringParameterPresent(string parameter, string haystack)
133 | {
134 | return (strstr(haystack, parameter, 0) != -1)?1:0;
135 | }
136 |
137 |
138 | string stringWildcardGetNext(string wildcarded)
139 | {
140 | int start = strstr(wildcarded, STRING_WILDCARD_STR);
141 | int end = strstr(wildcarded, STRING_WILDCARD_STR, start+1);
142 |
143 | return strsub(wildcarded, start+2, end-start-2);
144 | }
145 |
146 | string stringWildcardReplace(string wildcarded, string wildcard, string replacement)
147 | {
148 | int start = strstr(wildcarded, STRING_WILDCARD_STR + wildcard + STRING_WILDCARD_STR, 0);
149 | int end = start + strlen(STRING_WILDCARD_STR + wildcard + STRING_WILDCARD_STR);
150 | string str1 = strsub(wildcarded, 0, start);
151 | string str2 = strsub(wildcarded, end);
152 |
153 | return str1 + replacement + str2;
154 | }
155 |
156 | int stringCompare(string s1, string s2)
157 | {
158 | for(int i = 0; i < strlen(s1) && i < strlen(s2); i++)
159 | {
160 | if(s1[i] > s2[i]) { return 1;}
161 | else if(s1[i] < s2[i]) { return -1;}
162 | }
163 |
164 | return 0;
165 | }
166 |
167 | string itoa(int num){
168 | string tmp;
169 | sprintf(tmp, "%d", num);
170 | return tmp;
171 | }
--------------------------------------------------------------------------------
/ulp/SparkFun-BOM_Generator.flt:
--------------------------------------------------------------------------------
1 | fiducial
2 | stand-off
3 |
--------------------------------------------------------------------------------
/ulp/SparkFun-BOM_Generator.ulp:
--------------------------------------------------------------------------------
1 | #usage "en: Outputs the contents of a design to Sparkle Friendly list "
2 | "Usage: run SparkFun-BOM_Generator
"
3 | "Author: Owen Lyke, Nathan Seidle <owen.lyke@sparkfun.com>
"
4 | "Version: 1.0
"
5 |
6 | /*
7 |
8 | #usage "en: Outputs the contents of a design to Sparkle Friendly list PCBWay requires the user to create panels that are at least 75x75mm. If the panel is smaller than this they will reject it because their v-score machine can't handle it. This ULP takes a given design and replicates it until the panel is just over the dimensions specified by the user. It also adds dimension lines between copies and v-score text so that PCBWay knows where to v-score. This script will also detect overhanging parts and warn the user that gaps are needed. Script tries to identify the soldermask color based on the logos on the board (SparkFun vs SparkX vs LilyPad). Script looks for 0.8mm tag for thin boards. Script outputs a ordering_instructions.txt file containing all the characteristics of this panel."
9 | "Usage: run bom_sparkle
"
10 | "Author: Nathan Seidle <inathan@sparkfun.com>
"
11 | "Version: 1.0
"
12 |
13 | */
14 |
15 | // Modified October 2021, Paul Clark
16 | /*
17 |
18 | Modification goals:
19 | - Add Pick and Place Helper
20 | * Provide a 'quick' way to highlight particular parts when hand-populating a board
21 |
22 | */
23 |
24 | // Modified October 2018, Owen Lyke
25 | /*
26 |
27 | Modification goals:
28 | - improve detection of false positives (a part that is on the board but doesn't exactly match a production part that can be used)
29 | * previous method was to search the part name and make sure it included the value
30 |
31 | - output a format that sparkle can handle to automatically set the quantity (this depends on SWIT adding this functionality in sparkle first)
32 | * currently in-progress, requires SWIT support but can be easily adapted into the output format when needed
33 |
34 | - improve detetion of on-board vs no-package components
35 | * answered by allowing the user to flag entries as "BOM" or "Non-BOM" while still not missing any board elements
36 | * also looping through boad elements as opposed to schematic elements helps
37 |
38 | */
39 |
40 | #include "z_Include_SF_BOM.ulp"
41 |
42 | string pnpString = "";
43 |
44 | if (schematic)
45 | {
46 | exit("edit .brd; run " + ulpName);
47 | }
48 | if (board)
49 | {
50 |
51 | int cnfrdres = configRead(configFile);
52 | if (cnfrdres)
53 | {
54 | configWrite(configFile);
55 | }
56 |
57 | // This loop does the initial categorization of all the components.
58 | // It is based off of only existence of PROD_ID or not
59 | initialGrouping();
60 |
61 | categorizeElements(); // Initial categorization
62 |
63 | dlgDialog("BOM Output"){
64 |
65 | dlgTabWidget{
66 | dlgTabPage("BOM View"){
67 | dlgHBoxLayout{
68 |
69 | dlgVBoxLayout{
70 | // BOM items
71 | dlgLabel("BOM Items");
72 | dlgListView(headerString, bomlistarry, bomSelected, bomSort);
73 | dlgPushButton("Move to Non-BOM")
74 | {
75 | if (bomSelected != -1)
76 | {
77 | master_status[bom_index_map[bomSelected]] = element_status_nonbom;
78 | categorizeElements();
79 | }
80 | }
81 | }
82 |
83 | dlgVBoxLayout
84 | {
85 | // Non-BOM items
86 | dlgHBoxLayout
87 | {
88 | dlgLabel("Non-BOM Items");
89 | }
90 | // dlgStretch(1);
91 | dlgListView(headerString, nonbomlistarry, nonbomSelected, nonbomSort);
92 | dlgPushButton("Move to BOM")
93 | {
94 | if (nonbomSelected != -1)
95 | {
96 | master_status[nonbom_index_map[nonbomSelected]] = element_status_bom;
97 | categorizeElements();
98 | }
99 | }
100 | }
101 |
102 | // Filters
103 | dlgVBoxLayout
104 | {
105 |
106 | dlgLabel("Welcome to the BOM utility!");
107 | dlgPushButton("BOM Utility Help/Info/FAQ")
108 | {
109 | dlgDialog("NBOM Utility Info")
110 | {
111 | dlgLabel("This ULP lets you confidently keep track of all the elements on your board\n\
112 | \n\
113 | The main feature is the ability to change which items are considered to be part of the BOM.\n\
114 | There are two ways of doins this:\n\
115 | \t- 1) Manually move items from \"BOM Items\" to \"Non-BOM Items\" and back using the buttons below each list\n\
116 | \t- 2) Apply a filter on the package names to exclude them from the \"Non-BOM Items\" list.\n\
117 | \n\
118 | * Notes: \n\
119 | t- Items that have no PROD_ID, no contacts, and no holes are considered \"Non-Hardware\" and are excluded from BOM permanently\n\
120 | \t- You can toggle the filter to see what is hidden from the \"Non-BOM Items\" list\n\
121 | \t- Items in the \"BOM Items\" list are not affected by filters, so you can manually override a filter.\n\
122 | \t- A defualt ilter file is loaded on startup, if present. You can also write your own filter files and load them.\n\
123 | \t\t (each line of the text file is a filter entry)\n\
124 | \t- The sparkle output will let you know how many BOM items are missing a PROD_ID (these are not displayed in the sparkle CSV)");
125 | // dlgListView("Qty\tPROD_ID\tPackage\tValue\tNames", silklistarry, silkSelected, silkSort);
126 | dlgPushButton("Close")
127 | {
128 | dlgAccept();
129 | }
130 | };
131 | }
132 |
133 | dlgPushButton("Export BOM as CSV: ")
134 | {
135 | // exportFilePath = dlgFileOpen("Select directory in which to export the BOM", EAGLE_HOME, "*");
136 | exportFilePath = dlgDirectory("Select directory in which to export the BOM", EAGLE_HOME);
137 |
138 | if (exportFilePath != "")
139 | {
140 | exportFilePath += "/bom_output.csv";
141 |
142 | output(exportFilePath, "wt")
143 | {
144 | string line = "Qty, PROD_ID, Names, Value, Package";
145 | printf("%s\n", line); // Header
146 | for (int indi = 0; indi < numUniqueEntries; indi++)
147 | {
148 | if (master_status[indi] == element_status_bom)
149 | {
150 | string local_names = replaceCharacter(master_names[indi], ',', ';');
151 | string local_values = replaceCharacter(master_values[indi], ',', ';');
152 | string local_prod_ids = replaceCharacter(master_prod_ids[indi], ',', ';');
153 | string local_package_names = replaceCharacter(master_package_names[indi], ',', ';');
154 |
155 | printf("%d, %s, %s, %s, %s\n", master_quantities[indi], local_prod_ids, local_names, local_values, local_package_names);
156 | }
157 | }
158 | dlgMessageBox("File created at: " + exportFilePath);
159 | }
160 | // dlgDialog("Rename Export File?")
161 | // {
162 | // dlgLabel("Output file created at: " + exportFilePath);
163 | // dlgLabel("Rename the file?");
164 | // dlgHBoxLayout{
165 | // dlgPushButton("-No"){
166 | // dlgAccept();
167 | // }
168 | // dlgPushButton("+Yes"){
169 | // string newExportFileName = "";
170 | // string data[];
171 | // int line = fileread(data, exportFilePath);
172 |
173 | // dlgDialog("Enter new name: "){
174 | // dlgTextEdit(&newExportFileName){ dlgAccept(); };
175 | // }
176 |
177 | // output(newExportFileName){
178 | // if(line)
179 | // {
180 | // int indi = 0;
181 | // while(data[indi] != ""){
182 | // filterStrings[indi] = data[indi];
183 | // indi++;
184 | // }
185 | // }
186 | // }
187 |
188 | // dlgAccept();
189 | // }
190 |
191 | // }
192 | // };
193 | }
194 | else
195 | {
196 | dlgMessageBox("No path supplied");
197 | }
198 |
199 | exportFilePath = "";
200 | }
201 |
202 | dlgHBoxLayout
203 | {
204 | dlgVBoxLayout
205 | {
206 | dlgLabel("Filters status: \n(double click to change)");
207 | dlgListBox(filterStatus, filters_active) categorizeElements();
208 | }
209 | dlgVBoxLayout
210 | {
211 | dlgLabel("Number of filtered items \n(hidden from the Non-BOM list):");
212 | dlgTextView(numFilteredItems);
213 | }
214 | }
215 | dlgPushButton("View Non-Hardware Items")
216 | {
217 | dlgDialog("Non-Hardware Elements")
218 | {
219 | dlgLabel("Stuff");
220 | dlgListView(headerString, nonhardwarelistarry, nonhardwareSelected, nonhardwareSort);
221 | dlgHBoxLayout
222 | {
223 | dlgPushButton("Move to BOM")
224 | {
225 | if (nonhardwareSelected != -1)
226 | {
227 | master_status[nonhardware_index_map[nonhardwareSelected]] = element_status_bom;
228 | categorizeElements();
229 | dlgAccept();
230 | }
231 | }
232 | dlgPushButton("Move to Non-BOM")
233 | {
234 | if (nonhardwareSelected != -1)
235 | {
236 | master_status[nonhardware_index_map[nonhardwareSelected]] = element_status_nonbom;
237 | categorizeElements();
238 | dlgAccept();
239 | }
240 | }
241 | }
242 | dlgPushButton("Close")
243 | {
244 | dlgAccept();
245 | }
246 | };
247 | }
248 | }
249 | }
250 | }
251 |
252 | dlgTabPage("Filter Settings")
253 | {
254 | // Filter Modification
255 | dlgLabel("Current Filter Strings \n(Apply only to items in the Non-BOM list - initially any item with a PROD_ID is displayed)");
256 | dlgListView("Filter", filterStrings, filter_string_selected, filter_string_sort);
257 | dlgPushButton("Remove from filter list")
258 | {
259 | removeFromFilterList();
260 | categorizeElements();
261 | }
262 |
263 | dlgLabel("Add new filters");
264 | dlgTextEdit(temp_filter_string);
265 | dlgPushButton("Add to filter list")
266 | {
267 | addToFilterList();
268 | categorizeElements();
269 | }
270 |
271 | dlgHBoxLayout
272 | {
273 | dlgPushButton("Load filter cnfg file")
274 | {
275 | customFilterFile = dlgFileOpen("Select a filter cnfiguration file (.flt)", path_ulp[0], "*.flt");
276 | configRead(customFilterFile);
277 | categorizeElements();
278 | }
279 | dlgPushButton("Save as default cnfg")
280 | {
281 | configWrite(configFile);
282 | categorizeElements();
283 | }
284 | }
285 | }
286 |
287 | dlgTabPage("Sparkle Output")
288 | {
289 | dlgLabel("*Reminder* Don't forget to add a PCB part to the BOM in Sparkle");
290 | dlgLabel("CSV of PROD_IDs for Sparkle");
291 | dlgTextView(sparkleBOM);
292 | dlgLabel("PROD_ID Status:");
293 | dlgTextView(prod_id_warning);
294 | }
295 |
296 | dlgTabPage("Pick and Place Helper")
297 | {
298 | dlgVBoxLayout{
299 | // BOM items
300 | dlgLabel("BOM Items");
301 | dlgListView(pnpHeaderString, pnplistarry, pnpSelected, bomSort);
302 | dlgPushButton("Show")
303 | {
304 | if (pnpSelected == -1)
305 | {
306 | pnpString = "";
307 | }
308 | else
309 | {
310 | pnpString = "show " + string(master_pnp_names[bom_index_map[pnpSelected]]);
311 | }
312 | dlgAccept();
313 | };
314 | };
315 | }
316 | }
317 |
318 | dlgGridLayout
319 | {
320 |
321 | dlgCell(0, 0)
322 | {
323 | dlgPushButton("Done")
324 | {
325 | setup_complete = 1;
326 | // result = 0;
327 | dlgAccept();
328 | };
329 | };
330 | }
331 | }
332 | ;
333 | if (pnpString == "")
334 | exit(0);
335 | else
336 | exit(pnpString);
337 | }
338 | else
339 | {
340 | dlgMessageBox("Please run this ulp from the board editor");
341 | exit(1);
342 | }
343 |
--------------------------------------------------------------------------------
/ulp/SparkFun-CAMmer-linux.ulp:
--------------------------------------------------------------------------------
1 | #usage "en: Output Gerbers of a given board. This script looks at how many layers, if there are bottom components, etc and outputs the necessary Gerber files. It will also zip them together if user requests it."
2 | "Usage: run sparkfun-cammer
"
3 | "Author: Nathan Seidle <inathan@sparkfun.com>
"
4 | "Version: 1.0
"
5 |
6 | /*
7 | Original board dimension code came from https://gist.github.com/itavero/8042433
8 | CAM code comes from https://www.element14.com/community/thread/22904/l/re-can-a-ulp-initiate-a-cam-job?displayFullThread=true
9 |
10 | See EAGLE help file for "Command Line Options"
11 |
12 | The ZIP creation relies on 7zip. Specifically 7za.exe the stand-alone version of 7zip. To get this you need
13 | to first install 7zip, then download the "7-zip Extra" 7z stand alone console version. Use 7zip to open the 7z
14 | archive. In the archive you should see the 7za.exe file. Put this in the same directory as this ULP.
15 |
16 | TODO:
17 |
18 | Add option to preview in gerbV upon completion
19 |
20 | https://forums.autodesk.com/t5/eagle-forum/generate-manufacturing-data-from-a-terminal/m-p/7778090/highlight/true#M10377
21 |
22 | eaglecon -X -dCAMJOB -j"C:\Users\OldLenny\Dropbox\Projects\SparkFun_Eagle_Settings\cam\sfe-gerb274x_newProcessor.cam" -o"C:\Users\OldLenny\Dropbox\Projects\BlackBoard\Hardware\Production" "C:\Users\OldLenny\Dropbox\Projects\BlackBoard\Hardware\Production\BlackBoard-Panel.brd"
23 | 42 seconds to CAM the BlackBoard panel (8.8 x 7.2" with massive amounts of intense silkscreen artifacts)
24 | */
25 |
26 | string configFile = filesetext(argv[0], ".cfg");
27 |
28 | string bottomPackages = "";
29 |
30 | //Config options we want to save
31 | int outputGerbers = 1;
32 | int outputTopStencil = 1;
33 | int outputBottomStencil = 1;
34 | int zipOutput = 1;
35 | int runGerbV = 1;
36 |
37 | void configWrite()
38 | {
39 | output(configFile)
40 | {
41 | printf("%d\n", outputGerbers);
42 | printf("%d\n", outputTopStencil);
43 | printf("%d\n", outputBottomStencil);
44 | printf("%d\n", zipOutput);
45 | printf("%d\n", runGerbV);
46 | }
47 | }
48 |
49 | void configRead()
50 | {
51 | if (filesize(configFile))
52 | { //Check if file exists
53 | string data[];
54 | int line = fileread(data, configFile);
55 | if (line >= 4)
56 | {
57 | outputGerbers = strtol(data[0]);
58 | outputTopStencil = strtol(data[1]);
59 | outputBottomStencil = strtol(data[2]);
60 | zipOutput = strtol(data[3]);
61 | runGerbV = strtol(data[4]);
62 | }
63 | }
64 | }
65 |
66 | //Finds a string in a string no matter where, no matter capitalization
67 | int containsString(string toSearch, string toFind)
68 | {
69 | int pos = strstr(strlwr(toSearch), strlwr(toFind));
70 | if (pos >= 0) //String found
71 | {
72 | return (1);
73 | }
74 |
75 | return (0);
76 | }
77 |
78 | //Detect if board has four layers
79 | //This was re-written to scan only for signal wires on internals layers becaused things like a microB connector uses polygons on layers 2/15
80 | int hasFourLayers()
81 | {
82 | //Old way
83 | /*board(B) {
84 | B.layers(L) {
85 | if(L.used == 1 && L.number == 2)
86 | {
87 | return(1);
88 | }
89 | if(L.used == 1 && L.number == 15)
90 | {
91 | return(1);
92 | }
93 | }
94 | }*/
95 |
96 | board(B)
97 | {
98 | B.signals(S)
99 | {
100 | S.wires(W)
101 | {
102 | if (W.layer == 2)
103 | {
104 | return (1);
105 | }
106 | if (W.layer == 15)
107 | {
108 | return (1);
109 | }
110 | }
111 | }
112 | }
113 | return (0); //Nope
114 | }
115 |
116 | //Detect if board has six layers
117 | int hasSixLayers()
118 | {
119 | board(B)
120 | {
121 | B.signals(S)
122 | {
123 | S.wires(W)
124 | {
125 | if (W.layer == 3)
126 | {
127 | return (1);
128 | }
129 | if (W.layer == 14)
130 | {
131 | return (1);
132 | }
133 | }
134 | }
135 | }
136 | return (0); //Nope
137 | }
138 |
139 | //Detect if parts are on a given layer of the board
140 | int hasPartsOnLayer(int layerNumber)
141 | {
142 | board(B)
143 | {
144 | B.elements(E)
145 | {
146 | E.package.contacts(C)
147 | {
148 | if (C.smd && C.smd.layer == layerNumber)
149 | {
150 |
151 | //Ignore
152 | //Fiducials, jumpers with traces as closure method, jumpers that are normally open
153 | if (containsString(E.package.name, "fiducial") == 0 && containsString(E.package.name, "NC_TRACE") == 0 && containsString(E.package.name, "NC_BY_TRACE") == 0 && containsString(E.package.name, "SJ_2S-NO") == 0 && containsString(E.package.name, "SMT-JUMPER") == 0 && containsString(E.package.name, "USB-MICROB-PTH-MILL") == 0 && containsString(E.package.name, "USB-C") == 0 && containsString(E.package.name, "PAD.03X.03") == 0 //Test points
154 | && containsString(E.package.name, "PAD.03X.05") == 0 && containsString(E.package.name, "USB-SOLDER-PADS") == 0)
155 | {
156 | //String not found, this is a legit part
157 | bottomPackages += E.package.name + ",";
158 | return (1);
159 | }
160 | }
161 | }
162 | }
163 | }
164 |
165 | return (0); //Nope
166 | }
167 |
168 | //Detect if parts are on the top of the board
169 | int hasTopParts()
170 | {
171 | return (hasPartsOnLayer(1));
172 | }
173 |
174 | //Detect if parts are on the bottom of the board
175 | int hasBottomParts()
176 | {
177 | return (hasPartsOnLayer(16));
178 | }
179 |
180 | string get_project_path()
181 | {
182 | if (board)
183 | board(B) return (filedir(B.name));
184 | if (schematic)
185 | schematic(B) return (filedir(B.name));
186 | }
187 |
188 | //Change any / in a string to \
189 | //Useful for directory structure before calling a cmd
190 | string convertForwardToBackSlashes(string thing)
191 | {
192 | //Convert forward slashes to back slashes so we can run system command
193 | int pos = strrchr(thing, '/');
194 | while (pos >= 0)
195 | {
196 | //thing = strsub(thing, 0, pos) + "\\\\" + strsub(thing, pos + 1, strlen(thing)); //Remove and replace
197 | thing = strsub(thing, 0, pos) + "\\" + strsub(thing, pos + 1, strlen(thing)); //Remove and replace
198 | pos = strrchr(thing, '/'); //Look for the next forward slash
199 | }
200 | return (thing);
201 | }
202 |
203 | //Returns true if a file exists
204 | int FileExists(string name)
205 | {
206 | string files[];
207 | return (fileglob(files, name) != 0);
208 | }
209 |
210 | //CAM the current BRD file
211 | void createGerbers()
212 | {
213 | //Get the name of this brd (no extension, no directory)
214 | string baseFileName = "";
215 | board(B)
216 | {
217 | baseFileName = filesetext(filename(B.name), "");
218 | }
219 |
220 | //Convert forward slashes to back slashes so we can run system commands
221 | string projectDirectory = convertForwardToBackSlashes(get_project_path());
222 |
223 | string commandToRun = "echo Relax. This can take a minute..."; //This is the start of the command. /C = close window
224 | //string commandToRun = "cmd.exe /K echo Relax. This can take a minute..."; //This is the start of the command. /C = close window
225 | string s = "";
226 |
227 | //Remove any files in the production folder left over from previous panel CAM
228 | //There's a chance that a previous ULP job creates files that should not be zipped.
229 | commandToRun += " && echo Removing old files";
230 |
231 | string fileLocation = "";
232 | sprintf(fileLocation, "%s%s.G*", get_project_path(), baseFileName); //Search for file using forward slashes
233 | if (FileExists(fileLocation))
234 | {
235 | sprintf(s, "rm -rf \"%s%s.G*\"", projectDirectory, baseFileName); //Remove file with back slashes
236 | commandToRun += " && " + s;
237 | }
238 |
239 | sprintf(fileLocation, "%s%s.TXT", get_project_path(), baseFileName);
240 | if (FileExists(fileLocation))
241 | {
242 | sprintf(s, "rm -rf \"%s%s.TXT\"", projectDirectory, baseFileName);
243 | commandToRun += " && " + s;
244 | }
245 |
246 | sprintf(fileLocation, "%s%s.ZIP", get_project_path(), baseFileName);
247 | if (FileExists(fileLocation))
248 | {
249 | sprintf(s, "rm -rf \"%s%s.ZIP\"", projectDirectory, baseFileName);
250 | commandToRun += " && " + s;
251 | }
252 |
253 | sprintf(fileLocation, "%s%s.dri", get_project_path(), baseFileName);
254 | if (FileExists(fileLocation))
255 | {
256 | sprintf(s, "rm -rf \"%s%s.dri\"", projectDirectory, baseFileName);
257 | commandToRun += " && " + s;
258 | }
259 |
260 | //The new version of Eagle (v8/9) has a faster CAM processor. We call it with the CAM file and we get gerbers out.
261 | sprintf(s, " && echo Running New CAM Processor on %s", baseFileName);
262 | commandToRun += s;
263 |
264 | //1,217 seconds to complete CAM using old method
265 | //42 seconds to CAM the BlackBoard panel (8.8 x 7.2" with massive amounts of intense silkscreen artifacts)
266 | //28 times faster!
267 |
268 | //Run CAM file from EagleCon
269 |
270 | //Find the user's directory containing the SparkFun CAM files
271 | string pathToCAMs = "";
272 | for (int x = 0; x < 20; x++)
273 | {
274 | string thisDirectory = path_cam[x];
275 | if (strlen(thisDirectory) == 0)
276 | {
277 | dlgMessageBox("Could not find the sfe-gerb* CAM files. Have you loaded the SparkFun_Eagle_Settings folders into the EAGLE 'Directories' menu correctly?");
278 | exit(-1);
279 | }
280 |
281 | sprintf(fileLocation, "%s/sfe-gerb274*.cam", thisDirectory);
282 | if (FileExists(fileLocation))
283 | {
284 | pathToCAMs = thisDirectory;
285 | break;
286 | }
287 | }
288 |
289 | string camFileLocation = pathToCAMs + "/sfe-gerb274x-2layer.cam"; //You must have the SparkFun CAM files in the CAM directory setting so that Eagle can find this file
290 |
291 | if (hasSixLayers() == 1)
292 | camFileLocation = pathToCAMs + "/sfe-gerb274x-6layer.cam"; //You must have the SparkFun CAM files in the CAM directory setting so that Eagle can find this file
293 | else if (hasFourLayers() == 1)
294 | camFileLocation = pathToCAMs + "/sfe-gerb274x-4layer.cam"; //You must have the SparkFun CAM files in the CAM directory setting so that Eagle can find this file
295 |
296 | sprintf(fileLocation, "%s%s.brd", get_project_path(), baseFileName);
297 |
298 | sprintf(s, " \"%s/eagle\" -X -dCAMJOB -j\"%s\" -o\"%s\" \"%s\"",
299 | EAGLE_DIR,
300 | camFileLocation,
301 | get_project_path(),
302 | fileLocation);
303 |
304 | commandToRun += " && " + s;
305 |
306 | //This is the old way of generating gerbers. It works, but it's very slow.
307 | /*
308 | //Generate Gerbers
309 | string fileExtension = "";
310 | string layerNumbers = "";
311 | string device = "";
312 | string mirror = "";
313 | for (int x = 0; x < 12; x++)
314 | {
315 | if (x == 0) //Top copper
316 | {
317 | if (outputGerbers == 0)
318 | continue;
319 | fileExtension = "GTL";
320 | layerNumbers = "1 17 18";
321 | commandToRun += " && echo Running Top Copper";
322 | }
323 | else if (x == 1) //Top silk
324 | {
325 | if (outputGerbers == 0)
326 | continue;
327 | fileExtension = "GTO";
328 | layerNumbers = "21";
329 | commandToRun += " && echo Running Top Silk";
330 | }
331 | else if (x == 2) //Top mask
332 | {
333 | if (outputGerbers == 0)
334 | continue;
335 | fileExtension = "GTS";
336 | layerNumbers = "29";
337 | commandToRun += " && echo Running Top Mask";
338 | }
339 | else if (x == 3) //Bottom copper
340 | {
341 | if (outputGerbers == 0)
342 | continue;
343 | fileExtension = "GBL";
344 | layerNumbers = "16 17 18";
345 | commandToRun += " && echo Running Bottom Copper";
346 | }
347 | else if (x == 4) //Bottom silk
348 | {
349 | if (outputGerbers == 0)
350 | continue;
351 | fileExtension = "GBO";
352 | layerNumbers = "22";
353 | commandToRun += " && echo Running Bottom Silk";
354 | }
355 | else if (x == 5) //Bottom mask
356 | {
357 | if (outputGerbers == 0)
358 | continue;
359 | fileExtension = "GBS";
360 | layerNumbers = "30";
361 | commandToRun += " && echo Running Bottom Mask";
362 | }
363 | else if (x == 6) //Outline/keepout
364 | {
365 | if (outputGerbers == 0)
366 | continue;
367 | fileExtension = "GKO";
368 | layerNumbers = "20 46"; //Turn on dimension and milling (contains v-score indicators) layers
369 | commandToRun += " && echo Running Board Outline";
370 | }
371 | else if (x == 7) //Top paste
372 | {
373 | if (outputTopStencil == 0)
374 | continue;
375 | fileExtension = "GTP";
376 | layerNumbers = "31";
377 | commandToRun += " && echo Running Top Paste";
378 | }
379 | else if (x == 8) //Bottom paste
380 | {
381 | if (outputBottomStencil == 0)
382 | continue;
383 | if (hasBottomParts() == 0)
384 | continue;
385 | fileExtension = "GBP";
386 | layerNumbers = "32";
387 | commandToRun += " && echo Running Bottom Paste";
388 | }
389 | else if (x == 9) //Drill file
390 | {
391 | if (outputGerbers == 0)
392 | continue;
393 | fileExtension = "TXT";
394 | layerNumbers = "44 45";
395 | commandToRun += " && echo Running Drill File";
396 | }
397 | else if (x == 10) //Inner layer 2
398 | {
399 | if (outputGerbers == 0)
400 | continue;
401 | if (hasFourLayers() == 0)
402 | continue;
403 | fileExtension = "GL2";
404 | layerNumbers = "2 17 18";
405 | commandToRun += " && echo Running Layer 2";
406 | }
407 | else if (x == 11) //Inner layer 15
408 | {
409 | if (outputGerbers == 0)
410 | continue;
411 | if (hasFourLayers() == 0)
412 | continue;
413 | fileExtension = "GL3";
414 | layerNumbers = "15 17 18";
415 | commandToRun += " && echo Running Layer 15";
416 | }
417 |
418 | //Deal with special layers
419 | device = "GERBER_RS274X";
420 | if (x == 9)
421 | device = "EXCELLON_24"; //Drill file
422 |
423 | mirror = "-m-"; //No mirror
424 | //if(x == 8) mirror = "-m+"; //Mirror the bottom paste layer
425 |
426 | //Add this CAM operation to the list
427 | sprintf(s, " \"%s/eagle\" -X -N- %s -f+ -O+ -c+ -x0 -y0 -d%s -o \"%s.%s\" \"%s\" %s",
428 | EAGLE_DIR,
429 | mirror,
430 | device,
431 | baseFileName,
432 | fileExtension,
433 | projectDirectory + baseFileName + ".brd",
434 | layerNumbers);
435 |
436 | commandToRun += " && " + s;
437 | }*/
438 |
439 | //Zip files using 7za (7za.exe should be located in same directory as ULP)
440 | if (zipOutput == 1)
441 | {
442 | string sevenZaLocation = convertForwardToBackSlashes(filedir(argv[0]));
443 | sevenZaLocation += "\\7za.exe";
444 |
445 | string outputFileName = projectDirectory + baseFileName + ".zip";
446 |
447 | //Get all the wanted files
448 | string fileList = "";
449 | fileList += "\"" + projectDirectory + baseFileName + ".GTL" + "\"";
450 | fileList += " \"" + projectDirectory + baseFileName + ".GTO" + "\"";
451 | fileList += " \"" + projectDirectory + baseFileName + ".GTS" + "\"";
452 |
453 | fileList += " \"" + projectDirectory + baseFileName + ".GBL" + "\"";
454 | fileList += " \"" + projectDirectory + baseFileName + ".GBO" + "\"";
455 | fileList += " \"" + projectDirectory + baseFileName + ".GBS" + "\"";
456 |
457 | if (hasSixLayers() == 1)
458 | {
459 | fileList += " \"" + projectDirectory + baseFileName + ".GL2" + "\"";
460 | fileList += " \"" + projectDirectory + baseFileName + ".GL3" + "\"";
461 | fileList += " \"" + projectDirectory + baseFileName + ".GL4" + "\"";
462 | fileList += " \"" + projectDirectory + baseFileName + ".GL5" + "\"";
463 | }
464 | else if (hasFourLayers() == 1)
465 | {
466 | fileList += " \"" + projectDirectory + baseFileName + ".GL2" + "\"";
467 | fileList += " \"" + projectDirectory + baseFileName + ".GL3" + "\"";
468 | }
469 |
470 | fileList += " \"" + projectDirectory + baseFileName + ".GKO" + "\"";
471 |
472 | fileList += " \"" + projectDirectory + baseFileName + ".TXT" + "\""; //Get drill file
473 |
474 | fileList += " \"" + projectDirectory + "ordering_instructions.txt" + "\""; //Send the ordering instructions as an extra precaution
475 |
476 | if (outputTopStencil == 1)
477 | {
478 | fileList += " \"" + projectDirectory + baseFileName + ".GTP" + "\"";
479 | }
480 | if (outputBottomStencil == 1 && hasBottomParts() == 1)
481 | {
482 | fileList += " \"" + projectDirectory + baseFileName + ".GBP" + "\"";
483 | }
484 |
485 | sprintf(s, "\"%s\" a \"%s\" %s",
486 | sevenZaLocation,
487 | outputFileName,
488 | fileList);
489 |
490 | commandToRun += " && " + s;
491 | }
492 |
493 | if (runGerbV == 1)
494 | {
495 | string gerbVLocation = convertForwardToBackSlashes(filedir(argv[0]));
496 | gerbVLocation += "\\gerbv.exe";
497 |
498 | //Get all the wanted files
499 | string fileList = "";
500 | fileList += "\"" + projectDirectory + baseFileName + ".GTL" + "\"";
501 | fileList += " \"" + projectDirectory + baseFileName + ".GTO" + "\"";
502 | fileList += " \"" + projectDirectory + baseFileName + ".GTS" + "\"";
503 |
504 | fileList += " \"" + projectDirectory + baseFileName + ".GBL" + "\"";
505 | fileList += " \"" + projectDirectory + baseFileName + ".GBO" + "\"";
506 | fileList += " \"" + projectDirectory + baseFileName + ".GBS" + "\"";
507 |
508 | if (hasSixLayers() == 1)
509 | {
510 | fileList += " \"" + projectDirectory + baseFileName + ".GL2" + "\"";
511 | fileList += " \"" + projectDirectory + baseFileName + ".GL3" + "\"";
512 | fileList += " \"" + projectDirectory + baseFileName + ".GL4" + "\"";
513 | fileList += " \"" + projectDirectory + baseFileName + ".GL5" + "\"";
514 | }
515 | else if (hasFourLayers() == 1)
516 | {
517 | fileList += " \"" + projectDirectory + baseFileName + ".GL2" + "\"";
518 | fileList += " \"" + projectDirectory + baseFileName + ".GL3" + "\"";
519 | }
520 |
521 | fileList += " \"" + projectDirectory + baseFileName + ".GKO" + "\"";
522 |
523 | fileList += " \"" + projectDirectory + baseFileName + ".TXT" + "\""; //Get drill file
524 |
525 | if (outputTopStencil == 1)
526 | {
527 | fileList += " \"" + projectDirectory + baseFileName + ".GTP" + "\"";
528 | }
529 | if (outputBottomStencil == 1 && hasBottomParts() == 1)
530 | {
531 | fileList += " \"" + projectDirectory + baseFileName + ".GBP" + "\"";
532 | }
533 |
534 | sprintf(s, "\"%s\" %s",
535 | gerbVLocation,
536 | fileList);
537 |
538 | commandToRun += " && " + s;
539 | }
540 |
541 | //dlgMessageBox(commandToRun);
542 | if (system(commandToRun) != 0)
543 | {
544 | dlgMessageBox("Error: Command failed.", "OK");
545 | }
546 | else
547 | {
548 | dlgMessageBox("Gerber generation complete.");
549 | }
550 | }
551 |
552 | if (board)
553 | {
554 | configRead(); //Read any settings if available
555 |
556 | //GUI
557 | int dstatus = dlgDialog("Gerber Generation Options")
558 | {
559 |
560 | dlgHBoxLayout { dlgSpacing(300); }
561 |
562 | if (hasSixLayers() == 1)
563 | {
564 | dlgHBoxLayout { dlgLabel("Note: This is a six layer board\t"); }
565 | }
566 | else if (hasFourLayers() == 1)
567 | {
568 | dlgHBoxLayout { dlgLabel("Note: This is a four layer board\t"); }
569 | }
570 | if (hasBottomParts() == 1)
571 | {
572 | dlgHBoxLayout
573 | {
574 | dlgLabel("Note: This board has parts on bottom side:
" + bottomPackages);
575 | }
576 | outputBottomStencil = 1; //Persuade user to generate these gerbers
577 | }
578 | else
579 | {
580 | dlgHBoxLayout { dlgLabel("This board does not have parts on bottom side\t"); }
581 | outputBottomStencil = 0;
582 | }
583 |
584 | dlgHBoxLayout { dlgLabel("\t"); }
585 |
586 | dlgGroup("Output Files")
587 | {
588 | dlgHBoxLayout { dlgCheckBox("Gerbers", outputGerbers); }
589 | dlgHBoxLayout { dlgCheckBox("Top Stencil", outputTopStencil); }
590 | dlgHBoxLayout { dlgCheckBox("Bottom Stencil", outputBottomStencil); }
591 | dlgHBoxLayout { dlgCheckBox("Zip Output Files", zipOutput); }
592 | }
593 |
594 | dlgHBoxLayout { dlgCheckBox("Run gerbV upon completion", runGerbV); }
595 |
596 | dlgPushButton("+Generate")
597 | {
598 | configWrite(); //Record current settings
599 |
600 | createGerbers(); //Generate gerbers for this BRD
601 |
602 | //Preview in gerbV
603 |
604 | dlgAccept(-1);
605 | }
606 |
607 | dlgStretch(1);
608 | };
609 |
610 | configWrite(); //Record current settings
611 | }
612 | else
613 | {
614 | dlgMessageBox("Please run SparkFun CAMmer from a board.");
615 | exit(1);
616 | }
617 |
--------------------------------------------------------------------------------
/ulp/SparkFun-Flip.ulp:
--------------------------------------------------------------------------------
1 | #usage "en: Flip the entire design around X midpoint. Very helpful for placing bottom silk correctly."
2 | "Usage: run sparkfun-flip
"
3 | "Author: Nathan Seidle <inathan@sparkfun.com>
"
4 | "Version: 1.0
"
5 |
6 | //Original board dimension code came from https://gist.github.com/itavero/8042433
7 |
8 | string bigScript = ""; //The big string of commands that we will eventually run as a script
9 |
10 | real xMax = 0;
11 | real yMax = 0;
12 | real xMin = 0;
13 | real yMin = 0;
14 |
15 | void flip() {
16 | //Determine the current grid type and size
17 | int originalGridUnit; //1 = mm, 3 = inches
18 | board(B) {
19 | originalGridUnit = B.grid.unit;
20 | }
21 |
22 | //Turn on everything. Group everything.
23 | bigScript += "DISPLAY ALL; GROUP ALL;\n";
24 |
25 | //Change grid to inches
26 | bigScript += "GRID INCH ON;\n";
27 |
28 | //Mirror everything around the mid point of this design
29 | string s = "";
30 | sprintf(s, "MIRROR (>%.5f 0);\n", xMax/2);
31 | bigScript += s;
32 |
33 | //Return grid to original settings
34 | if(originalGridUnit == GRID_UNIT_MIC) //mic
35 | {
36 | bigScript += "GRID MIC ON;\n";
37 | }
38 | if(originalGridUnit == GRID_UNIT_MM) //mm
39 | {
40 | bigScript += "GRID MM ON;\n";
41 | }
42 | if(originalGridUnit == GRID_UNIT_MIL) //mil
43 | {
44 | bigScript += "GRID MIL ON;\n";
45 | }
46 | if(originalGridUnit == GRID_UNIT_INCH) //inch
47 | {
48 | bigScript += "GRID IN ON;\n";
49 | }
50 |
51 | //Turn on default layers
52 | bigScript += "DISPLAY NONE; DISPLAY 1 2 15 16 17 18 19 20 21 22 23 24 45 46 51; DISPLAY -25 -26 -27 -28;\n";
53 |
54 | //This clears the group selection
55 | bigScript += "GROUP;\n";
56 | }
57 |
58 | //Look at board dimensions and components
59 | //Find the min/max coordinates of the design
60 | void calculateDesignDimensions()
61 | {
62 | //Find min/max dimensions of this board
63 | char firstPoint = 'y';
64 | char firstPointOverhang = 'y';
65 |
66 | board(B) {
67 | B.wires(W) {
68 | if (W.layer == LAYER_DIMENSION) {
69 | // Wire is on dimension layer
70 | real wx1 = u2inch(W.x1);
71 | real wy1 = u2inch(W.y1);
72 | real wx2 = u2inch(W.x2);
73 | real wy2 = u2inch(W.y2);
74 |
75 | // Start point of wire
76 | if (firstPoint == 'y') {
77 | firstPoint = 'n';
78 | xMax = wx1;
79 | xMin = wx1;
80 | yMax = wy1;
81 | yMin = wy1;
82 | }
83 | else {
84 | if (wx1 > xMax) {
85 | xMax = wx1;
86 | }
87 | if (wx1 < xMin) {
88 | xMin = wx1;
89 | }
90 | if (wy1 > yMax) {
91 | yMax = wy1;
92 | }
93 | if (wy1 < yMin) {
94 | yMin = wy1;
95 | }
96 | }
97 |
98 | // End point of wire
99 | if (wx2 > xMax) {
100 | xMax = wx2;
101 | }
102 | if (wx2 < xMin) {
103 | xMin = wx2;
104 | }
105 | if (wy2 > yMax) {
106 | yMax = wy2;
107 | }
108 | if (wy2 < yMin) {
109 | yMin = wy2;
110 | }
111 | }
112 | }
113 | }
114 |
115 | //Check if this design has dimension lines. If it doesn't then it's probably a DXF import of an enclosure or something very weird.
116 | if(xMin == 0 && yMax == 0)
117 | {
118 | dlgMessageBox("!This board has no dimension lines. Cannot flip. Exiting.");
119 | exit(-1);
120 | }
121 | }
122 |
123 | if (board)
124 | {
125 | calculateDesignDimensions(); //Find the max X of the design
126 |
127 | flip(); //Flip the design
128 |
129 | exit(bigScript); //Execute this generated script
130 | }
131 | else
132 | {
133 | dlgMessageBox("Please run SparkFun Flip ULP from a board.");
134 | exit(1);
135 | }
--------------------------------------------------------------------------------
/ulp/Trace-Length.ulp:
--------------------------------------------------------------------------------
1 | /*
2 | This ULP was originally created by EAGLE PCB by
3 | "A. Zaffran 05.04.2000 alf@cadsoft.de"
4 |
5 | Modified November 18th, 2020 by N. Seidle to make nets searchable.
6 | Often there are 2 or 5 nets you need to match lengths.
7 |
8 | THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
9 | */
10 |
11 | real f, WLtotal;
12 | int index[];
13 |
14 | // ** aus "Mechanik der Elektronik"
15 | // mm <1 1 2 3 4 5 6 7 8 9 10 11 12 13 mm Leiterbreite bei 35 um Cu
16 |
17 | real k[] = {9, 8.8, 6, 4, 3.2, 2.9, 2.9, 2.9, 2.9, 2.9, 2.9, 2.9, 2.9, 2.9, 2.9};
18 |
19 | // _______________________
20 | // Imax ~ 5.25 V [d x b x (d + b)] x k || (tL ~60°)
21 | //
22 | // d = um Cu-Kaschierung
23 | // b = Breite mm
24 | // k = Korrekturwert aus Tabelle 02.02.2000 alf
25 | // ** aus "Mechanik der Elektronik"
26 |
27 | real Cu = 0.035; // 35 um Cu Kaschierung
28 |
29 | real Length[], Freq[], Widthmin[], Widthmax[];
30 | string Signal[];
31 |
32 | real c = 299800; // Lichtgechwindigkeit Vakuum in [km/s]
33 |
34 | int n = 0;
35 | int t;
36 | string data[];
37 | string h;
38 | int note = 0;
39 |
40 | int true = 1;
41 | int false = 0;
42 | int abort = false;
43 | string netFilter = "CC";
44 |
45 | //Get the name of this brd (no extension, no directory)
46 | string get_project_name()
47 | {
48 | if (board)
49 | board(B) return (filesetext(filename(B.name), ""));
50 | if (schematic)
51 | schematic(B) return (filesetext(filename(B.name), ""));
52 | }
53 |
54 | string get_project_path()
55 | {
56 | if (board)
57 | board(B) return (filedir(B.name));
58 | if (schematic)
59 | schematic(B) return (filedir(B.name));
60 | }
61 |
62 | void configWrite()
63 | {
64 | //Get the name of this brd (no extension, no directory)
65 | string baseFileName = get_project_name();
66 | string configFile = get_project_path() + baseFileName + "-TraceLength.txt";
67 |
68 | output(configFile)
69 | {
70 | printf("%s\n", netFilter);
71 | }
72 | }
73 |
74 | void configRead()
75 | {
76 | //Get the name of this brd (no extension, no directory)
77 | string baseFileName = get_project_name();
78 | string configFile = get_project_path() + baseFileName + "-TraceLength.txt";
79 |
80 | if (filesize(configFile))
81 | { //Check if file exists
82 | string data[];
83 | int line = fileread(data, configFile);
84 | if (line >= 0)
85 | {
86 | netFilter = data[0];
87 | }
88 | }
89 | }
90 |
91 | void dialog(void)
92 | {
93 | int select = 0;
94 | int Result = dlgDialog("Wire length of Layout")
95 | {
96 | dlgLabel("List of signals with length and its max. frequency / current\n");
97 |
98 | string lab;
99 | sprintf(lab, " Cu thickness = %.3f mm", Cu);
100 | dlgLabel(lab);
101 | dlgListView("", data, select);
102 | dlgStretch(0);
103 |
104 | dlgHBoxLayout
105 | {
106 | dlgStretch(1);
107 | dlgLabel("&Filters");
108 | dlgStringEdit(netFilter);
109 | dlgPushButton("+Apply")
110 | {
111 | abort = false;
112 | dlgAccept();
113 | }
114 | dlgPushButton("-Close")
115 | {
116 | abort = true;
117 | dlgReject();
118 | }
119 | }
120 | };
121 | }
122 |
123 | real WireLength(real x1, real x2, real y1, real y2)
124 | {
125 | return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
126 | }
127 |
128 | real ArcLength(real ang1, real ang2, real radius)
129 | {
130 | return radius * 2 * PI / 360 * (ang2 - ang1);
131 | }
132 |
133 | real Frequency(real c, real l)
134 | {
135 | return c / l;
136 | }
137 |
138 | void WireWidth(string sig, real w)
139 | {
140 | // ermitteln der min-max Leiterbahnbreite
141 | if (w < Widthmin[n])
142 | Widthmin[n] = w;
143 | if (w > Widthmax[n])
144 | Widthmax[n] = w;
145 | }
146 |
147 | //Finds a string in a string no matter where, no matter capitalization
148 | int containsString(string toSearch, string toFind)
149 | {
150 | int pos = strstr(strlwr(toSearch), strlwr(toFind));
151 | if (pos >= 0) //String found
152 | {
153 | return (1);
154 | }
155 |
156 | return (0);
157 | }
158 |
159 | real imax(real breite)
160 | {
161 | return (breite == 0) ? 0 : 5.25 * sqrt((Cu * breite * (Cu + breite)) * k[int(trunc(breite))]);
162 | }
163 |
164 | if (board)
165 | {
166 | configRead(); //Get previous netFilter
167 |
168 | //Loop until user presses close button
169 | while (abort == false)
170 | {
171 | //dlgMessageBox(netFilter);
172 | for (int x = 0; x < n; x++)
173 | data[x] = "";
174 | n = 0;
175 |
176 | board(B)
177 | {
178 | B.signals(S)
179 | {
180 | WLtotal = 0;
181 | Widthmin[n] = 32000;
182 | Widthmax[n] = 0;
183 | S.wires(W)
184 | {
185 | if (W.layer < 17)
186 | { // nur Kupfer-Layer
187 | if (W.arc)
188 | {
189 | WLtotal += ArcLength(W.arc.angle1, W.arc.angle2, u2mm(W.arc.radius));
190 | }
191 | else
192 | {
193 | WLtotal += WireLength(u2mm(W.x2), u2mm(W.x1), u2mm(W.y2), u2mm(W.y1));
194 | }
195 | WireWidth(S.name, u2mm(W.width));
196 | }
197 | }
198 | if (WLtotal != 0)
199 | {
200 | if (containsString(S.name, netFilter))
201 | {
202 | Signal[n] = S.name;
203 | Length[n] = WLtotal;
204 | Freq[n] = Frequency(c, WLtotal);
205 | ++n;
206 | }
207 | }
208 | }
209 | sort(n, index, Freq);
210 |
211 | sprintf(h, "Signal\tf max. [MHz]\tl [mm]\tA [mm2]\tR [mOhm]\tw min [mm]\tw max [mm]\tImax [A]");
212 | data[0] = h;
213 | t = 1;
214 |
215 | for (int i = 0; i < n; ++i)
216 | {
217 | real mm2 = Widthmin[index[i]] * Cu;
218 | real mOhm = 0;
219 | string R;
220 | if (Widthmin[index[i]])
221 | {
222 | mOhm = (174 * Length[index[i]] / 10) / (Cu * 1000 * Widthmin[index[i]]);
223 | sprintf(R, "%7.2f", mOhm);
224 | }
225 |
226 | sprintf(h, "%s\t%10.2f\t%7.3f\t%4.3f\t%s\t%6.3f\t%6.3f\t%6.2f", Signal[index[i]], Freq[index[i]], Length[index[i]], mm2, R, Widthmin[index[i]], Widthmax[index[i]], imax(Widthmin[index[i]]));
227 | data[t] = h;
228 |
229 | if (!Widthmin[index[i]])
230 | {
231 | note = 1;
232 | sprintf(h, " ***");
233 | data[t] += h;
234 | }
235 | t++;
236 | }
237 |
238 | dialog();
239 | }
240 | configWrite(); //Get previous netFilter
241 | }
242 | }
243 | else
244 | {
245 | dlgMessageBox("\n Start this ULP in a Board \n");
246 | exit(0);
247 | }
248 |
--------------------------------------------------------------------------------
/ulp/Unrouted.ulp:
--------------------------------------------------------------------------------
1 | /*
2 | * UNROUTED.ULP
3 | *
4 | * simple script to zoom to the first unrouted wire in board editor.
5 | * this might be helpful when searching for tiny left-overs.
6 | *
7 | * done by Daniel Mack , http://caiaq.de
8 | */
9 |
10 | int gridunit;
11 |
12 | real u2u(int val) {
13 | switch (gridunit) {
14 | case GRID_UNIT_MIC : return u2mic(val);
15 | case GRID_UNIT_MM : return u2mm(val);
16 | case GRID_UNIT_MIL : return u2mil(val);
17 | case GRID_UNIT_INCH : return u2inch(val);
18 | }
19 | }
20 |
21 | string RunOnExit = "";
22 |
23 | if (board) {
24 | board(B) {
25 | gridunit = (B.grid.unit);
26 | B.signals(S) {
27 | S.wires(W) {
28 | if (W.layer == 19) {
29 | real x1 = u2u(W.x1);
30 | real x2 = u2u(W.x2);
31 | real y1 = u2u(W.y1);
32 | real y2 = u2u(W.y2);
33 |
34 | x1 -= (x2 - x1) / 2;
35 | x2 += (x2 - x1) / 2;
36 | y1 -= (y2 - y1) / 2;
37 | y2 += (y2 - y1) / 2;
38 |
39 | sprintf(RunOnExit, "\nWINDOW (%.6f %.6f) (%.6f %.6f);\n", x1, y1, x2, y2);
40 | exit (RunOnExit);
41 | }
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ulp/add+mod-attributes.ulp:
--------------------------------------------------------------------------------
1 | #usage "en: Modify attributes on all devices/technologies within a given library"
2 | "Usage: run add+mod-attributes
"
3 | "Author: Owen Lyke
"
4 | "Version: 1.0.0
"
5 | "Allows you to add/remove attributes to/from all devices and variants in a library. Supports specification of constant or variable as well as defualt value"
6 |
7 |
8 |
9 |
10 | int MAX_NUM_ROWS = 10;
11 | int num_rows = 1;
12 | int setup_complete = 0;
13 |
14 | string option_strings[] = {"variable", "constant", "DELETE"};
15 | string labels[] = {"Enter Label", "Enter Label", "Enter Label", "Enter Label", "Enter Label", "Enter Label", "Enter Label", "Enter Label", "Enter Label", "Enter Label"};
16 | int options[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
17 | string values[] = {"Enter Value", "Enter Value", "Enter Value", "Enter Value", "Enter Value", "Enter Value", "Enter Value", "Enter Value", "Enter Value", "Enter Value"};
18 | int overwrite_val[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
19 | int attr_val_pre_exists[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
20 |
21 |
22 | int result = 0;
23 |
24 |
25 | // Used by set-all-devices-attribute.ulp
26 | string ScriptFile = "";
27 | string cmdScript, cmd, s;
28 |
29 | string Lines[], Attribut[], AttValue[];
30 | int setAtt[];
31 | int cntl = 0;
32 | int cntAtt = 0;
33 |
34 | if (argv[1] == "?") {
35 | dlgMessageBox(usage, "OK");
36 | }
37 |
38 | void test(void) {
39 | dlgDialog(filename(argv[0]) + " Script") {
40 | dlgTextView(cmd);
41 | dlgHBoxLayout {
42 | dlgPushButton("OK") dlgAccept();
43 | dlgPushButton("Abbruch") { dlgReject(); exit(-2); }
44 | }
45 | };
46 | return;
47 | }
48 |
49 |
50 | string check_varname(string s) { // 2008-09-04
51 | if(s == "''") return s;
52 | return "'"+s+"'";
53 | }
54 |
55 |
56 | if(library){
57 |
58 | // // Setup
59 | while(setup_complete == 0)
60 | {
61 | dlgDialog("Add Attribute - Setup"){
62 |
63 | dlgLabel("This is the Add Attribute ULP \n\n\
64 | You may add up to 10 rows, and must have at least one row. \n\
65 | Each row allows you to add or modify an attribute for ALL devices and technologies in the library. \n\
66 | Label: case-insensitive label of the attribute. Also the 'name' of the attribute. \n\
67 | Type: allows you to choose to set the attribute to constant or variable. Also allows removal of all attributes with the given name. \n\
68 | Value: the value to fill in for each attribute. Leave as 'Enter Value' for a blank default. \n\
69 | Overwrite Values: Check this box to overwrite existing values for a given label name. If not overwrite then existing values will remain. \n\
70 | ");
71 |
72 | dlgGridLayout {
73 | dlgCell(0, 0) dlgLabel("Label");
74 | dlgCell(0, 1) dlgLabel("Type");
75 | dlgCell(0, 2) dlgLabel("Value");
76 | dlgCell(0, 3) dlgLabel("Overwrite Values?");
77 |
78 | for(int indi = 0; indi < num_rows; indi++)
79 | {
80 | dlgCell(indi + 1, 0) dlgTextEdit(labels[indi]);
81 | dlgCell(indi + 1, 1) dlgListBox(option_strings, options[indi]) dlgMessageBox("You have selected " + option_strings[options[indi]]);
82 | dlgCell(indi + 1, 2) dlgTextEdit(values[indi]);
83 | dlgCell(indi + 1, 3) dlgCheckBox("OVRWT", overwrite_val[indi]);
84 | }
85 |
86 | };
87 |
88 | dlgPushButton("Add Row"){
89 | // add row
90 | num_rows++;
91 | if(num_rows > MAX_NUM_ROWS){
92 | dlgMessageBox("No more rows allowed. Use multiple calls to this ULP");
93 | num_rows = MAX_NUM_ROWS;
94 | }
95 | dlgAccept();
96 | };
97 | dlgPushButton("Remove Last Row"){
98 | // add row
99 | num_rows--;
100 | if(num_rows < 1){
101 | dlgMessageBox("You must have at least one row");
102 | num_rows = 1;
103 | }
104 | dlgAccept();
105 | };
106 |
107 | dlgGridLayout {
108 |
109 | dlgCell(0, 1){
110 | dlgPushButton("Accept (Modify Library)"){
111 | setup_complete = 1;
112 | result = 0;
113 | dlgAccept();
114 | };
115 | };
116 |
117 | dlgCell(0, 0){
118 | dlgPushButton("Cancel"){
119 | setup_complete = 1;
120 | result = 1;
121 | dlgAccept();
122 | };
123 | };
124 | }
125 |
126 | };
127 | }
128 |
129 | // CAPSIFY!
130 | for(int indi = 0; indi < num_rows; indi++)
131 | {
132 | labels[indi] = strupr(labels[indi]);
133 | }
134 |
135 |
136 | // Use the really cool code to actually set all the ATTRIBUTES by constructing a long command to execute
137 | // Thanks to the original code located here: // https://github.com/plusea/EAGLE/blob/master/ulp/set-all-devices-attribute.ulp
138 |
139 | library(L){
140 |
141 | // readScript();
142 | cmdScript = filesetext(L.name, "~.scr");
143 | L.devicesets(DS) {
144 | sprintf(s, "EDIT %s.DEV;\n", DS.name);
145 | cmd += s;
146 | int n;
147 | DS.devices(D) {
148 | string t[];
149 | int nt = strsplit(t, D.technologies, ' ');
150 | sprintf(s, "PACKAGE %s;\n", check_varname(D.name) );
151 | cmd += s;
152 | for (int i = 0; i < nt; i++) {
153 | sprintf(s, "TECHNOLOGY %s;\n", t[i]);
154 | cmd += s;
155 | D.attributes(A, t[i]) {
156 |
157 |
158 | for(int indi = 0; indi < num_rows; indi++) {
159 | status(DS.name+":"+D.name+":"+t[i]);
160 |
161 | if (A.name == labels[indi]) {
162 | if (strlen(A.value)){
163 | attr_val_pre_exists[indi] = 1;
164 | // dlgMessageBox("found the specified attribute with a value already. Device: " + D.name + ", tech: " + t[i] + ", ATTR: " + A.name + ", value: " + A.value );
165 | }
166 | else
167 | {
168 | attr_val_pre_exists[indi] = 0;
169 | // dlgMessageBox("found one with zero length!");
170 | }
171 | }
172 | }
173 | }
174 |
175 | for(int indi = 0; indi < num_rows; indi++) // Within each technology enumerate all the atribute commands
176 | {
177 | string name = labels[indi];
178 | string value = values[indi];
179 | string option = option_strings[options[indi]];
180 |
181 |
182 | // If modifying the new value then use "ATTRIBUTE NAME 'value' option" form
183 | // Unless you have asked not to overwrite existing values
184 |
185 | // Make sure the user actually edited the name... (and make sure it has no spaces)
186 | if(name != "Enter Label"){
187 |
188 | string array[];
189 | int nw = strsplit(array, name, ' ');
190 | if(nw == 1){
191 |
192 | if(options[indi] == 2){ // If deleting an attibute then just do it!
193 | sprintf(s, "ATTRIBUTE %s %s;\n", name, "DELETE");
194 | }
195 | else if(overwrite_val[indi]){
196 |
197 | if(values[indi] != "Enter Value") // If overwriting and have valid new value then just use this form
198 | {
199 | sprintf(s, "ATTRIBUTE %s '%s' %s\n", name, value, option);
200 | }
201 | else // Otherwise just overwrite the option for that attribute
202 | {
203 | sprintf(s, "ATTRIBUTE %s %s;\n", name, option);
204 | }
205 | }
206 | else // If oyu are not overwriting existing values then you are here
207 | {
208 | if(attr_val_pre_exists[indi]){ // A value already exists for your attribute: use the two argument form
209 | // Do nothing if you don't want to overwrite and the attribute already exists with a value
210 |
211 | // // If you wanted you could set the option to the one defined by the user, using this command:
212 | // sprintf(s, "ATTRIBUTE %s %s;\n", name, option);
213 | }
214 | else // No value already exists so you can specify the new value or change the option
215 | {
216 | if(values[indi] != "Enter Value"){
217 | sprintf(s, "ATTRIBUTE %s '%s' %s\n", name, value, option);
218 | }
219 | else
220 | {
221 | sprintf(s, "ATTRIBUTE %s %s;\n", name, option);
222 | }
223 | }
224 | }
225 |
226 | cmd += s;
227 | s = "";
228 |
229 | }
230 | }
231 | }
232 | }
233 | }
234 | }
235 | }
236 |
237 |
238 | output(cmdScript, "wtD") printf("%s", cmd);
239 | if( result == 0 ){
240 | sprintf(s, "SCRIPT '%s';\n", cmdScript);
241 | exit(s);
242 | }
243 | else{
244 | exit(1);
245 | }
246 |
247 | }
248 | else{
249 | dlgMessageBox("Please run this ULP from the library you wish to modify.");
250 | exit(1);
251 | }
--------------------------------------------------------------------------------
/ulp/adimv4_0mm.ulp:
--------------------------------------------------------------------------------
1 | /****************************************************************************************
2 | * *
3 | * AutoDimensionning of Board in mm (Version 3.0) for EAGLE 4.X only! *
4 | * *
5 | * ORIGINAL Filename: adimv2_0mm.ulp *
6 | * Written by: Michel Dagenais *
7 | * Date: September 12th 1998 *
8 | * Modified: Brain Technology (www.braintechnology.de) (* Nov 1999 *) *
9 | * Now places text on appropriate side (closer to object beeing dimensionned). *
10 | * *
11 | * Filename: adimv3_0mm.ulp *
12 | * Edited by: Jeff Moore *
13 | * Date: February 1st 2001 *
14 | * *
15 | * This ULP program will put all the necessary dimensions for holes (layer 45) and *
16 | * board outline (arcs and wires on layer 20) for your board into a .scr file of your *
17 | * choice and into the directory of your choice. *
18 | * Run the resulting script on your board to place the dimentions into the board file. *
19 | * *
20 | * Few requirements: *
21 | * *
22 | * 1. The shape of your board (board outline) is drawn on layer 20 (Dimension). *
23 | * 2. You reserve layer 47 (Measures) to dimension your board. *
24 | * *
25 | * *
26 | * *
27 | ****************************************************************************************/
28 |
29 | real datum_dot_diameter = 01.27; // diameter of connecting dot on datum line
30 |
31 | real datum_wire_width = 0.50; // width or datum line
32 | real default_wire_width = 0.20; // default wire width for dimension extender and leader
33 | real wire_width;
34 |
35 | real extender_clearance = 1.27; // clearance from closest edge
36 | real text_offset = 12.7; // distance of dimension text from closest edge
37 |
38 | real right_top_extender_length = text_offset * 2.28;
39 | real left_bottom_extender_length = text_offset * 2.28;
40 |
41 | real right_top_datum_location = extender_clearance + (right_top_extender_length * 0.75);
42 | real left_bottom_datum_location = extender_clearance + (left_bottom_extender_length * 0.75);
43 |
44 | int right_limit;
45 | int top_limit;
46 | int left_limit;
47 | int bottom_limit;
48 |
49 | int x_points[];
50 | string x_points_loc[]; // top or bottom
51 | int y_points[];
52 | string y_points_loc[]; // right or left
53 | string text_location;
54 | string fileName;
55 |
56 | int lower_right;
57 | int higher_right;
58 | int lower_top;
59 | int higher_top;
60 | int lower_left;
61 | int higher_left;
62 | int lower_bottom;
63 | int higher_bottom;
64 |
65 | int count_x_points;
66 | int count_y_points;
67 |
68 | int i;
69 | int j;
70 |
71 | void check_x_points(int point_cxp, int y_point_cxp)
72 | {
73 | for (i = 0; i <= count_x_points; ++i)
74 | {
75 | if (point_cxp == x_points[i])
76 | break;
77 | }
78 | if (i > count_x_points)
79 | {
80 | x_points[count_x_points] = point_cxp;
81 | int middle = bottom_limit + ((abs(bottom_limit) + abs(top_limit)) * 0.5);
82 | if (y_point_cxp < middle)
83 | text_location = "bottom";
84 | else
85 | text_location = "top";
86 | x_points_loc[count_x_points] = text_location;
87 | ++count_x_points;
88 | }
89 | }
90 |
91 | void check_y_points(int point_cxp, int x_point_cxp)
92 | {
93 | for (i = 0; i <= count_y_points; ++i)
94 | {
95 | if (point_cxp == y_points[i])
96 | break;
97 | }
98 | if (i > count_y_points)
99 | {
100 | y_points[count_y_points] = point_cxp;
101 | int middle = left_limit + ((abs(left_limit) + abs(right_limit)) * 0.5);
102 | if (x_point_cxp < middle)
103 | text_location = "left";
104 | else
105 | text_location = "right";
106 | y_points_loc[count_y_points] = text_location;
107 | ++count_y_points;
108 | }
109 | }
110 |
111 | fileName = dlgFileSave("Save Dimensioning File", filesetext("millimeters",".scr"), "*.scr");
112 | if (fileName == "") exit(0);
113 |
114 | output(fileName)
115 | {
116 | printf(";\n");
117 | printf("Grid mm;\n");
118 | printf("Change Width 2.0;\n");
119 | printf("Change Size 1.77;\n");
120 | printf("Change Ratio 8;\n");
121 | printf("Display 20 44 45 47;\n");
122 | printf("Layer 47;\n");
123 | board(B)
124 | {
125 | B.wires(W)
126 | {
127 | if (W.layer == 20)
128 | {
129 | switch (W.y2 - W.y1)
130 | {
131 | case 0:
132 | {
133 | if (W.y2 > top_limit)
134 | top_limit = W.y2;
135 | else
136 | {
137 | if (W.y2 < bottom_limit)
138 | bottom_limit = W.y2;
139 | }
140 | }
141 | default:
142 | {
143 | if (W.y2 > W.y1)
144 | {
145 | if (W.y2 > top_limit)
146 | top_limit = W.y2;
147 | if (W.y1 < bottom_limit)
148 | bottom_limit = W.y1;
149 | }
150 | else
151 | {
152 | if (W.y1 > top_limit)
153 | top_limit = W.y1;
154 | if (W.y2 < bottom_limit)
155 | bottom_limit = W.y2;
156 | }
157 | }
158 | }
159 | switch (W.x2 - W.x1)
160 | {
161 | case 0:
162 | {
163 | if (W.x2 > right_limit)
164 | right_limit = W.x2;
165 | else
166 | {
167 | if (W.x2 < left_limit)
168 | left_limit = W.x2;
169 | }
170 | }
171 | default:
172 | {
173 | if (W.x2 > W.x1)
174 | {
175 | if (W.x2 > right_limit)
176 | right_limit = W.x2;
177 | if (W.x1 < left_limit)
178 | left_limit = W.x1;
179 | }
180 | else
181 | {
182 | if (W.x1 > right_limit)
183 | right_limit = W.x1;
184 | if (W.x2 < left_limit)
185 | left_limit = W.x2;
186 | }
187 | }
188 | }
189 | }
190 | }
191 | // B.wires(A)
192 | // {
193 | // if (A.layer == 20)
194 | // {
195 | // check_x_points(A.x1, A.y1);
196 | // check_y_points(A.y1, A.x1);
197 | // }
198 | // }
199 | B.wires(W)
200 | {
201 | if (W.layer == 20)
202 | {
203 | if(!(W.arc))
204 | {
205 | check_y_points(W.y2, W.x2);
206 | check_y_points(W.y1, W.x1);
207 | check_x_points(W.x2, W.y2);
208 | check_x_points(W.x1, W.y1);
209 | }
210 | }
211 | }
212 | B.holes(H)
213 | {
214 | check_x_points(H.x, H.y);
215 | check_y_points(H.y, H.x);
216 | }
217 | B.elements(E)
218 | {
219 | E.package.contacts(C)
220 | {
221 | if(C.pad)
222 | {
223 | check_x_points(C.pad.x, C.pad.y);
224 | check_y_points(C.pad.y, C.pad.x);
225 | }
226 | }
227 | }
228 | //
229 | // Adding X dimensions
230 | //
231 | for (i = 0; i <= count_x_points; ++i)
232 | {
233 | if (x_points[i] == 0)
234 | {
235 | printf("Circle 0 (0 %.2f) (0 %.2f);\n", (u2mm(top_limit) + right_top_datum_location), (u2mm(top_limit) + right_top_datum_location + (datum_dot_diameter /2)));
236 | printf("Circle 0 (0 %.2f) (0 %.2f);\n", (u2mm(bottom_limit) - left_bottom_datum_location), (u2mm(bottom_limit) - left_bottom_datum_location - (datum_dot_diameter /2)));
237 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, u2mm(x_points[i]), (u2mm(top_limit) + extender_clearance), u2mm(x_points[i]), (u2mm(top_limit) + right_top_extender_length));
238 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, u2mm(x_points[i]), (u2mm(bottom_limit) - extender_clearance), u2mm(x_points[i]), (u2mm(bottom_limit) - left_bottom_extender_length));
239 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mm(x_points[i])), u2mm(x_points[i]), (u2mm(top_limit) + text_offset));
240 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mm(x_points[i])), u2mm(x_points[i]), (u2mm(bottom_limit) - text_offset - 0.3));
241 |
242 | }
243 | if (x_points_loc[i] == "top")
244 | {
245 | if (x_points[i] > higher_top)
246 | higher_top = x_points[i];
247 | if (x_points[i] < lower_top)
248 | lower_top = x_points[i];
249 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mm(x_points[i])), u2mm(x_points[i]), (u2mm(top_limit) + text_offset));
250 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mm(x_points[i]), (u2mm(top_limit) + extender_clearance), u2mm(x_points[i]), (u2mm(top_limit) + right_top_extender_length));
251 | }
252 | else
253 | {
254 | if (x_points[i] > higher_bottom)
255 | higher_bottom = x_points[i];
256 | if (x_points[i] < lower_bottom)
257 | lower_bottom = x_points[i];
258 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mm(x_points[i])), u2mm(x_points[i]), (u2mm(bottom_limit) - text_offset - 0.3));
259 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mm(x_points[i]), (u2mm(bottom_limit) - extender_clearance), u2mm(x_points[i]), (u2mm(bottom_limit) - left_bottom_extender_length));
260 | }
261 | }
262 | // Join all X dimensions
263 | if (lower_top != higher_top)
264 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mm(lower_top), (u2mm(top_limit) + right_top_datum_location), u2mm(higher_top), (u2mm(top_limit) + right_top_datum_location));
265 | if (lower_bottom != higher_bottom)
266 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mm(lower_bottom), (u2mm(bottom_limit) - left_bottom_datum_location), u2mm(higher_bottom), (u2mm(bottom_limit) - left_bottom_datum_location));
267 |
268 | //
269 | // Adding Y dimensions
270 | //
271 | for (i = 0; i <= count_y_points; ++i)
272 | {
273 | if (y_points[i] == 0)
274 | {
275 | printf("Circle 0 (%.2f 0) (%.2f 0);\n", (u2mm(right_limit) + right_top_datum_location), (u2mm(right_limit) + right_top_datum_location + (datum_dot_diameter /2)));
276 | printf("Circle 0 (%.2f 0) (%.2f 0);\n", (u2mm(left_limit) - left_bottom_datum_location), (u2mm(left_limit) - left_bottom_datum_location - (datum_dot_diameter /2)));
277 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, (u2mm(right_limit) + extender_clearance), u2mm(y_points[i]), (u2mm(right_limit) + right_top_extender_length), u2mm(y_points[i]));
278 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, (u2mm(left_limit) - extender_clearance), u2mm(y_points[i]), (u2mm(left_limit) - left_bottom_extender_length), u2mm(y_points[i]));
279 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mm(y_points[i])), (u2mm(right_limit) + text_offset), u2mm(y_points[i]));
280 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mm(y_points[i])), (u2mm(left_limit) - text_offset - 0.3), u2mm(y_points[i]));
281 | }
282 | if (y_points_loc[i] == "right")
283 | {
284 | if (y_points[i] > higher_right)
285 | higher_right = y_points[i];
286 | if (y_points[i] < lower_right)
287 | lower_right = y_points[i];
288 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mm(y_points[i])), (u2mm(right_limit) + text_offset), u2mm(y_points[i]));
289 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mm(right_limit) + extender_clearance), u2mm(y_points[i]), (u2mm(right_limit) + right_top_extender_length), u2mm(y_points[i]));
290 | }
291 | else
292 | {
293 | if (y_points[i] > higher_left)
294 | higher_left = y_points[i];
295 | if (y_points[i] < lower_left)
296 | lower_left = y_points[i];
297 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mm(y_points[i])), (u2mm(left_limit) - text_offset - 0.3), u2mm(y_points[i]));
298 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mm(left_limit) - extender_clearance), u2mm(y_points[i]), (u2mm(left_limit) - left_bottom_extender_length), u2mm(y_points[i]));
299 | }
300 | }
301 | // Join all Y dimensions
302 | if (lower_right != higher_right)
303 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mm(right_limit) + right_top_datum_location), u2mm(lower_right), (u2mm(right_limit) + right_top_datum_location), u2mm(higher_right));
304 | if (lower_left != higher_left)
305 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mm(left_limit) - left_bottom_datum_location), u2mm(lower_left), (u2mm(left_limit) - left_bottom_datum_location), u2mm(higher_left));
306 | }
307 | printf("Text 'All Dimensions in MM' R0 (%.2f %.2f);\n",u2mm(right_limit),u2mm(top_limit));
308 | printf("Text 'Spark Fun Electronics' R0 (%.2f %.2f);\n",u2mm(right_limit),u2mm(top_limit)-2);
309 | printf("Grid Last;\n");
310 | printf("Window Fit;\n");
311 | }
312 |
--------------------------------------------------------------------------------
/ulp/autodim_in.ulp:
--------------------------------------------------------------------------------
1 | /****************************************************************************************
2 | * *
3 | * AutoDimensionning of Board in mm (Version 3.0) for EAGLE 4.X only! *
4 | * *
5 | * ORIGINAL Filename: adimv2_0mm.ulp *
6 | * Written by: Michel Dagenais *
7 | * Date: September 12th 1998 *
8 | * Modified: Brain Technology (www.braintechnology.de) (* Nov 1999 *) *
9 | * Now places text on appropriate side (closer to object beeing dimensionned). *
10 | * *
11 | * Filename: adimv3_0mm.ulp *
12 | * Edited by: Jeff Moore *
13 | * Date: February 1st 2001 *
14 | * *
15 | * This ULP program will put all the necessary dimensions for holes (layer 45) and *
16 | * board outline (arcs and wires on layer 20) for your board into a .scr file of your *
17 | * choice and into the directory of your choice. *
18 | * Run the resulting script on your board to place the dimentions into the board file. *
19 | * *
20 | * Few requirements: *
21 | * *
22 | * 1. The shape of your board (board outline) is drawn on layer 20 (Dimension). *
23 | * 2. You reserve layer 47 (Measures) to dimension your board. *
24 | * *
25 | * *
26 | * *
27 | ****************************************************************************************/
28 |
29 | real datum_dot_diameter = 01.27; // diameter of connecting dot on datum line
30 |
31 | real datum_wire_width = 5; // width of datum line
32 | real default_wire_width = 5; // default wire width for dimension extender and leader
33 | real wire_width;
34 |
35 | real extender_clearance = -50; // clearance from closest edge
36 | real text_offset = 100; // distance of dimension text from closest edge
37 |
38 | real right_top_extender_length = text_offset;
39 | real left_bottom_extender_length = text_offset;
40 |
41 | real right_top_datum_location = extender_clearance + (right_top_extender_length);
42 | real left_bottom_datum_location = extender_clearance + (left_bottom_extender_length);
43 |
44 | int right_limit;
45 | int top_limit;
46 | int left_limit;
47 | int bottom_limit;
48 |
49 | int x_points[];
50 | string x_points_loc[]; // top or bottom
51 | int y_points[];
52 | string y_points_loc[]; // right or left
53 | string text_location;
54 | string fileName;
55 |
56 | int lower_right;
57 | int higher_right;
58 | int lower_top;
59 | int higher_top;
60 | int lower_left;
61 | int higher_left;
62 | int lower_bottom;
63 | int higher_bottom;
64 |
65 | int count_x_points;
66 | int count_y_points;
67 |
68 | int i;
69 | int j;
70 |
71 | void check_x_points(int point_cxp, int y_point_cxp)
72 | {
73 | for (i = 0; i <= count_x_points; ++i)
74 | {
75 | if (point_cxp == x_points[i])
76 | break;
77 | }
78 | if (i > count_x_points)
79 | {
80 | x_points[count_x_points] = point_cxp;
81 | int middle = bottom_limit + ((abs(bottom_limit) + abs(top_limit)) * 0.5);
82 | if (y_point_cxp < middle)
83 | text_location = "bottom";
84 | else
85 | text_location = "top";
86 | x_points_loc[count_x_points] = text_location;
87 | ++count_x_points;
88 | }
89 | }
90 |
91 | void check_y_points(int point_cxp, int x_point_cxp)
92 | {
93 | for (i = 0; i <= count_y_points; ++i)
94 | {
95 | if (point_cxp == y_points[i])
96 | break;
97 | }
98 | if (i > count_y_points)
99 | {
100 | y_points[count_y_points] = point_cxp;
101 | int middle = left_limit + ((abs(left_limit) + abs(right_limit)) * 0.5);
102 | if (x_point_cxp < middle)
103 | text_location = "left";
104 | else
105 | text_location = "right";
106 | y_points_loc[count_y_points] = text_location;
107 | ++count_y_points;
108 | }
109 | }
110 |
111 | fileName = dlgFileSave("Save Dimensioning File", filesetext("inch",".scr"), "*.scr");
112 | if (fileName == "") exit(0);
113 |
114 | output(fileName)
115 | {
116 | printf(";\n");
117 | printf("Grid mil;\n");
118 | printf("Change Width 50;\n");
119 | printf("Change Size 40;\n");
120 | printf("Change Ratio 8;\n");
121 | printf("Display 20 44 45 47;\n");
122 | printf("Layer 47;\n");
123 | board(B)
124 | {
125 | B.wires(W)
126 | {
127 | if (W.layer == 20)
128 | {
129 | switch (W.y2 - W.y1)
130 | {
131 | case 0:
132 | {
133 | if (W.y2 > top_limit)
134 | top_limit = W.y2;
135 | else
136 | {
137 | if (W.y2 < bottom_limit)
138 | bottom_limit = W.y2;
139 | }
140 | }
141 | default:
142 | {
143 | if (W.y2 > W.y1)
144 | {
145 | if (W.y2 > top_limit)
146 | top_limit = W.y2;
147 | if (W.y1 < bottom_limit)
148 | bottom_limit = W.y1;
149 | }
150 | else
151 | {
152 | if (W.y1 > top_limit)
153 | top_limit = W.y1;
154 | if (W.y2 < bottom_limit)
155 | bottom_limit = W.y2;
156 | }
157 | }
158 | }
159 | switch (W.x2 - W.x1)
160 | {
161 | case 0:
162 | {
163 | if (W.x2 > right_limit)
164 | right_limit = W.x2;
165 | else
166 | {
167 | if (W.x2 < left_limit)
168 | left_limit = W.x2;
169 | }
170 | }
171 | default:
172 | {
173 | if (W.x2 > W.x1)
174 | {
175 | if (W.x2 > right_limit)
176 | right_limit = W.x2;
177 | if (W.x1 < left_limit)
178 | left_limit = W.x1;
179 | }
180 | else
181 | {
182 | if (W.x1 > right_limit)
183 | right_limit = W.x1;
184 | if (W.x2 < left_limit)
185 | left_limit = W.x2;
186 | }
187 | }
188 | }
189 | }
190 | }
191 | // B.wires(A)
192 | // {
193 | // if (A.layer == 20)
194 | // {
195 | // check_x_points(A.x1, A.y1);
196 | // check_y_points(A.y1, A.x1);
197 | // }
198 | // }
199 | B.wires(W)
200 | {
201 | if (W.layer == 20)
202 | {
203 | if(!(W.arc))
204 | {
205 | check_y_points(W.y2, W.x2);
206 | check_y_points(W.y1, W.x1);
207 | check_x_points(W.x2, W.y2);
208 | check_x_points(W.x1, W.y1);
209 | }
210 | }
211 | }
212 | B.holes(H)
213 | {
214 | check_x_points(H.x, H.y);
215 | check_y_points(H.y, H.x);
216 | }
217 | B.elements(E)
218 | {
219 | E.package.contacts(C)
220 | {
221 | if(C.pad)
222 | {
223 | check_x_points(C.pad.x, C.pad.y);
224 | check_y_points(C.pad.y, C.pad.x);
225 | }
226 | }
227 | }
228 | //
229 | // Adding X dimensions
230 | //
231 | for (i = 0; i <= count_x_points; ++i)
232 | {
233 | if (x_points[i] == 0)
234 | {
235 | printf("Circle 0 (0 %.2f) (0 %.2f);\n", (u2mil(top_limit) + right_top_datum_location), (u2mil(top_limit) + right_top_datum_location + (datum_dot_diameter /2)));
236 | printf("Circle 0 (0 %.2f) (0 %.2f);\n", (u2mil(bottom_limit) - left_bottom_datum_location), (u2mil(bottom_limit) - left_bottom_datum_location - (datum_dot_diameter /2)));
237 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, u2mil(x_points[i]), (u2mil(top_limit) + extender_clearance), u2mil(x_points[i]), (u2mil(top_limit) + right_top_extender_length));
238 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, u2mil(x_points[i]), (u2mil(bottom_limit) - extender_clearance), u2mil(x_points[i]), (u2mil(bottom_limit) - left_bottom_extender_length));
239 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(top_limit) + text_offset));
240 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(bottom_limit) - text_offset - 0.3));
241 |
242 | }
243 | if (x_points_loc[i] == "top")
244 | {
245 | if (x_points[i] > higher_top)
246 | higher_top = x_points[i];
247 | if (x_points[i] < lower_top)
248 | lower_top = x_points[i];
249 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(top_limit) + text_offset));
250 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mil(x_points[i]), (u2mil(top_limit) + extender_clearance), u2mil(x_points[i]), (u2mil(top_limit) + right_top_extender_length));
251 | }
252 | else
253 | {
254 | if (x_points[i] > higher_bottom)
255 | higher_bottom = x_points[i];
256 | if (x_points[i] < lower_bottom)
257 | lower_bottom = x_points[i];
258 | printf("Text '%.2f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(bottom_limit) - text_offset - 0.3));
259 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mil(x_points[i]), (u2mil(bottom_limit) - extender_clearance), u2mil(x_points[i]), (u2mil(bottom_limit) - left_bottom_extender_length));
260 | }
261 | }
262 | // Join all X dimensions
263 | if (lower_top != higher_top)
264 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mil(lower_top), (u2mil(top_limit) + right_top_datum_location), u2mil(higher_top), (u2mil(top_limit) + right_top_datum_location));
265 | if (lower_bottom != higher_bottom)
266 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mil(lower_bottom), (u2mil(bottom_limit) - left_bottom_datum_location), u2mil(higher_bottom), (u2mil(bottom_limit) - left_bottom_datum_location));
267 |
268 | //
269 | // Adding Y dimensions
270 | //
271 | for (i = 0; i <= count_y_points; ++i)
272 | {
273 | if (y_points[i] == 0)
274 | {
275 | printf("Circle 0 (%.2f 0) (%.2f 0);\n", (u2mil(right_limit) + right_top_datum_location), (u2mil(right_limit) + right_top_datum_location + (datum_dot_diameter /2)));
276 | printf("Circle 0 (%.2f 0) (%.2f 0);\n", (u2mil(left_limit) - left_bottom_datum_location), (u2mil(left_limit) - left_bottom_datum_location - (datum_dot_diameter /2)));
277 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, (u2mil(right_limit) + extender_clearance), u2mil(y_points[i]), (u2mil(right_limit) + right_top_extender_length), u2mil(y_points[i]));
278 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, (u2mil(left_limit) - extender_clearance), u2mil(y_points[i]), (u2mil(left_limit) - left_bottom_extender_length), u2mil(y_points[i]));
279 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mil(y_points[i])), (u2mil(right_limit) + text_offset), u2mil(y_points[i]));
280 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mil(y_points[i])), (u2mil(left_limit) - text_offset - 0.3), u2mil(y_points[i]));
281 | }
282 | if (y_points_loc[i] == "right")
283 | {
284 | if (y_points[i] > higher_right)
285 | higher_right = y_points[i];
286 | if (y_points[i] < lower_right)
287 | lower_right = y_points[i];
288 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mil(y_points[i])), (u2mil(right_limit) + text_offset), u2mil(y_points[i]));
289 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mil(right_limit) + extender_clearance), u2mil(y_points[i]), (u2mil(right_limit) + right_top_extender_length), u2mil(y_points[i]));
290 | }
291 | else
292 | {
293 | if (y_points[i] > higher_left)
294 | higher_left = y_points[i];
295 | if (y_points[i] < lower_left)
296 | lower_left = y_points[i];
297 | printf("Text '%.2f' R0 (%.2f %.2f);\n", abs(u2mil(y_points[i])), (u2mil(left_limit) - text_offset - 0.3), u2mil(y_points[i]));
298 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mil(left_limit) - extender_clearance), u2mil(y_points[i]), (u2mil(left_limit) - left_bottom_extender_length), u2mil(y_points[i]));
299 | }
300 | }
301 | // Join all Y dimensions
302 | if (lower_right != higher_right)
303 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mil(right_limit) + right_top_datum_location), u2mil(lower_right), (u2mil(right_limit) + right_top_datum_location), u2mil(higher_right));
304 | if (lower_left != higher_left)
305 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, (u2mil(left_limit) - left_bottom_datum_location), u2mil(lower_left), (u2mil(left_limit) - left_bottom_datum_location), u2mil(higher_left));
306 | }
307 | printf("Text 'All Dimensions in mil' R0 (0 -100);\n");
308 | printf("Text 'Spark Fun Electronics' R0 (0 -200);\n");
309 | printf("Grid Last;\n");
310 | printf("Window Fit;\n");
311 | }
312 |
--------------------------------------------------------------------------------
/ulp/autodim_mil.ulp:
--------------------------------------------------------------------------------
1 | /****************************************************************************************
2 | * *
3 | * AutoDimensionning of Board in mm (Version 3.0) for EAGLE 4.X only! *
4 | * *
5 | * ORIGINAL Filename: adimv2_0mm.ulp *
6 | * Written by: Michel Dagenais *
7 | * Date: September 12th 1998 *
8 | * Modified: Brain Technology (www.braintechnology.de) (* Nov 1999 *) *
9 | * Now places text on appropriate side (closer to object beeing dimensionned). *
10 | * *
11 | * Filename: adimv3_0mm.ulp *
12 | * Edited by: Jeff Moore *
13 | * Date: February 1st 2001 *
14 | * *
15 | * This ULP program will put all the necessary dimensions for holes (layer 45) and *
16 | * board outline (arcs and wires on layer 20) for your board into a .scr file of your *
17 | * choice and into the directory of your choice. *
18 | * Run the resulting script on your board to place the dimentions into the board file. *
19 | * *
20 | * Few requirements: *
21 | * *
22 | * 1. The shape of your board (board outline) is drawn on layer 20 (Dimension). *
23 | * 2. You reserve layer 47 (Measures) to dimension your board. *
24 | * *
25 | * *
26 | * *
27 | ****************************************************************************************/
28 |
29 | real datum_dot_diameter = 5; // diameter of connecting dot on datum line
30 |
31 | real datum_wire_width = 4; // width or datum line
32 | real default_wire_width = 2.5; // default wire width for dimension extender and leader
33 | real wire_width;
34 |
35 | real extender_clearance = 25; // clearance from closest edge
36 | real text_offset = 250; // distance of dimension text from closest edge
37 |
38 | real right_top_extender_length = text_offset * 2.28;
39 | real left_bottom_extender_length = text_offset * 2.28;
40 |
41 | real right_top_datum_location = extender_clearance + (right_top_extender_length * 0.75);
42 | real left_bottom_datum_location = extender_clearance + (left_bottom_extender_length * 0.75);
43 |
44 | int right_limit;
45 | int top_limit;
46 | int left_limit;
47 | int bottom_limit;
48 |
49 | int x_points[];
50 | string x_points_loc[]; // top or bottom
51 | int y_points[];
52 | string y_points_loc[]; // right or left
53 | string text_location;
54 | string fileName;
55 |
56 | int lower_right;
57 | int higher_right;
58 | int lower_top;
59 | int higher_top;
60 | int lower_left;
61 | int higher_left;
62 | int lower_bottom;
63 | int higher_bottom;
64 |
65 | int count_x_points;
66 | int count_y_points;
67 |
68 | int i;
69 | int j;
70 |
71 | void check_x_points(int point_cxp, int y_point_cxp)
72 | {
73 | for (i = 0; i <= count_x_points; ++i)
74 | {
75 | if (point_cxp == x_points[i])
76 | break;
77 | }
78 | if (i > count_x_points)
79 | {
80 | x_points[count_x_points] = point_cxp;
81 | int middle = bottom_limit + ((abs(bottom_limit) + abs(top_limit)) * 0.5);
82 | if (y_point_cxp < middle)
83 | text_location = "bottom";
84 | else
85 | text_location = "top";
86 | x_points_loc[count_x_points] = text_location;
87 | ++count_x_points;
88 | }
89 | }
90 |
91 | void check_y_points(int point_cxp, int x_point_cxp)
92 | {
93 | for (i = 0; i <= count_y_points; ++i)
94 | {
95 | if (point_cxp == y_points[i])
96 | break;
97 | }
98 | if (i > count_y_points)
99 | {
100 | y_points[count_y_points] = point_cxp;
101 | int middle = left_limit + ((abs(left_limit) + abs(right_limit)) * 0.5);
102 | if (x_point_cxp < middle)
103 | text_location = "left";
104 | else
105 | text_location = "right";
106 | y_points_loc[count_y_points] = text_location;
107 | ++count_y_points;
108 | }
109 | }
110 |
111 | fileName = dlgFileSave("Save Dimensioning File", filesetext("inch",".scr"), "*.scr");
112 | if (fileName == "") exit(0);
113 |
114 | output(fileName)
115 | {
116 | printf(";\n");
117 | printf("Grid mil;\n");
118 | printf("Change Width 50;\n");
119 | printf("Change Size 40;\n");
120 | printf("Change Ratio 8;\n");
121 | printf("Display 20 44 45 47;\n");
122 | printf("Layer 47;\n");
123 | board(B)
124 | {
125 | B.wires(W)
126 | {
127 | if (W.layer == 20)
128 | {
129 | switch (W.y2 - W.y1)
130 | {
131 | case 0:
132 | {
133 | if (W.y2 > top_limit)
134 | top_limit = W.y2;
135 | else
136 | {
137 | if (W.y2 < bottom_limit)
138 | bottom_limit = W.y2;
139 | }
140 | }
141 | default:
142 | {
143 | if (W.y2 > W.y1)
144 | {
145 | if (W.y2 > top_limit)
146 | top_limit = W.y2;
147 | if (W.y1 < bottom_limit)
148 | bottom_limit = W.y1;
149 | }
150 | else
151 | {
152 | if (W.y1 > top_limit)
153 | top_limit = W.y1;
154 | if (W.y2 < bottom_limit)
155 | bottom_limit = W.y2;
156 | }
157 | }
158 | }
159 | switch (W.x2 - W.x1)
160 | {
161 | case 0:
162 | {
163 | if (W.x2 > right_limit)
164 | right_limit = W.x2;
165 | else
166 | {
167 | if (W.x2 < left_limit)
168 | left_limit = W.x2;
169 | }
170 | }
171 | default:
172 | {
173 | if (W.x2 > W.x1)
174 | {
175 | if (W.x2 > right_limit)
176 | right_limit = W.x2;
177 | if (W.x1 < left_limit)
178 | left_limit = W.x1;
179 | }
180 | else
181 | {
182 | if (W.x1 > right_limit)
183 | right_limit = W.x1;
184 | if (W.x2 < left_limit)
185 | left_limit = W.x2;
186 | }
187 | }
188 | }
189 | }
190 | }
191 | // B.wires(A)
192 | // {
193 | // if (A.layer == 20)
194 | // {
195 | // check_x_points(A.x1, A.y1);
196 | // check_y_points(A.y1, A.x1);
197 | // }
198 | // }
199 | B.wires(W)
200 | {
201 | if (W.layer == 20)
202 | {
203 | if(!(W.arc))
204 | {
205 | check_y_points(W.y2, W.x2);
206 | check_y_points(W.y1, W.x1);
207 | check_x_points(W.x2, W.y2);
208 | check_x_points(W.x1, W.y1);
209 | }
210 | }
211 | }
212 | B.holes(H)
213 | {
214 | check_x_points(H.x, H.y);
215 | check_y_points(H.y, H.x);
216 | }
217 | B.elements(E)
218 | {
219 | E.package.contacts(C)
220 | {
221 | if(C.pad)
222 | {
223 | check_x_points(C.pad.x, C.pad.y);
224 | check_y_points(C.pad.y, C.pad.x);
225 | }
226 | }
227 | }
228 | //
229 | // Adding X dimensions
230 | //
231 | for (i = 0; i <= count_x_points; ++i)
232 | {
233 | if (x_points[i] == 0)
234 | {
235 | printf("Circle 0 (%.2f) (%.2f);\n", (u2mil(top_limit) + right_top_datum_location), (u2mil(top_limit) + right_top_datum_location + (datum_dot_diameter /2)));
236 | printf("Circle 0 (%.2f) (%.2f);\n", (u2mil(bottom_limit) - left_bottom_datum_location), (u2mil(bottom_limit) - left_bottom_datum_location - (datum_dot_diameter /2)));
237 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, u2mil(x_points[i]), (u2mil(top_limit) + extender_clearance), u2mil(x_points[i]), (u2mil(top_limit) + right_top_extender_length));
238 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", datum_wire_width, u2mil(x_points[i]), (u2mil(bottom_limit) - extender_clearance), u2mil(x_points[i]), (u2mil(bottom_limit) - left_bottom_extender_length));
239 | printf("Text '%.0f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(top_limit) + text_offset));
240 | printf("Text '%.0f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(bottom_limit) - text_offset - 0.3));
241 |
242 | }
243 | if (x_points_loc[i] == "top")
244 | {
245 | if (x_points[i] > higher_top)
246 | higher_top = x_points[i];
247 | if (x_points[i] < lower_top)
248 | lower_top = x_points[i];
249 | printf("Text '%.0f' R90 (%.2f %.2f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(top_limit) + text_offset));
250 | printf("Wire %.2f (%.2f %.2f) (%.2f %.2f);\n", default_wire_width, u2mil(x_points[i]), (u2mil(top_limit) + extender_clearance), u2mil(x_points[i]), (u2mil(top_limit) + right_top_extender_length));
251 | }
252 | else
253 | {
254 | if (x_points[i] > higher_bottom)
255 | higher_bottom = x_points[i];
256 | if (x_points[i] < lower_bottom)
257 | lower_bottom = x_points[i];
258 | printf("Text '%.0f' R90 (%f %f);\n", abs(u2mil(x_points[i])), u2mil(x_points[i]), (u2mil(bottom_limit) - text_offset - 0.3));
259 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, u2mil(x_points[i]), (u2mil(bottom_limit) - extender_clearance), u2mil(x_points[i]), (u2mil(bottom_limit) - left_bottom_extender_length));
260 | }
261 | }
262 | // Join all X dimensions
263 | if (lower_top != higher_top)
264 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, u2mil(lower_top), (u2mil(top_limit) + right_top_datum_location), u2mil(higher_top), (u2mil(top_limit) + right_top_datum_location));
265 | if (lower_bottom != higher_bottom)
266 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, u2mil(lower_bottom), (u2mil(bottom_limit) - left_bottom_datum_location), u2mil(higher_bottom), (u2mil(bottom_limit) - left_bottom_datum_location));
267 |
268 | //
269 | // Adding Y dimensions
270 | //
271 | for (i = 0; i <= count_y_points; ++i)
272 | {
273 | if (y_points[i] == 0)
274 | {
275 | printf("Circle 0 (%f 0) (%f 0);\n", (u2mil(right_limit) + right_top_datum_location), (u2mil(right_limit) + right_top_datum_location + (datum_dot_diameter /2)));
276 | printf("Circle 0 (%f 0) (%f 0);\n", (u2mil(left_limit) - left_bottom_datum_location), (u2mil(left_limit) - left_bottom_datum_location - (datum_dot_diameter /2)));
277 | printf("Wire %f (%f %f) (%f %f);\n", datum_wire_width, (u2mil(right_limit) + extender_clearance), u2mil(y_points[i]), (u2mil(right_limit) + right_top_extender_length), u2mil(y_points[i]));
278 | printf("Wire %f (%f %f) (%f %f);\n", datum_wire_width, (u2mil(left_limit) - extender_clearance), u2mil(y_points[i]), (u2mil(left_limit) - left_bottom_extender_length), u2mil(y_points[i]));
279 | printf("Text '%.0f' R0 (%f %f);\n", abs(u2mil(y_points[i])), (u2mil(right_limit) + text_offset), u2mil(y_points[i]));
280 | printf("Text '%.0f' R0 (%f %f);\n", abs(u2mil(y_points[i])), (u2mil(left_limit) - text_offset - 0.3), u2mil(y_points[i]));
281 | }
282 | if (y_points_loc[i] == "right")
283 | {
284 | if (y_points[i] > higher_right)
285 | higher_right = y_points[i];
286 | if (y_points[i] < lower_right)
287 | lower_right = y_points[i];
288 | printf("Text '%.0f' R0 (%f %f);\n", abs(u2mil(y_points[i])), (u2mil(right_limit) + text_offset), u2mil(y_points[i]));
289 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, (u2mil(right_limit) + extender_clearance), u2mil(y_points[i]), (u2mil(right_limit) + right_top_extender_length), u2mil(y_points[i]));
290 | }
291 | else
292 | {
293 | if (y_points[i] > higher_left)
294 | higher_left = y_points[i];
295 | if (y_points[i] < lower_left)
296 | lower_left = y_points[i];
297 | printf("Text '%.0f' R0 (%f %f);\n", abs(u2mil(y_points[i])), (u2mil(left_limit) - text_offset - 0.3), u2mil(y_points[i]));
298 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, (u2mil(left_limit) - extender_clearance), u2mil(y_points[i]), (u2mil(left_limit) - left_bottom_extender_length), u2mil(y_points[i]));
299 | }
300 | }
301 | // Join all Y dimensions
302 | if (lower_right != higher_right)
303 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, (u2mil(right_limit) + right_top_datum_location), u2mil(lower_right), (u2mil(right_limit) + right_top_datum_location), u2mil(higher_right));
304 | if (lower_left != higher_left)
305 | printf("Wire %f (%f %f) (%f %f);\n", default_wire_width, (u2mil(left_limit) - left_bottom_datum_location), u2mil(lower_left), (u2mil(left_limit) - left_bottom_datum_location), u2mil(higher_left));
306 | }
307 | printf("Text 'All Dimensions in mil' R0 (%f %f);\n",u2mil(right_limit),u2mil(top_limit));
308 | printf("Text 'Spark Fun Electronics' R0 (%f %f);\n",u2mil(right_limit),u2mil(top_limit)-2);
309 | printf("Grid Last;\n");
310 | printf("Window Fit;\n");
311 | }
312 |
--------------------------------------------------------------------------------
/ulp/board_default.ulp:
--------------------------------------------------------------------------------
1 | /****************************************************************************************
2 | * *
3 | * *
4 | ****************************************************************************************/
5 | board(B)
6 | {
7 | B.layers(L) printf("Layer %3d %s\n", L.number, L.name);
8 | }
9 |
10 | int i;
11 |
12 | void set_defaults(void)
13 | {
14 |
15 | }
--------------------------------------------------------------------------------
/ulp/drill-exactsize.ulp:
--------------------------------------------------------------------------------
1 | // ***** MODIFIED VERSION of CadSoft's drill-aid ULP!!
2 | // By MadWizard for imagedump script. See www.madwizard.org
3 |
4 |
5 | string cmd = "GRID mm;\nLayer 116 drillImage;\nchange layer 116;\n";
6 |
7 | void center(int x, int y, int drill) {
8 |
9 | real width = u2mm(drill) / 2;
10 | real radius = width / 2 ;
11 | string h;
12 | sprintf(h, "circle %.3f (%.3f %.3f) (%.3f %.3f) ;\n",
13 | width,
14 | u2mm(x), u2mm(y), u2mm(x) + radius, u2mm(y) );
15 | cmd += h;
16 | return;
17 | }
18 |
19 | if (board) board(B) {
20 |
21 |
22 | B.holes(L) {
23 | center(L.x, L.y, L.drill);
24 | }
25 | B.elements(E) {
26 | E.package.holes(H) {
27 | center(H.x, H.y, H.drill);
28 | }
29 | E.package.contacts(C) {
30 | if (C.pad) {
31 | center(C.pad.x, C.pad.y, C.pad.drill);
32 | }
33 | }
34 | }
35 | B.signals(S) {
36 | S.vias(V) {
37 | center(V.x, V.y, V.drill);
38 | }
39 | }
40 | exit (cmd);
41 | }
42 |
43 | else dlgMessageBox("Start this ULP in a Board!", "OK");
44 | exit (0);
45 |
--------------------------------------------------------------------------------
/ulp/exp-lbrs.ulp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/exp-lbrs.ulp
--------------------------------------------------------------------------------
/ulp/gerbv.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/gerbv.exe
--------------------------------------------------------------------------------
/ulp/help-images/PartCreator-Axis-Indicators.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/help-images/PartCreator-Axis-Indicators.bmp
--------------------------------------------------------------------------------
/ulp/help-images/PartCreator-Center-Pad.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/help-images/PartCreator-Center-Pad.bmp
--------------------------------------------------------------------------------
/ulp/help-images/PartCreator-Pad-Distances.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/help-images/PartCreator-Pad-Distances.bmp
--------------------------------------------------------------------------------
/ulp/help-images/PartCreator-Pin-Size.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/help-images/PartCreator-Pin-Size.bmp
--------------------------------------------------------------------------------
/ulp/import-bmp.ulp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_Eagle_Settings/b4dd178bea6bf97d586f5cf2bf20edca98f1f488/ulp/import-bmp.ulp
--------------------------------------------------------------------------------
/ulp/mirror-board.ulp:
--------------------------------------------------------------------------------
1 | #usage "Mirror board (with all Layers)"
2 | "Author: support@cadsoft.de"
3 |
4 | // THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
5 | // Version 1.01 -- 2006-09-15 alf@cadsoft.de
6 | // 2008-04-10 changed GROUP ... (>x y); alf@cadsoft.de
7 |
8 | string cmd;
9 | int lVisible[];
10 | int useLayer[];
11 | string lNames[] = { " " };
12 |
13 | int maxX = INT_MIN;
14 | int minX = INT_MAX;
15 | int maxY = INT_MIN;
16 | int minY = INT_MAX;
17 | int bminx, bmaxx, bminy, bmaxy;
18 |
19 | int uval = 1;
20 | if (board) board(B) uval = B.grid.unit;
21 | string unit[] = { "Micron", "mm", "Mil", "Inch" };
22 | int unitPrec[] = { 0, 1, 1, 3 }, RoundFactor = pow(10, unitPrec[uval]);
23 |
24 | real u2u(int v) {
25 | switch (uval) {
26 | case GRID_UNIT_MIC : return u2mic(v);
27 | break;
28 |
29 | case GRID_UNIT_MM : return u2mm(v);
30 | break;
31 |
32 | case GRID_UNIT_MIL : return u2mil(v);
33 | break;
34 |
35 | case GRID_UNIT_INCH : return u2inch(v);
36 | break;
37 | }
38 | }
39 |
40 |
41 | void checkmaxmin(int x1, int x2, int y1, int y2) {
42 | if (x1 > maxX) maxX = x1;
43 | if (x2 > maxX) maxX = x2;
44 | if (y1 > maxY) maxY = y1;
45 | if (y2 > maxY) maxY = y2;
46 | if (x1 < minX) minX = x1;
47 | if (x2 < minX) minX = x2;
48 | if (y1 < minY) minY = y1;
49 | if (y2 < minY) minY = y2;
50 | return;
51 | }
52 |
53 | void checkarc( int x1, int x2, int y1, int y2, int xc, int yc, real angle1, real angle2, real radius) {
54 | checkmaxmin( x1, x2, y1, y2 );
55 | if ( angle2 > angle1 + 270.0) {
56 | if ( angle1 < 90 ) checkmaxmin( x1 , xc - radius, yc + radius, yc - radius );
57 | else if( angle1 < 180 ) checkmaxmin( xc - radius, xc + radius, y1 , yc - radius );
58 | else if( angle1 < 270 ) checkmaxmin( x1 , xc + radius, yc - radius, yc + radius );
59 | else if( angle1 < 360 ) checkmaxmin( xc + radius, xc - radius, y1 , yc + radius );
60 | }
61 | else if( angle2 > angle1 + 180.0) {
62 | if ( angle1 < 90 ) checkmaxmin( x1 , xc - radius, yc + radius, y2 );
63 | else if( angle1 < 180 ) checkmaxmin( x1 , xc - radius, yc - radius, y2 );
64 | else if( angle1 < 270 ) checkmaxmin( x1 , xc + radius, yc - radius, y2 );
65 | else if( angle1 < 360 ) checkmaxmin( x1 , xc + radius, yc + radius, y2 );
66 | }
67 | else if( angle2 > angle1 + 90.0 ) {
68 | if ( angle1 < 90 ) checkmaxmin( x1 , x2 , yc + radius, y2 );
69 | else if( angle1 < 180 ) checkmaxmin( x1 , xc - radius, y1 , y2 );
70 | else if( angle1 < 270 ) checkmaxmin( x1 , x2 , yc - radius, y2 );
71 | else if( angle1 < 360 ) checkmaxmin( x1 , xc + radius, y1 , y2 );
72 | }
73 | return;
74 | }
75 |
76 | real WireLength(int x1, int x2, int y1, int y2) {
77 | return sqrt( pow(u2u(x2) - u2u(x1), 2) + pow( u2u(y2) - u2u(y1), 2));
78 | }
79 |
80 |
81 |
82 | // main
83 | if (board) {
84 | board(B) {
85 | bminx = B.area.x1;
86 | bmaxx = B.area.x2;
87 | bminy = B.area.y1;
88 | bmaxy = B.area.y2;
89 | B.layers(L) {
90 | lNames[L.number] = L.name;
91 | lVisible[L.number] = L.visible;
92 | useLayer[L.number] = L.used;
93 | }
94 | B.wires(W) {
95 | if (W.layer == 20) {
96 | if (W.arc) {
97 | checkarc(W.arc.x1, W.arc.x2, W.arc.y1, W.arc.y2, W.arc.xc, W.arc.yc, W.arc.angle1, W.arc.angle2, W.arc.radius);
98 | }
99 | else {
100 | checkmaxmin( W.x1, W.x2, W.y1, W.y2 );
101 | }
102 | }
103 | }
104 | B.circles(C) {
105 | if (C.layer == 20) {
106 | checkmaxmin( C.x - C.radius, C.x + C.radius, C.y - C.radius, C.y + C.radius );
107 | }
108 | }
109 | B.elements(E) {
110 | E.package.wires(W) {
111 | if (W.layer == 20) {
112 | // *** Dimension in Packages ***
113 | if (W.arc) {
114 | checkarc(W.arc.x1, W.arc.x2, W.arc.y1, W.arc.y2, W.arc.xc, W.arc.yc, W.arc.angle1, W.arc.angle2, W.arc.radius);
115 | }
116 | else {
117 | checkmaxmin( W.x1, W.x2, W.y1, W.y2 );
118 | }
119 | }
120 | }
121 | E.package.circles(C) {
122 | if (C.layer == 20) {
123 | checkmaxmin( C.x - C.radius, C.x + C.radius, C.y - C.radius, C.y + C.radius );
124 | }
125 | }
126 | }
127 | }
128 | string s;
129 | sprintf(s, "DISPLAY ALL;\n");
130 | cmd += s;
131 | sprintf(s, "GROUP (%.4f %.4f) (%.4f %.4f) (%.4f %.4f) (%.4f %.4f) (>%.4f %.4f);\n",
132 | u2u(bminx-1000), u2u(bminy-1000),
133 | u2u(bmaxx+1000), u2u(bminy-1000),
134 | u2u(bmaxx+1000), u2u(bmaxy+1000),
135 | u2u(bminx-1000), u2u(bmaxy+1000),
136 | u2u(bminx-1000), u2u(bminy-1000)
137 | );
138 | cmd += s;
139 | sprintf(s, "GRID FINEST;\nMIRROR (>%.4f %.4f);\nGRID LAST;\n",
140 | (u2u(maxX) + u2u(minX)) / 2, u2u(minY) );
141 | cmd += s;
142 | cmd += "DISPLAY NONE ";
143 | for(int l = 1; l < 256; l++) {
144 | if (lNames[l]) { // Layer defined
145 | if (lVisible[l]) sprintf(s, " %d", l);
146 | else sprintf(s, " -%d", l);
147 | cmd += s;
148 | }
149 | }
150 | cmd += ";";
151 | }
152 | exit(cmd);
--------------------------------------------------------------------------------
/ulp/oshw-logo.ulp:
--------------------------------------------------------------------------------
1 | /*
2 | * oshw_logo.ulp
3 | * April 2011, By Bill Westfield (westfw@yahoo.com)
4 | *
5 | * Draw the "golden orb" Open Source Hardware logo
6 | * This is rather customizable; it can draw wires or polygons,
7 | * on any desired layer, at any desired size.
8 | */
9 |
10 | #usage "Create an instance of the Open Source Hardware Logo
\n"
11 | " run oshw-logo [outside-diameter]\n\n
"
12 | " The logo will be centered at the current 'mark'
\n"
13 | "Author: Bill Westfield (westfw@yahoo.com) 8-Apr-2011"
14 |
15 | real linewidth = 0.015;
16 | real td=0, totaldiam = 0.45;
17 |
18 | if (argc > 1) {
19 | td = strtod(argv[1]);
20 | }
21 | if (td == 0) {
22 | td = totaldiam; /* outside diameter of teeth (total) */
23 | }
24 |
25 | /*
26 | * derived sizes. Change to alter "the look", but probably not
27 | * as a matter of course
28 | */
29 | real id = (td / 3.2); /* outside of wheel */
30 | real od = (id * 2.2); /* outside of teeth */
31 | real bgapa = 45; /* Bottom gap angle */
32 | real tia = 26; /* Tooth inside angle */
33 | real toa = 14; /* tooth outside angle */
34 | real ga = (45-tia); /* Gap inside angle */
35 |
36 | /*
37 | * Internal variables
38 | */
39 | int i;
40 | string s, cmd;
41 |
42 | /*
43 | * Draw an orb as an outline (wire) or as a filled shape (polygon)
44 | * on a particular layer
45 | */
46 | void draw_orb (string command, string layer)
47 | {
48 | real sa; /* Start angle for the drawing */
49 |
50 | sprintf(s, "change layer %s; set wire_bend 7;\n", layer); cmd += s;
51 | /*
52 | * Start point
53 | */
54 | sprintf(s, "%s %f (P %f %f)", command, linewidth,
55 | od/2, -90.0 + bgapa/2);
56 | cmd += s;
57 |
58 | sa = -90 + tia/2;
59 |
60 | for (i=0; i < 7; i++) {
61 | /* outside gap */
62 | sprintf(s," @+%f (P %f %f)", od/2, od/2, sa + ga);
63 | cmd += s;
64 | /* to outside tooth */
65 | sprintf(s," +0 (P %f %f)", td/2, sa + ga + (tia - toa)/2);
66 | cmd += s;
67 | /* outside of tooth */
68 | sprintf(s," +0 (P %f %f)", td/2, sa + ga + (tia - toa)/2 + toa);
69 | cmd +=s;
70 | /* back to next gap */
71 | sprintf(s," +0 (P %f %f)", od/2, sa + 45.0); cmd += s;
72 | sa += 45.0;
73 | }
74 | /*
75 | * End point
76 | */
77 | sprintf(s, " @+%f (P %f %f)", od/2, od/2, -90.0 - bgapa/2);
78 | cmd +=s;
79 | /*
80 | * Inside circle
81 | * (we need to draw the circle in two steps to get the curvature
82 | * in the right direction.)
83 | */
84 | sprintf(s, " +0 (P %f %f) @-%f (P %f %f) (P %f %f) +0 (P %f %f)",
85 | id/2, -90.0 - bgapa/2, id/2,
86 | id/2, -180.0,
87 | id/2, -90 + bgapa/2,
88 | od/2, 270 + bgapa/2);
89 | cmd +=s;
90 | cmd += ";\n";
91 | }
92 |
93 | //draw_orb("poly", "tplace");
94 | draw_orb("poly", "symbols");
95 | //draw_orb("wire", "top");
96 |
97 | exit(cmd);
98 |
--------------------------------------------------------------------------------
/ulp/readme.md:
--------------------------------------------------------------------------------
1 | SparkFun Eagle User Language Programs (ULPs)
2 | ========================================
3 |
4 | These ULPs were developed to aid in various day to day operations at SparkFun. They may or may not be helpful to general users.
5 |
6 | * **Include_String.ulp** - Functions used by SparkFun-BOM-Generator.
7 | * **SparkFun-BOM-Generator.ulp** - Scans schematic components and outputs a list of product IDs needed for creating BOMs within the SparkFun ERP software. Also attempts to detect and warn user if there are values that don't match their attribute (for example the product ID is for a 10k but the user has changed the value to 4.7k).
8 | * **SparkFun-CAMmer.ulp** - Creates gerber files from a BRD design. Zips files together using 7za.exe. Checks to see if there are internal layers (up to 4) and outputs appropriate gerbers. Checks to see if there are components on the bottom layer and outputs bottom stencil if requested.
9 | * **SparkFun-Panelizer.ulp** - Creates a given sized panel by copying and pasting a board design with spacing between boards. Works with both 2 layer and 4 layer boards. Automatically loads the correct DRC file (protects against unmasked vias and incorrect polygon pours). Detects if there are overhanging parts that may interfere with the neighboring board. Draws optional v-score indicators and production-friendly frame.
10 | * **SparkFun-PartCreator.ulp** - Parametrically create a device, footprint, and symbol for rectangular ICs.
11 |
12 | License Information
13 | -------------------
14 |
15 | The **code** is released under the GPL v3 license.
16 |
17 | Distributed as-is; no warranty is given.
18 |
19 | - Your friends at SparkFun.
--------------------------------------------------------------------------------
/ulp/set-all-devices-attribute.ulp:
--------------------------------------------------------------------------------
1 |
2 | #usage "en:Run a SCRIPT through all Device Sets (Technology) in a library to define ATTRIBUTEs
\n"
3 | "RUN set-all-devices-attribute [SCRIPT]
"
4 | "The script must conform to the following syntax:
"
5 | "ATTRIBUTE name 'value'
"
6 | "ATTRIBUTE name DELETE
"
7 | "The words may be separated by one single space character only.
"
8 | "In case the value DELETE is used, the attribute will be deleted.
"
9 | "Value must be included in two single quotes, otherwise special "
10 | "characters, like + - space can cause error messages in the script file.
"
11 | "If there is no value given or this attribute is already defined in the Device Set "
12 | "the attribute remains unchanged.
"
13 | "Author: librarian@cadsoft.de
"
14 | ,
15 | "de:Startet ein SCRIPT um in allen Devicesets (Technologien) in einer Bibliothek ATTRIBUTE zu definieren.
\n"
16 | "RUN set-all-devices-attribute [SCRIPT]
"
17 | "Das Script muß nach folgenden Regeln erstellt sein:
"
18 | "ATTRIBUTE Name 'Wert'
"
19 | "ATTRIBUTE Name DELETE
"
20 | "Die Wörter dürfen mit nur einem Leerzeichen (Space) getrennt sein.
"
21 | "Ist der Wert DELETE zugewiesen, wird das Attribute gelöscht
"
22 | "Der Wert muß in zwei Apostrophen eingeschlossen sein, da es sonst bei "
23 | "Sonderzeichen + - Space etc. im erzeugten Script zu Fehlermeldungen kommen kann.
"
24 | "Ist kein Wert angegeben und/oder das Attribute im Deviceset schon vorhanden und "
25 | "ein Wert zugewiesen, dann bleibt das Attribute in diesem Deviceset unverändert.
"
26 | "Author: librarian@cadsoft.de
"
27 |
28 |
29 | // https://github.com/plusea/EAGLE/blob/master/ulp/set-all-devices-attribute.ulp
30 |
31 | string Version = "1.1"; // 2008-09-04 check Variant name
32 | // 1.0 // 2008-06-13 alf@cadsoft.de
33 |
34 | string ScriptFile = argv[1];
35 | string cmdScript, cmd, s;
36 |
37 | string Lines[], Attribut[], AttValue[];
38 | int setAtt[];
39 | int cntl = 0;
40 | int cntAtt = 0;
41 |
42 | if (argv[1] == "?") {
43 | dlgMessageBox(usage, "OK");
44 | }
45 |
46 | void test(void) {
47 | dlgDialog(filename(argv[0]) + " Script") {
48 | dlgTextView(cmd);
49 | dlgHBoxLayout {
50 | dlgPushButton("OK") dlgAccept();
51 | dlgPushButton("Abbruch") { dlgReject(); exit(-2); }
52 | }
53 | };
54 | return;
55 | }
56 |
57 |
58 | string check_varname(string s) { // 2008-09-04
59 | if(s == "''") return s;
60 | return "'"+s+"'";
61 | }
62 |
63 |
64 | void readScript(void) {
65 | cntl = fileread(Lines, ScriptFile);
66 | for (int n = 0; n < cntl; n++) {
67 | if (strstr(Lines[n], "ATTRIBUTE") == 0) {
68 | string a[];
69 | int cnta = strsplit(a, Lines[n], ' ');
70 | Attribut[cntAtt] = a[1];
71 | AttValue[cntAtt] = a[2];
72 | for (int an = 3; an < cnta; an++) { // complete parameter with space
73 | AttValue[cntAtt] += " "+a[an];
74 | }
75 | cntAtt++;
76 | }
77 | }
78 | return;
79 | }
80 |
81 |
82 | if (library) {
83 | library(L) {
84 | if (ScriptFile) {
85 | string fg[];
86 | int cntf = fileglob(fg, path_scr[0]+"/"+ScriptFile);
87 | if (!cntf) ScriptFile = "";
88 | else ScriptFile = fg[0];
89 | }
90 | if (!ScriptFile) ScriptFile = dlgFileOpen("Select a SCRIPT with ATTRIBUTE commands to run in all DEVICESETS", path_scr[0], "*.scr");
91 | if (!ScriptFile) exit(0);
92 | readScript();
93 | cmdScript = filesetext(L.name, "~.scr");
94 | L.devicesets(DS) {
95 | sprintf(s, "EDIT %s.DEV;\n", DS.name);
96 | cmd += s;
97 | int n;
98 | DS.devices(D) {
99 | string t[];
100 | int nt = strsplit(t, D.technologies, ' ');
101 | sprintf(s, "PACKAGE %s;\n", check_varname(D.name) );
102 | cmd += s;
103 | for (int i = 0; i < nt; i++) {
104 | sprintf(s, "TECHNOLOGY %s;\n", t[i]);
105 | cmd += s;
106 | for (n = 0; n < cntAtt; n ++) setAtt[n] = 1; // preset flags
107 | D.attributes(A, t[i]) {
108 | for (n = 0; n < cntAtt; n++) {
109 | status(DS.name+":"+D.name+":"+t[i]);
110 |
111 | if (A.name == Attribut[n]) {
112 | if (A.value || !AttValue[n]) setAtt[n] = 0; // wenn das Attribut schon einen Wert besitzt
113 | // oder im Script kein Wert zugewiesen wird,
114 | // wird das Attribut nicht geändert
115 | }
116 | }
117 | }
118 | for (n = 0; n < cntAtt; n ++) {
119 | if (setAtt[n] || AttValue[n] == "DELETE") {
120 | sprintf(s, "ATTRIBUTE %s %s;\n", Attribut[n], AttValue[n]);
121 | cmd+=s;
122 | s="";
123 | }
124 | }
125 | }
126 | }
127 | }
128 | }
129 | output(cmdScript, "wtD") printf("%s", cmd);
130 | sprintf(s, "SCRIPT '%s';\n", cmdScript);
131 | exit(s);
132 | }
133 |
134 | else dlgMessageBox("Start this ULP from a Library", "OK");
--------------------------------------------------------------------------------
/ulp/z_Include_SF_BOM.ulp:
--------------------------------------------------------------------------------
1 | // string ulpName = "SparkFun-BOM_Generator";
2 | string ulpName = argv[0];
3 | int setup_complete = 0;
4 | int redraw = 1;
5 |
6 | // Master lists of properties that we care about
7 | string master_prod_ids[];
8 | string master_package_names[];
9 | string master_values[];
10 | string master_names[];
11 | string master_pnp_names[];
12 | int master_quantities[];
13 | int master_status[];
14 | int master_matches_filters[];
15 | int numUniqueEntries = 0;
16 |
17 | // There are four classifications that a given unique entry can have:
18 | // - Valid for BOM, called "bom"
19 | // - Invalid for BOM, called "nonbom"
20 | // - Invlaid for BOM AND hidden by filters, called "filtered"
21 | // - Permanently removed from the search because it is a non-physical item, called "nonhardware"
22 |
23 | // Status definitions
24 | int element_status_unknown = 0;
25 | int element_status_bom = 1;
26 | int element_status_nonbom = 2;
27 | // int element_status_filtered = 3; // Filtered is not a status anymore, rather it is a show/hide flag and it is contained in master_matches_filters
28 | int element_status_nonhardware = 4;
29 |
30 | // Info for nonbom elements
31 | string nonbomlistarry[];
32 | int nonbomSort = 0;
33 | int nonbomSelected = -1;
34 | int nonbom_index_map[];
35 |
36 | // Info for bom elements
37 | string bomlistarry[];
38 | string pnplistarry[];
39 | int bomSort = 0;
40 | int bomSelected = -1;
41 | int pnpSelected = -1;
42 | int bom_index_map[];
43 |
44 | // Info for filtered elements
45 | string filteredlistarry[];
46 | int filteredSort = 0;
47 | int filteredSelected = -1;
48 | int filtered_index_map[];
49 |
50 | // Info for nonhardware elements
51 | string nonhardwarelistarry[];
52 | int nonhardwareSort = 0;
53 | int nonhardwareSelected = -1;
54 | int nonhardware_index_map[];
55 |
56 | // Counters for the number of elements in each category
57 | int bomCount = 0;
58 | int nonbomCount = 0;
59 | int filteredCount = 0;
60 | int nonhardwareCount = 0;
61 |
62 | // Filter settings
63 | string configFile = filesetext(argv[0], ".flt");
64 | string filterStrings[] = {"fiducial", "stand-off"};
65 | int filters_active = 1;
66 | string filterStatus[] = {"off", "on"};
67 | int filter_string_selected = -1;
68 | int filter_string_sort = 0;
69 | string temp_filter_string = "AddFilterHere";
70 | string customFilterFile = "";
71 |
72 | // GUI Vars
73 | string prod_id_warning = "";
74 | string headerString = "Qty\tPROD_ID\tNames\tValue\tPackage";
75 | string pnpHeaderString = "Qty\tPROD_ID\tPart\tNames\tValue\tPackage";
76 | string sparkleBOM; // A string for sparkle output
77 | string numFilteredItems = "";
78 | string exportFilePath = "";
79 |
80 | // Function definitions
81 |
82 | // Saves currrent filter strings to file "outfile"
83 | void configWrite(string outfile)
84 | {
85 | output(outfile)
86 | {
87 | int index = 0;
88 | while (filterStrings[index] != "")
89 | {
90 | printf("%s\n", filterStrings[index]);
91 | index++;
92 | }
93 | }
94 | }
95 |
96 | // Reads new filter strings from file "infile"
97 | int configRead(string infile)
98 | {
99 | if (filesize(infile))
100 | { //Check if file exists
101 |
102 | int indk = 0;
103 | while (filterStrings[indk] != "")
104 | { // Clear out old saved filter strings, if any exist
105 | filterStrings[indk] = "";
106 | indk++;
107 | }
108 |
109 | string data[];
110 | int line = fileread(data, infile);
111 |
112 | if (line)
113 | {
114 | int indi = 0;
115 | while (data[indi] != "")
116 | {
117 | filterStrings[indi] = data[indi];
118 | indi++;
119 | }
120 | }
121 | return 0;
122 | }
123 | else
124 | {
125 | return 1;
126 | }
127 | }
128 |
129 | void removeFromFilterList()
130 | {
131 | if (filter_string_selected == -1)
132 | {
133 | return;
134 | }
135 |
136 | int indi = filter_string_selected;
137 | while (filterStrings[indi] != "")
138 | {
139 | filterStrings[indi] = filterStrings[indi + 1];
140 | indi++;
141 | }
142 | }
143 |
144 | void addToFilterList()
145 | {
146 | if (temp_filter_string != "AddFilterHere")
147 | {
148 | int indi = 0;
149 | while (filterStrings[indi] != "")
150 | {
151 | indi++;
152 | }
153 |
154 | filterStrings[indi] = temp_filter_string;
155 | temp_filter_string = "AddFilterHere";
156 | }
157 | }
158 |
159 | //Strip off the alpha pre bits
160 | //Remove leading zeros
161 | string pidFormat(string id_str)
162 | {
163 | string numeral_entries[];
164 | int numEntries = strsplit(numeral_entries, id_str, '-');
165 | if (numEntries < 2)
166 | {
167 | // dlgMessageBox("Too few entries found in the product id");
168 | return "NaN";
169 | }
170 | string numerals = numeral_entries[1];
171 | while (numerals[0] == '0')
172 | {
173 | string t = strsub(numerals, 1, strlen(numerals));
174 | numerals = t;
175 | }
176 |
177 | return numerals;
178 | }
179 |
180 | string replaceCharacter(string base, char from, char to)
181 | {
182 | string retval = base;
183 | for (int indj = 0; indj < strlen(retval); indj++)
184 | {
185 | if (retval[indj] == from)
186 | {
187 | retval[indj] = to;
188 | }
189 | }
190 | return retval;
191 | }
192 |
193 | void generateSparkleList()
194 | {
195 | int invalidPIDcount = 0;
196 | sparkleBOM = "";
197 | for (int indi = 0; indi < bomCount; indi++)
198 | {
199 | string temp = "";
200 | string prod_id = master_prod_ids[bom_index_map[indi]];
201 | string idNUM = pidFormat(prod_id);
202 | if (idNUM == "NaN")
203 | {
204 | invalidPIDcount++;
205 | }
206 | else if (indi < (bomCount - 1))
207 | {
208 | sprintf(temp, "%s,", idNUM);
209 | }
210 | else
211 | {
212 | sprintf(temp, "%s", idNUM);
213 | }
214 |
215 | //Print multiple of this PROD_ID to indicate the qty of the item
216 | for (int x = 0; x < master_quantities[bom_index_map[indi]]; x++)
217 | {
218 | sparkleBOM += temp;
219 | }
220 | }
221 |
222 | if (invalidPIDcount)
223 | {
224 | // string msg = "";
225 | // sprintf(msg, "Warning: %d items in BOM list without PROD_ID", invalidPIDcount);
226 |
227 | sprintf(prod_id_warning, "Warning: %d BOM items have no PROD_ID!", invalidPIDcount);
228 | // dlgMessageBox(msg);
229 | }
230 | else
231 | {
232 | sprintf(prod_id_warning, "All BOM items have PROD_ID. Good job :D");
233 | }
234 | }
235 |
236 | //Finds a string in a string no matter where, no matter capitalization
237 | int containsString(string toSearch, string toFind)
238 | {
239 | int pos = strstr(strlwr(toSearch), strlwr(toFind));
240 | if (pos >= 0) //String found
241 | {
242 | return (1);
243 | }
244 | return (0);
245 | }
246 |
247 | int filterMatch(string str)
248 | {
249 | // Checks if str contains any of the filter strings
250 | int retval = 0; // Begin with no match
251 | int indi = 0;
252 | while (filterStrings[indi] != "")
253 | {
254 | if (containsString(str, filterStrings[indi]))
255 | {
256 | retval = 1;
257 | }
258 | indi++;
259 | }
260 | return retval;
261 | }
262 |
263 | int matchesFilters(UL_ELEMENT E)
264 | {
265 | return filterMatch(E.package.name);
266 | }
267 |
268 | int getStatus(UL_ELEMENT E)
269 | {
270 | // This is the function that contains rules that determine the status of a given element
271 | int this_status = element_status_unknown;
272 |
273 | // Flags for special circumstances
274 | int is_dnp = 0;
275 | int isALabel = 1;
276 | int has_pid = 0;
277 |
278 | // Test for DNP components
279 | if (containsString(E.attribute["Value"], "dnp") || containsString(E.value, "dnp"))
280 | // if((E.value == "DNP") || (E.attribute["Value"] == "DNP"))
281 | {
282 | is_dnp = 1;
283 | }
284 |
285 | // Test for pure-silkness
286 | //If this element has pads then it's not a label
287 | int padCount = 0;
288 | E.footprint.contacts(C)
289 | {
290 | padCount++;
291 | }
292 | if (padCount > 0)
293 | isALabel = 0;
294 | //If this element has a hole then it's not a label
295 | int holeCount = 0;
296 | E.footprint.holes(H)
297 | {
298 | holeCount++;
299 | }
300 | if (holeCount > 0)
301 | isALabel = 0;
302 |
303 | // See if it has a product id
304 | if (E.attribute["PROD_ID"])
305 | {
306 | has_pid = 1;
307 | }
308 |
309 | // Now take your info and make a decision about the status of the element:
310 | if (has_pid)
311 | {
312 | this_status = element_status_bom; // Has pid and IS hardware then its on the BOM
313 | }
314 | else if (is_dnp || isALabel)
315 | {
316 | this_status = element_status_nonhardware;
317 | }
318 | else
319 | {
320 | this_status = element_status_nonbom;
321 | }
322 |
323 | return this_status;
324 | }
325 |
326 | int elementsMatch(UL_ELEMENT E, int master_index)
327 | {
328 | // The definition of a unique element is important, and we will define it in reverse.
329 | // A non-unique element is one that has a different:
330 | // - value
331 | // - package
332 | // - product id
333 | // - element_status
334 |
335 | int match = 1;
336 | if (E.value != master_values[master_index])
337 | {
338 | match = 0;
339 | }
340 | if (E.package.name != master_package_names[master_index])
341 | {
342 | match = 0;
343 | }
344 | if (E.attribute["PROD_ID"] != master_prod_ids[master_index])
345 | {
346 | match = 0;
347 | }
348 | if (getStatus(E) != master_status[master_index])
349 | {
350 | match = 0;
351 | }
352 |
353 | return match;
354 | }
355 |
356 | int elementIsUnique(UL_ELEMENT E)
357 | {
358 | int is_unique = 1;
359 | for (int indi = 0; indi < numUniqueEntries; indi++)
360 | {
361 | if (elementsMatch(E, indi) == 1)
362 | {
363 | is_unique = 0;
364 | }
365 | }
366 | return is_unique;
367 | }
368 |
369 | int getMasterIndexMatch(UL_ELEMENT E)
370 | {
371 | int index = 0;
372 | if (elementIsUnique(E) == 0)
373 | {
374 | while (elementsMatch(E, index) != 1)
375 | {
376 | index++;
377 | }
378 | }
379 | else
380 | {
381 | index = -1;
382 | }
383 | return index;
384 | }
385 |
386 | void initialGrouping()
387 | {
388 | // This is how we initially count the number of unique elements, as well as fill out the arrays of data that can be used for sorting later
389 |
390 | board(B)
391 | {
392 | B.elements(E)
393 | {
394 | if (elementIsUnique(E))
395 | {
396 | // Add new unique item to the master arrays
397 |
398 | master_prod_ids[numUniqueEntries] = E.attribute["PROD_ID"];
399 | master_package_names[numUniqueEntries] = E.package.name;
400 | master_values[numUniqueEntries] = E.value;
401 | master_names[numUniqueEntries] = E.name;
402 | master_pnp_names[numUniqueEntries] = E.name;
403 | master_quantities[numUniqueEntries] = 1;
404 | master_status[numUniqueEntries] = getStatus(E); // Returns one of four categories, bom, nonbom, filtered, or nonhardware
405 | master_matches_filters[numUniqueEntries] = matchesFilters(E);
406 | numUniqueEntries++;
407 | }
408 | else
409 | {
410 | int index = getMasterIndexMatch(E);
411 | if (index != -1)
412 | {
413 | // Add quantity and additional name to that master item
414 | master_names[index] += (", " + E.name);
415 | master_pnp_names[index] += (" " + E.name);
416 | master_quantities[index]++;
417 | }
418 | }
419 | }
420 | }
421 | }
422 |
423 | void categorizeElements()
424 | {
425 | // Clear out the old lists
426 | for (int indk = 0; indk < bomCount; indk++)
427 | {
428 | bomlistarry[indk] = "";
429 | pnplistarry[indk] = "";
430 | bom_index_map[indk] = -1;
431 | }
432 | for (int indj = 0; indj < nonbomCount; indj++)
433 | {
434 | nonbomlistarry[indj] = "";
435 | nonbom_index_map[indj] = -1;
436 | }
437 | for (int indl = 0; indl < filteredCount; indl++)
438 | {
439 | filteredlistarry[indl] = "";
440 | filtered_index_map[indl] = -1;
441 | }
442 | for (int indm = 0; indm < nonhardwareCount; indm++)
443 | {
444 | nonhardwarelistarry[indm] = "";
445 | nonhardware_index_map[indm] = -1;
446 | }
447 |
448 | // Reset the counters
449 | bomCount = 0;
450 | nonbomCount = 0;
451 | filteredCount = 0;
452 | nonhardwareCount = 0;
453 |
454 | // Recategorize the elements from the master lists
455 | for (int indi = 0; indi < numUniqueEntries; indi++)
456 | {
457 | string temp = "";
458 | sprintf(temp, "%d\t%s\t%s\t%s\t%s", master_quantities[indi], master_prod_ids[indi], master_names[indi], master_values[indi], master_package_names[indi]);
459 | string temp2 = "";
460 | sprintf(temp2, "%d\t%s\t%s\t%s\t%s\t%s", master_quantities[indi], master_prod_ids[indi], pidFormat(master_prod_ids[indi]), master_pnp_names[indi], master_values[indi], master_package_names[indi]);
461 |
462 | if (master_status[indi] == element_status_nonhardware)
463 | {
464 | nonhardwarelistarry[nonhardwareCount] = temp;
465 | nonhardware_index_map[nonhardwareCount] = indi;
466 | nonhardwareCount++;
467 | }
468 | else if (master_status[indi] == element_status_bom)
469 | {
470 | bomlistarry[bomCount] = temp;
471 | pnplistarry[bomCount] = temp2;
472 | bom_index_map[bomCount] = indi;
473 | bomCount++;
474 | }
475 | else if (master_status[indi] == element_status_nonbom) // Note: filters only apply to nonbom items, because in an ideal world a design would have no items that are both non-hardware and have no prod_id
476 | {
477 | if ((master_matches_filters[indi] == 1) && (filters_active == 1))
478 | {
479 | filteredlistarry[filteredCount] = temp;
480 | filtered_index_map[filteredCount] = indi;
481 | filteredCount++;
482 | }
483 | else
484 | {
485 | nonbomlistarry[nonbomCount] = temp;
486 | nonbom_index_map[nonbomCount] = indi;
487 | nonbomCount++;
488 | }
489 | }
490 | else
491 | {
492 | // Problems have arisen
493 | }
494 | }
495 |
496 | sprintf(numFilteredItems, "%d", filteredCount); // Show how many items are hidden
497 |
498 | generateSparkleList();
499 | }
500 |
--------------------------------------------------------------------------------