4 # PCB, interactive printed circuit board design
5 # Copyright (C) 1994,1995,1996 Thomas Nau
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 # Contact addresses for paper mail and Email:
22 # Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 # Thomas.Nau@rz.uni-ulm.de
29 # -------------------------------------------------------------------
30 # ThanX to Johan Andersson (johan@homemail.com), modified by Thomas Nau
31 # the definition of a plcc package for base code to make qfp package.
32 # modified for correct pad numbering by Holm Tiffe
34 # Code from plcc.inc modified by Thomas Olson to make this qfp.inc definition.
35 # Although in retrospec quad flat packs are more diverse than this algorithm will do.
36 # Many qfp are the same physical size but have more thus narrower pads.
41 # $5: additional border (will be ignored)
44 `define(`QUARTER', `eval($4 /4)')
45 define(`OFFSET', `eval((QUARTER +1) /2)')
46 define(`WIDTH', `eval((QUARTER-1) *31 +2*42)')
47 define(`CENTER', `eval(WIDTH / 2)')
48 define(`NUMPINS', `$4')
49 Element(0x00 "$1" "`$2'" "$3" 100 CENTER 0 100 0x00)
55 #define(`count', `eval(OFFSET+1)')
57 forloop(`i', 1, QUARTER,
58 `PAD(eval(X-65), Y, eval(X+5), Y, 20, count)' `define(`count', incr(count))'
59 `define(`Y', eval(Y+31))'
65 forloop(`i', 1, QUARTER,
66 `PAD(X, eval(Y+65), X, eval(Y-5), 20, count)' `define(`count', incr(count))'
67 `define(`X', eval(X+31))'
72 define(`Y', eval(WIDTH-42))
73 forloop(`i', 1, QUARTER,
74 `PAD(eval(X+65), Y, eval(X-5), Y, 20, count)' `define(`count', incr(count))'
75 `define(`Y', eval(Y-31))'
79 define(`X', eval(WIDTH-42))
81 forloop(`i', 1, QUARTER,
82 `PAD(X, eval(Y-65), X, eval(Y+5), 20, count)' `define(`count', incr(count))'
83 `ifelse(eval(count > NUMPINS), 1, `define(`count', 1)')'
84 `define(`X', eval(X-31))'
87 ElementLine(28 0 WIDTH 0 10)
88 ElementLine(WIDTH 0 WIDTH WIDTH 10)
89 ElementLine(WIDTH WIDTH 0 WIDTH 10)
90 ElementLine(0 WIDTH 0 28 10)
91 ElementLine(0 28 28 0 10)
93 ElementArc(80 80 20 20 0 360 10)
98 # -------------------------------------------------------------------
101 # Yet another QFP Package family -- untested (but looks pretty)
102 # Concepts stolen from PLCC and older QFP macros above.
103 # December 1999, Larry Doolittle <LRDoolittle@lbl.gov>
104 # This is intended to be fully general, and replace all other QFP code.
105 # It can handle square or rectangular packages of variable pitch.
106 # It sings, it dances, it might even be made to handle PLCCs and
107 # the Motorola package outlines with those cool-looking tabs on the
110 # PKG_GEN_QFP is the general case, PKG_LQFP and PKG_QFP call it
111 # with different setup.
112 # PITCH pad center-to-center distance ***IN UNITS OF 0.1 MICROMETER***
113 # (weird, I know, but this sets 1 mil=254 units exactly, so
114 # pitches defined in either Imperial or Metric may be used)
115 # PAD_WIDTH width of pad (mils)
116 # XPADS Number of pads in X direction
117 # YPADS Number of pads in Y direction
118 # (total number of pads is 2*(XPADS+YPADS) )
119 # X_LENGTH X length in mils from end-to-end of the pads
120 # Y_LENGTH Y length in mils from end-to-end of the pads
121 # ISTART Where along the left row (YPADS long) to find pin 1.
122 # (generally ISTART=1 for pin 1 in the corner, but ISTART
123 # is 11 for some 84-pin square packages and 17 for some
124 # 132-pin square packages)
126 # Feb 3, 2000 LRD: allow XPADS == 0 to represent SOIC packages
128 define(`PKG_GEN_QFP',
130 define(`PX', `eval((PITCH*(XPADS-1)+127)/254)')
131 define(`PY', `eval((PITCH*(YPADS-1)+127)/254)')
132 define(`PHW', `eval(PAD_WIDTH/2)')
133 Element(0x00 "$1" "`$2'" "$3" 100 0 0 100 0x00)
137 # left row, going down
138 define(`X_OUTER', PHW)
139 define(`X_INNER', eval(PAD_LENGTH-PHW))
140 define(`Y0', `eval((Y_LENGTH-PY)/2)')
141 forloop(`i', ISTART, YPADS,
142 `define(`Y', eval(Y0+(PITCH*(i-1)+127)/254) )'
143 `PAD(X_OUTER, Y, X_INNER, Y, PAD_WIDTH, count)'
144 `define(`count',incr(count))'
147 # bottom row, going right
149 define(`Y_OUTER', eval(Y_LENGTH-PHW))
150 define(`Y_INNER', eval(Y_LENGTH+PHW-PAD_LENGTH))
151 define(`X0', `eval((X_LENGTH-PX)/2)')
152 forloop(`i', 1, XPADS,
153 `define(`X', eval(X0+(PITCH*(i-1)+127)/254) )'
154 `PAD(X, Y_OUTER, X, Y_INNER, PAD_WIDTH, count)'
155 `define(`count',incr(count))'
158 # right row, going up
159 define(`X_OUTER', eval(X_LENGTH-PHW))
160 define(`X_INNER', eval(X_LENGTH+PHW-PAD_LENGTH))
161 define(`Y0', `eval((Y_LENGTH+PY)/2)')
162 forloop(`i', 1, YPADS,
163 `define(`Y', eval(Y0-(PITCH*(i-1)+127)/254) )'
164 `PAD(X_OUTER, Y, X_INNER, Y, PAD_WIDTH, count)'
165 `define(`count',incr(count))'
168 # top row, going left
170 define(`Y_OUTER', PHW)
171 define(`Y_INNER', eval(PAD_LENGTH+PHW-PAD_WIDTH))
172 define(`X0', `eval((X_LENGTH+PX)/2)')
173 forloop(`i', 1, XPADS,
174 `define(`X', eval(X0-(PITCH*(i-1)+127)/254) )'
175 `PAD(X, Y_OUTER, X, Y_INNER, PAD_WIDTH, count)'
176 `define(`count',incr(count))'
179 # left row, going down again, maybe
180 define(`X_OUTER', PHW)
181 define(`X_INNER', eval(PAD_LENGTH-PHW))
182 define(`Y0', `eval((Y_LENGTH-PY)/2)')
183 ifelse(ISTART,1,,`forloop(`i', 1, eval(ISTART-1),
184 `define(`Y', eval(Y0+(PITCH*(i-1)+127)/254) )'
185 `PAD(X_OUTER, Y, X_INNER, Y, PAD_WIDTH, count)'
186 `define(`count',incr(count))'
189 define(`NOSMUDGE', 10)
190 define(`SSOX', eval(NOSMUDGE+PAD_LENGTH))
191 define(`SSOY', ifelse(XPADS,0,0,eval(NOSMUDGE+PAD_LENGTH)))
192 define(`PPX', eval(X_LENGTH-SSOX))
193 define(`PPY', eval(Y_LENGTH-SSOY))
194 ElementLine(SSOX SSOY PPX SSOY 8)
195 ElementLine(PPX SSOY PPX PPY 8)
196 ElementLine(PPX PPY SSOX PPY 8)
197 ElementLine(SSOX PPY SSOX SSOY 8)
200 define(`Y1', ifelse(ISTART,1,`eval(SSOY+40)',
201 `eval(Y0+(PITCH*(ISTART-1)+127)/254)'))
202 ElementArc(eval(SSOX+40) Y1 20 20 0 360 10)
204 # Moderately useful place for the Mark. This way,
205 # if the pins can line up with the grid, they do.
206 Mark(eval((X_LENGTH-PX)/2) eval((Y_LENGTH-PY)/2))
209 # PKG_QFP: square quad flat pack, 0.8 mm pitch, based on PKG_GEN_QFP above
213 # $4: total number of pins (package is assumed square)
214 # This configuration should correspond to the old PKG_QFP, renamed
215 # PKG_OLD_QFP above for comparison. The two implementations have,
216 # among other things, different coordinate zeros.
219 `define(`PITCH', 8000)
220 define(`PAD_WIDTH', 20)
221 define(`PAD_LENGTH', 90)
222 define(`XPADS', `eval($4 /4)')
223 define(`YPADS', `eval($4 /4)')
224 define(`X_LENGTH', `eval((PITCH*(XPADS-1)+127)/254+232)')
225 define(`Y_LENGTH', X_LENGTH)
227 PKG_GEN_QFP($1, $2, $3)'
230 # PKG_208_LQFP: leaded quad flat pack, 0.5 mm pitch, based on PKG_GEN_QFP above
234 # This configuration based on a mechanical drawing of a
235 # Cirrus Logic EP7211 in a 208-Pin LQFP
237 define(`PKG_208_LQFP',
238 `define(`PITCH', 5000)
239 define(`PAD_LENGTH', 60)
240 define(`PAD_WIDTH', 10)
243 define(`X_LENGTH', 1220)
244 define(`Y_LENGTH', 1220)
246 PKG_GEN_QFP($1, $2, $3)'
249 # Interesting hack, this. pcb -> sh -> m4 -> tcl
250 # Refer to qfp-ui, a tcl program that should accompany this file.
251 # Search path for this puppy comes from QueryLibrary.sh, which
252 # I (LRD) patched to merge M4PATH into PATH
253 define(`PKG_MENU_QFP',
254 `esyscmd(qfp-ui "$1" "`$2'" "$3")'