Merge branch 'master' of git://git.gpleda.org/pcb
[geda-pcb/see.git] / lib / qfp.inc
blob0ceaeedaab9d36572319bb0d83122c68b2d3a020
2 #                             COPYRIGHT
3
4 #   PCB, interactive printed circuit board design
5 #   Copyright (C) 1994,1995,1996 Thomas Nau
6
7 #   This program is free software; you can redistribute it and/or modify
8 #   it under the terms of the GNU General Public License as published by
9 #   the Free Software Foundation; either version 2 of the License, or
10 #   (at your option) any later version.
11
12 #   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.
16
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.
20
21 #   Contact addresses for paper mail and Email:
22 #   Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
23 #   Thomas.Nau@rz.uni-ulm.de
24
25 #   RCS: $Id$
27 #  QFP packages
30 # -------------------------------------------------------------------
31 # ThanX to Johan Andersson (johan@homemail.com), modified by Thomas Nau
32 # the definition of a plcc package for base code to make qfp package.
33 # modified for correct pad numbering by Holm Tiffe
35 # Code from plcc.inc modified by Thomas Olson to make this qfp.inc definition.
36 # Although in retrospec quad flat packs are more diverse than this algorithm will do.
37 # Many qfp are the same physical size but have more thus narrower pads. 
38 # $1: canonical name
39 # $2: name on PCB
40 # $3: value
41 # $4: number of pins
42 # $5: additional border (will be ignored)
44 define(`PKG_OLD_QFP',
45         `define(`QUARTER', `eval($4 /4)')
46         define(`OFFSET', `eval((QUARTER +1) /2)')
47         define(`WIDTH', `eval((QUARTER-1) *31 +2*42)')
48         define(`CENTER', `eval(WIDTH / 2)')
49         define(`NUMPINS', `$4')
50 Element(0x00 "$1" "`$2'" "$3" 100 CENTER 0 100 0x00)
53         # left row
54 define(`X', 0)
55 define(`Y', 42)
56 #define(`count', `eval(OFFSET+1)')
57 define(`count', 1)
58 forloop(`i', 1, QUARTER,
59         `PAD(eval(X-65), Y, eval(X+5), Y, 20, count)' `define(`count', incr(count))'
60         `define(`Y', eval(Y+31))'
61         )
63         # bottom row
64 define(`X', 42)
65 define(`Y', WIDTH)
66 forloop(`i', 1, QUARTER,
67         `PAD(X, eval(Y+65), X, eval(Y-5), 20, count)' `define(`count', incr(count))'
68         `define(`X', eval(X+31))'
71         # right row
72 define(`X', WIDTH)
73 define(`Y', eval(WIDTH-42))
74 forloop(`i', 1, QUARTER,
75         `PAD(eval(X+65), Y, eval(X-5), Y, 20, count)' `define(`count', incr(count))'
76         `define(`Y', eval(Y-31))'
79         # top row
80 define(`X', eval(WIDTH-42))
81 define(`Y', 0)
82 forloop(`i', 1, QUARTER,
83         `PAD(X, eval(Y-65), X, eval(Y+5), 20, count)' `define(`count', incr(count))'
84         `ifelse(eval(count > NUMPINS), 1, `define(`count', 1)')'
85         `define(`X', eval(X-31))'
88         ElementLine(28 0 WIDTH 0 10)
89         ElementLine(WIDTH 0 WIDTH WIDTH 10)
90         ElementLine(WIDTH WIDTH 0 WIDTH 10)
91         ElementLine(0 WIDTH 0 28 10)
92         ElementLine(0 28 28 0 10)
94         ElementArc(80 80 20 20 0 360 10)
96         Mark(0 0)
97 )')
99 # -------------------------------------------------------------------
102 # Yet another QFP Package family -- untested (but looks pretty)
103 # Concepts stolen from PLCC and older QFP macros above.
104 # December 1999, Larry Doolittle <LRDoolittle@lbl.gov>
105 # This is intended to be fully general, and replace all other QFP code.
106 # It can handle square or rectangular packages of variable pitch.
107 # It sings, it dances, it might even be made to handle PLCCs and
108 # the Motorola package outlines with those cool-looking tabs on the
109 # plastic.
111 # PKG_GEN_QFP is the general case, PKG_LQFP and PKG_QFP call it
112 # with different setup.
113 #   PITCH      pad center-to-center distance ***IN UNITS OF 0.1 MICROMETER***
114 #             (weird, I know, but this sets 1 mil=254 units exactly, so
115 #              pitches defined in either Imperial or Metric may be used)
116 #   PAD_WIDTH  width of pad (mils)
117 #   XPADS      Number of pads in X direction
118 #   YPADS      Number of pads in Y direction
119 #             (total number of pads is 2*(XPADS+YPADS) )
120 #   X_LENGTH   X length in mils from end-to-end of the pads
121 #   Y_LENGTH   Y length in mils from end-to-end of the pads
122 #   ISTART    Where along the left row (YPADS long) to find pin 1.
123 #             (generally ISTART=1 for pin 1 in the corner, but ISTART
124 #              is 11 for some 84-pin square packages and 17 for some
125 #              132-pin square packages)
127 # Feb 3, 2000 LRD: allow XPADS == 0 to represent SOIC packages
129 define(`PKG_GEN_QFP',
130         `
131         define(`PX', `eval((PITCH*(XPADS-1)+127)/254)')
132         define(`PY', `eval((PITCH*(YPADS-1)+127)/254)')
133         define(`PHW', `eval(PAD_WIDTH/2)')
134 Element(0x00 "$1" "`$2'" "$3" 100 0 0 100 0x00)
136         define(`count', 1)
138         # left row, going down
139         define(`X_OUTER', PHW)
140         define(`X_INNER', eval(PAD_LENGTH-PHW))
141         define(`Y0', `eval((Y_LENGTH-PY)/2)')
142         forloop(`i', ISTART, YPADS,
143                 `define(`Y', eval(Y0+(PITCH*(i-1)+127)/254) )'
144                 `PAD(X_OUTER, Y, X_INNER, Y, PAD_WIDTH, count)'
145                 `define(`count',incr(count))'
146         )
148         # bottom row, going right
149         ifelse(XPADS,0,,`
150         define(`Y_OUTER', eval(Y_LENGTH-PHW))
151         define(`Y_INNER', eval(Y_LENGTH+PHW-PAD_LENGTH))
152         define(`X0', `eval((X_LENGTH-PX)/2)')
153         forloop(`i', 1, XPADS,
154                 `define(`X', eval(X0+(PITCH*(i-1)+127)/254) )'
155                 `PAD(X, Y_OUTER, X, Y_INNER, PAD_WIDTH, count)'
156                 `define(`count',incr(count))'
157         )')
159         # right row, going up
160         define(`X_OUTER', eval(X_LENGTH-PHW))
161         define(`X_INNER', eval(X_LENGTH+PHW-PAD_LENGTH))
162         define(`Y0', `eval((Y_LENGTH+PY)/2)')
163         forloop(`i', 1, YPADS,
164                 `define(`Y', eval(Y0-(PITCH*(i-1)+127)/254) )'
165                 `PAD(X_OUTER, Y, X_INNER, Y, PAD_WIDTH, count)'
166                 `define(`count',incr(count))'
167         )
169         # top row, going left
170         ifelse(XPADS,0,,`
171         define(`Y_OUTER', PHW)
172         define(`Y_INNER', eval(PAD_LENGTH+PHW-PAD_WIDTH))
173         define(`X0', `eval((X_LENGTH+PX)/2)')
174         forloop(`i', 1, XPADS,
175                 `define(`X', eval(X0-(PITCH*(i-1)+127)/254) )'
176                 `PAD(X, Y_OUTER, X, Y_INNER, PAD_WIDTH, count)'
177                 `define(`count',incr(count))'
178         )')
180         # left row, going down again, maybe
181         define(`X_OUTER', PHW)
182         define(`X_INNER', eval(PAD_LENGTH-PHW))
183         define(`Y0', `eval((Y_LENGTH-PY)/2)')
184         ifelse(ISTART,1,,`forloop(`i', 1, eval(ISTART-1),
185                 `define(`Y', eval(Y0+(PITCH*(i-1)+127)/254) )'
186                 `PAD(X_OUTER, Y, X_INNER, Y, PAD_WIDTH, count)'
187                 `define(`count',incr(count))'
188         )')
190         define(`NOSMUDGE', 10)
191         define(`SSOX', eval(NOSMUDGE+PAD_LENGTH))
192         define(`SSOY', ifelse(XPADS,0,0,eval(NOSMUDGE+PAD_LENGTH)))
193         define(`PPX', eval(X_LENGTH-SSOX))
194         define(`PPY', eval(Y_LENGTH-SSOY))
195         ElementLine(SSOX SSOY PPX  SSOY 8)
196         ElementLine(PPX  SSOY PPX  PPY  8)
197         ElementLine(PPX  PPY  SSOX PPY  8)
198         ElementLine(SSOX PPY  SSOX SSOY 8)
200         # Pin 1 Indicator
201         define(`Y1', ifelse(ISTART,1,`eval(SSOY+40)',
202                                      `eval(Y0+(PITCH*(ISTART-1)+127)/254)'))
203         ElementArc(eval(SSOX+40) Y1 20 20 0 360 10)
205         # Moderately useful place for the Mark.  This way,
206         # if the pins can line up with the grid, they do.
207         Mark(eval((X_LENGTH-PX)/2) eval((Y_LENGTH-PY)/2))
210 # PKG_QFP: square quad flat pack, 0.8 mm pitch, based on PKG_GEN_QFP above
211 # $1: canonical name
212 # $2: name on PCB
213 # $3: value
214 # $4: total number of pins (package is assumed square)
215 # This configuration should correspond to the old PKG_QFP, renamed
216 # PKG_OLD_QFP above for comparison.  The two implementations have,
217 # among other things, different coordinate zeros.
219 define(`PKG_QFP',
220         `define(`PITCH', 8000)
221         define(`PAD_WIDTH', 20)
222         define(`PAD_LENGTH', 90)
223         define(`XPADS', `eval($4 /4)')
224         define(`YPADS', `eval($4 /4)')
225         define(`X_LENGTH', `eval((PITCH*(XPADS-1)+127)/254+232)')
226         define(`Y_LENGTH', X_LENGTH)
227         define(`ISTART', 1)
228         PKG_GEN_QFP($1, $2, $3)'
231 # PKG_208_LQFP: leaded quad flat pack, 0.5 mm pitch, based on PKG_GEN_QFP above
232 # $1: canonical name
233 # $2: name on PCB
234 # $3: value
235 # This configuration based on a mechanical drawing of a
236 # Cirrus Logic EP7211 in a 208-Pin LQFP
238 define(`PKG_208_LQFP',
239         `define(`PITCH', 5000)
240         define(`PAD_LENGTH', 60)
241         define(`PAD_WIDTH', 10)
242         define(`XPADS', 52)
243         define(`YPADS', 52)
244         define(`X_LENGTH', 1220)
245         define(`Y_LENGTH', 1220)
246         define(`ISTART', 1)
247         PKG_GEN_QFP($1, $2, $3)'
250 # Interesting hack, this.  pcb -> sh -> m4 -> tcl
251 # Refer to qfp-ui, a tcl program that should accompany this file.
252 # Search path for this puppy comes from QueryLibrary.sh, which
253 # I (LRD) patched to merge M4PATH into PATH
254 define(`PKG_MENU_QFP',
255         `esyscmd(qfp-ui "$1" "`$2'" "$3")'