#!/usr/bin/perl # # kifps.pl - Footprints for kicad # # Written 2006-2008 by Werner Almesberger # Copyright 2006-2008 Werner Almesberger # # # General parameters, in kicad units (1/10 mil) # # $LINE_WIDTH is the width of silk screen lines # $OUTER_MARGIN is the distance between pads and a silk screen surrounding the # package # $LINE_WIDTH = 50; $OUTER_MARGIN = 100; # The radio between the diameter of a hole and the copper ring surrounding it. # Recommended values are > 2 for epoxy, > 2.5. for pertinax. $COPPER_RATIO = 2.5; # # Units. # # Invoke &mm or &mil before issuing dimensions. # Low-level functions use &unit to make the appropriate conversion. # &unit_inv converts internal kicad units to the current unit. # sub mm { $unit = 1000/2.54; } sub mil { $unit = 10; } sub unit { return $_[0]*$unit; } sub unit_inv { return $_[0]/$unit; } # # Module assembly. # # &begin starts a new module. # &add adds a string to the current module. # &end closes the module. # sub add { $modules{$current} .= "$_[0]\n"; } sub begin { local ($name,$descr) = @_; $current = $name; $pad = 1; &add("\$MODULE $name"); &add(sprintf('Po 0 0 0 15 %08X 00000000 ~~',time)); &add("Li $name"); &add("Cd $descr"); &add("Sc 00000000"); &add("Op 0 0 0"); &add("At SMD"); &add("T0 0 0 200 200 0 40 N V 21 \"$name\""); &add('T1 0 0 200 200 0 40 N I 21 "Val*"'); } sub end { &add("\$EndMODULE $current"); } # # Pad and hole creation. # # &pad adds the next pad to the current module. # &pads adds a row of pads, specified by the number of pads in this row, the # pad geometry, the center of the row, and the vector from one pad center to # the next. # &pads4 adds four symmetric rows with counter-clockwise pin numbering. # &hole adds a circular hole. # &same decrements the pin number, such that the next pin will have the same # number as the previous pin. # # $x and $y are the coordinates of the pads's center. # $h and $w are the pads' height and width. They get translated to $px and $y, # which are the x and y size in the given orientation. # $cx and $cy specify the center of a row of pads. # $dx and $dy is the vector from one pad center to the next. # $d is the the hole diameter. The copper area is $d*$COPPER_RATIO. # sub pad_shape { local ($px,$py,$x,$y,$shape) = @_; &add('$PAD'); &add(sprintf("Sh \"$pad\" $shape %d %d 0 0 0",&unit($px),&unit($py))); &add("At SMD N 00888000"); &add('Ne 0 ""'); &add(sprintf("Po %d %d",&unit($x),-&unit($y))); &add('$EndPAD'); $pad++; } sub pad { local ($px,$py,$x,$y) = @_; &pad_shape($px,$py,$x,$y,"R"); } sub pads { local ($n,$px,$py,$cx,$cy,$dx,$dy) = @_; local ($x,$y,$i); $x = $cx-($n-1)/2*$dx; $y = $cy-($n-1)/2*$dy; for ($i = 0; $i != $n; $i++) { &pad($px,$py,$x,$y); $x += $dx; $y += $dy; } } sub pads4 { local ($n,$w,$h,$cx,$cy,$dx,$dy) = @_; &pads($n,$h,$w,$cx,$cy,$dx,$dy); &pads($n,$w,$h,-$cy,$cx,-$dy,$dx); &pads($n,$h,$w,-$cx,-$cy,-$dx,-$dy); &pads($n,$w,$h,$cy,-$cx,$dy,-$dx); } sub hole_ratio { local ($d,$x,$y,$ratio) = @_; local ($c) = $ratio*$d; &add('$PAD'); &add(sprintf("Sh \"$pad\" C %d %d 0 0 0",&unit($c),&unit($c))); &add(sprintf("Dr %d 0 0",&unit($d))); &add("At STD N 00448001"); &add('Ne 0 ""'); &add(sprintf("Po %d %d",&unit($x),-&unit($y))); &add('$EndPAD'); $pad++; } sub hole { local ($d,$x,$y) = @_; &hole_ratio($d,$x,$y,$COPPER_RATIO); } sub same { $pad--; } # # Silk elements # # &line draws a line # &rect draws a rectangle # &circle draws a circle # sub line { local ($x0,$y0,$x1,$y1) = @_; &add(sprintf("DS %d %d %d %d $LINE_WIDTH 21", &unit($x0),&unit(-$y0),&unit($x1),&unit(-$y1))); } sub rect { local ($x0,$y0,$x1,$y1) = @_; &line($x0,$y0,$x1,$y0); &line($x1,$y0,$x1,$y1); &line($x1,$y1,$x0,$y1); &line($x0,$y1,$x0,$y0); } sub circle { local ($x,$y,$r) = @_; &add(sprintf("DC %d %d %d %d $LINE_WIDTH 21", &unit($x),&unit(-$y),&unit($x+$r),&unit(-$y))); } # # Make chip components # sub chip { local ($w,$h,$edge_dist) = @_; local ($xpad); &mm; $xpad = ($edge_dist-$h)/2; &rect(-$edge_dist/2-&unit_inv($OUTER_MARGIN), -$w/2-&unit_inv($OUTER_MARGIN), $edge_dist/2+&unit_inv($OUTER_MARGIN), $w/2+&unit_inv($OUTER_MARGIN)); &pad($h,$w,-$xpad,0); &pad($h,$w,$xpad,0); } # # Make SOT components # # &sot makes a SOT component # &sot_sq is like &sot, but the middle pad(s) are squeezed # sub sot_vec { local ($h,$d,$edge_dist,$pkg_width,@w) = @_; local ($x,$y); local ($i); &mm; &rect(-$pkg_width/2,-$edge_dist/2-&unit_inv($OUTER_MARGIN), $pkg_width/2,$edge_dist/2+&unit_inv($OUTER_MARGIN)); $x = -$d; $y = -($edge_dist-$h)/2; for ($i = 0; $i != 6; $i++) { local $w = shift @w; local $xoff = shift @w; &pad($w,$h,$x+$xoff,$y) if $w; if ($i < 2) { $x += $d; } elsif ($i > 2) { $x -= $d; } else { $y = -$y; } } } sub sot { local ($n,$w,$h,$d,$edge_dist,$pkg_width) = @_; local (@vec); if ($n == 3) { @vec = ($w,0,0,0,$w,0,0,0,$w,0,0,0); } elsif ($n == 4) { @vec = ($w,0,0,0,$w,0,$w,0,0,0,$w,0); } elsif ($n == 5) { @vec = ($w,0,$w,0,$w,0,$w,0,0,0,$w,0); } elsif ($n == 6) { @vec = ($w,0,$w,0,$w,0,$w,0,$w,0,$w,0); } else { die; } &sot_vec($h,$d,$edge_dist,$pkg_width,@vec); } sub sod { local ($len, $pad_len, $pad_width, $pkg_width) = @_; local ($x, $y); &mm; $x = ($len+$pad_len)/2+&unit_inv($OUTER_MARGIN); $y = $pkg_width/2; &rect(-$x, -$y, $x, $y); &pad($pad_len, $pad_width, -$len/2, 0); &pad($pad_len, $pad_width, $len/2, 0); } # # Make QFN components # # &qfn makes a QFN component (with a center pad) # # $n is the number of pads # $d is the distance between pad centers # $edge_dist is the distance from one edge of the footprint to the opposite # edge. # $center_width is the width of the (quadratic) center pad # sub qfn { local ($n,$w,$h,$d,$edge_dist,$center_width) = @_; local ($boundary,$row_center); &mm; $boundary = $edge_dist/2+&unit_inv($OUTER_MARGIN); $row_center = ($edge_dist-$h)/2; &rect(-$boundary,-$boundary,$boundary,$boundary); &circle(-$row_center,$row_center,$h/2); &pads4($n/4,$w,$h,-$row_center,0,0,-$d); &pad($center_width,$center_width,0,0); } # # The Keystone 1059, 1060, and 3003 battery holders # sub keystone_1059 { local ($epad) = (10); # enlarge pads by that many mils local ($cd) = (70); # cut corner, distance from edge local ($pr,$pd) = (40,50); # polarity markers, radius and distance local ($x,$y); &mil; &hole(38,1060/2,100/2); &same; &hole(38,1060/2,-100/2); &hole(38,-1060/2,0); # zone for adhesive &rect(-433/2,-275/2,433/2,275/2); # the case &rect(-866/2,-630/2,866/2,630/2); &line(866/2,630/2-$cd,866/2-$cd,630/2); foreach $x (-1,1) { foreach $y (-1,1) { &line($x*1118/2,$y*275/2,$x*866/2,$y*275/2); } } # polarity markers ($x,$y) = (866/2-$pd,-630/2+$pd); &circle($x,$y,$pr); &line($x-$pr,$y,$x+$pr,$y); &line($x,$y-$pr,$x,$y+$pr); ($x,$y) = (-$x,-$y); &circle($x,$y,$pr); &line($x,$y-$pr,$x,$y+$pr); # the battery &mm; &circle(0,0,10); } sub keystone_1060 { local ($epad) = (10); # enlarge pads by that many mils local ($cd) = (70); # cut corner, distance from edge local ($pr,$pd) = (40,50); # polarity markers, radius and distance local ($x,$y); &mil; &pad(102+$epad,142+$epad,1154/2,0) &pad(102+$epad,142+$epad,-1154/2,0) # zone for adhesive &rect(-433/2,-275/2,433/2,275/2); # the case &rect(-866/2,-630/2,866/2,630/2); &line(866/2,630/2-$cd,866/2-$cd,630/2); foreach $x (-1,1) { foreach $y (-1,1) { &line($x*1118/2,$y*275/2,$x*866/2,$y*275/2); } } # polarity markers ($x,$y) = (866/2-$pd,-630/2+$pd); &circle($x,$y,$pr); &line($x-$pr,$y,$x+$pr,$y); &line($x,$y-$pr,$x,$y+$pr); ($x,$y) = (-$x,-$y); &circle($x,$y,$pr); &line($x,$y-$pr,$x,$y+$pr); # the battery &mm; &circle(0,0,10); } sub keystone_3003 { local ($epad) = (2); # enlarge pads by that many mm local ($pw) = 0.8; # width of the projection pads local ($dh) = 1.85; # diameter of holes local ($A,$B,$G) = (21.11,9.42,19.69); # see data sheet local $back = 7.7; # width of the back holder local ($x,$y); &mm; &hole_ratio($dh,-$A/2,0,2); &same; &hole_ratio($dh,$A/2,0,2); &same; &pad($back,$pw,0,-$A/2); foreach $x (-1,1) { foreach $y (-1,1) { &same; &pad($pw,($B-$dh)/2,$x*$A/2,$y*($B+$dh)/4); } } &pad(3.96+$epad,3.96+$epad,0,0); # the case foreach $x (-1,1) { &line(0,-$A/2,$x*$back/2,-$A/2); &line($x*$back/2,-$A/2,$x*$A/2,-$B/2); &line($x*$A/2,-$B/2,$x*$A/2,$B/2); &line($x*$A/2,$B/2,$x*$A/2,$G-$A/2); &line($x*$A/2,$G-$A/2,0,$G-$A/2); } # the battery &circle(0,0,10); } sub probe_pad { local ($px,$py) = @_; &mil; &pad_shape($px,$py,0,0,$px == $py ? "C" : "O"); } sub probe_pad_mm { local ($px,$py) = @_; &mm; &pad_shape($px,$py,0,0,$px == $py ? "C" : "O"); } # # Hirose Mini-USB B receptacles. # sub ux60_mb_st { local ($first, $x, $y, $n) = 1; &mm; # contacts for ($n = 0; $n != 5; $n++) { &pad(0.5, 2, $n*0.8-1.6, 8.65); } # case feet foreach $x (-4.2, 4.2) { foreach $y (3.1, 8.4) { &same unless $first; undef $first; &pad(2.5, 2.2, $x, $y); } } # keep-out area &rect(-7.7/2, 0, 7.7/2, 6); } sub ux60ra_mb_st { local ($first, $x, $y, $n) = 1; &mm; # contacts for ($n = 0; $n != 5; $n++) { &pad(0.5, 1.5, 1.6-$n*0.8, 6.4-0.75); } # case feet foreach $x (-4.55, 4.55) { &same unless $first; undef $first; &pad(2.4, 1.95, $x, 1.35); &same; &pad(2.4, 2.2, $x, 4.45); } # keep-out area &rect(-6.7/2, 0, 6.7/2, 3.75); &rect(-1, 3.75, 1, 4.9); # case &rect(-7.7/2, -2.25, 7.7/2, 8.4-2.25); } # # Hirose Micro-USB B receptacles. # sub zx62_b_pa { local ($first, $x, $y, $n) = 1; &mm; # contacts for ($n = 0; $n != 5; $n++) { &pad(0.4, 1.35, 1.3-$n*0.65, 1.45+3.35-1.35/2); } # case feet foreach $x (-1, 1) { &same unless $first; undef $first; &pad(2.1, 1.6, $x*(8.3-2.1)/2, 1.45+3.35-0.8); &same; &pad(1.8, 1.9, $x*(9.8-1.8)/2, 1.45); &same; &pad(1.9, 1.9, $x*(4.3-1.9)/2, 1.45); } # keep-out area &rect(-7.5/2, 0, 7.5/2, 1.45+3.35-1.35); # case &rect(-7.5/2, 1.45-2.15, 7.5/2, 1.45+(5-2.15)); } sub zx62r_b_p { local ($first, $x, $y, $n) = 1; &mm; # contacts for ($n = 0; $n != 5; $n++) { &pad(0.4, 1.35, 1.3-$n*0.65, 1.45+3.35-1.35/2); } # case feet foreach $x (-1, 1) { &same unless $first; undef $first; &pad(2.1, 2, $x*(8.3-2.1)/2, 1.45+3.35-1); &same; &pad(1.6, 1.9, $x*(9.8-1.6)/2, 1.45); &same; &pad(1.2, 1.9, $x*(2.9-1.2)/2, 1.45); } # keep-out area &rect(-7.5/2, 0, 7.5/2, 1.45+3.35-1.35); # case &rect(-7.5/2, 1.45-2.15, 7.5/2, 1.45+(5-2.15)); } sub zx62m_b_p { local ($first, $x, $y, $n) = 1; &mm; # contacts for ($n = 0; $n != 5; $n++) { &pad(0.4, 1.05, 1.3-$n*0.65, 1.9+5.15-1.05/2); } # case feet foreach $x (-1, 1) { &same unless $first; undef $first; &pad(2, 1.5, $x*4.7/2, 1.9+7.15-1.5/2); &same; $w = (12-6.9)/2; &pad($w, 2.4, $x*(12-$w)/2, 1.9+4.3); &same; $w = (12-8.8)/2; &pad($w, 2.4, $x*(12-$w)/2, 1.9); } # hole &rect(-7.8/2, 0, 7.8/2, 1.9+3.6); } # # SOT-143 is a little weird, with an asymmetric wide pin one. # sub sot_143 { local ($edge_dist) = 3.5; local ($pkg_width) = 3.04; local ($x,$y); local ($i); &mm; &rect(-$pkg_width/2,-$edge_dist/2-&unit_inv($OUTER_MARGIN), $pkg_width/2,$edge_dist/2+&unit_inv($OUTER_MARGIN)); &pad(1.1, 1.4, -1.9/2+0.2, -2.2/2); &pad(0.9, 1.4, 1.9/2, -2.2/2); &pad(0.9, 1.4, -1.9/2, 2.2/2); &pad(0.9, 1.4, 1.9/2, 2.2/2); } sub relay_js_1c { &mm; &rect(-2.3, -8, 22-2.3, 8); &hole(1, 0, 0); &hole(1, 2, -6); &hole(1, 2+12.2, -6); &hole(1, 2+12.2, 6); &hole(1, 2, 6); } # # Helper functions # sub module { local ($name,$descr,$fn,@args) = @_; &begin($name,$descr); &$fn(@args); &end; } sub dump { print "PCBNEW-LibModule-V1 date\n"; print "\$INDEX\n"; print join("\n",sort keys %modules)."\n"; print "\$EndINDEX\n"; for (sort keys %modules) { print $modules{$_}; } print "\$EndLIBRARY\n"; } ############################################################################### # # The components # # # Most of the data is based on information from Philips Semiconductors, # http://www.semiconductors.philips.com/package/ # Unless indicated otherwise, the land patterns are for reflow soldering. # # # Chip components # # We use the respective maximum values from # http://www.niccomp.com/Products/smt/NRC-LP0402.pdf # (C, D, and B) # # The dimensions are chosen for reflow soldering, with the maximum tolerated # pad size, which should also allow for manual soldering. For wave ("flow") # soldering, alterations may be necessary, see also: # http://download.siliconexpert.com/pdfs/Source/Passive/Resistor/PNS/Rev3/AOA0000CE1.pdf # # 0201 &module("0201","20x10 mil chip component, for reflow", *chip,0.35,0.3,0.9); # 0402 &module("0402","40x20 mil chip component, for reflow", *chip,0.6,0.5,1.6); # 0603 &module("0603","60x30 mil chip component, for reflow", *chip,0.8,0.7,2.2); # 0805 &module("0805","80x50 mil chip component, for reflow", *chip,1.2,0.8,2.9); # 1206 &module("1206","120x60 mil chip component, for reflow", *chip,1.4,1,4.4); # 1210 &module("1210","120x100 mil chip component, for reflow", *chip,2.4,1.2,4.4); # 2010 &module("2010","200x100 mil chip component, for reflow", *chip,2.6,1.5,6.6); # 2512 &module("2512","250x120 mil chip component, for reflow", *chip,3.2,2,8.4); # Epson FC-135 32.7680 kHz crystal # http://www.eea.epson.com/go/Prod_Admin/Categories/EEA/QD/Crystals/kHzSMD_Crystals/go/Resources/TestC2/FC135_145_255 &module("FC-135","Epson FC-135 32.7680 kHz crystal, for reflow", *chip,1.8,1,3.5); # # SOT (transistors, diodes, etc.) # # SOT-23, 2.9mm wide, 3 terminals, TO-236AB # http://www.nxp.com/acrobat/packages/footprint/SOT23-REFLOW-WAVE.pdf &module("SOT-23", "Small Outline Transistor package, 3 pins, 0.95 mm pin pitch, for reflow", *sot,3,0.7,0.6,0.95,2.7,3.3); # SOT-323, 2mm wide, 3 terminals, SC-70 # http://www.semiconductors.philips.com/acrobat/packages/footprint/SOT323-(SC-70)-REFLOW-WAVE.pdf &module("SOT-323", "Small Outline Transistor package, 3 pins, 0.65 mm pin pitch, for reflow", *sot,3,0.6,0.55,0.65,2.4,2.35); # SOT-353, 2mm wide, 5 terminals, SC-70-5, SC-88A, S-Mini, UMT5 # http://www.semiconductors.philips.com/acrobat/packages/footprint/SOT353-(SC-88A)-REFLOW.pdf &module("SOT-353", "Small Outline Transistor package, 5 pins, 0.65 mm pin pitch, for reflow", *sot_vec,0.6,0.65,2.4,2.35, 0.6,-0.1,0.4,0,0.6,0.1,0.6,0.1,0,0,0.6,-0.1); # SOT-523, 1.6mm wide, 3 terminals, SC-75/SC-89 # http://www.semiconductors.philips.com/acrobat/packages/footprint/FOOTPRINT-SC75-SC89-REFLOW.pdf &module("SOT-523", "Small Outline Transistor package, 3 pins, 0.5 mm pin pitch, for reflow", *sot,3,0.5,0.6,0.5,1.9,2); # SOT-553, 1.6mm wide, 5 terminals, SS-Mini # http://www.semiconductors.philips.com/acrobat/packages/footprint/FOOTPRINT-SOT665-REFLOW.pdf &module("SOT-553", "Small Outline Transistor package, 5 pins, 0.5 mm pin pitch, for reflow", *sot_vec,0.6,0.5,2.2,2, 0.375,-0.0375,0.3,0,0.375,0.0375,0.45,0,0,0,0.45,0); # SC-89-6, 1.6mm wide, 6 terminals (SOT-563) # http://www.aosmd.com/pdfs/datasheet/AOZ8205.pdf &module("SC-89-6", "Small Outline Transistor package, 6 pins, 0.5 mm pin pitch", *sot,6,0.3,0.45,0.5,1.7,1.6); # SOD-323, 50mil long, 2 terminals # http://www.zetex.com/3.0/pdf/ZLLS400.pdf &module("SOD-323", "Small Outline Diode package, 2 pins", *sod, 2.3, 0.5, 1, 1.37) # VMD3/SSS-Mini, 1.2mm wide, 3 terminals # http://www.rohm.com/products/databook/di/pdf/rb715z.pdf &module("VMD3", "Extra small power mold, 3 pins", *sot_vec,0.45,0.4,1.6,1.2, 0.4, 0, 0, 0, 0.4, 0, 0, 0, 0.5, 0, 0, 0); # SOT-143, ~3mm wide, 4 terminals # http://littelfuse.com/data/en/Data_Sheets/SP05x_LeadFree.pdf &module("SOT-143", "SOT-143, 4 pins", *sot_143); # # QFN/MLF # # 16QFN, 4x4, HVQNF16, reflow only # Freescale MMA6231Q # http://www.semiconductors.philips.com/acrobat/packages/footprint/SOT629-1_fp_reflow.pdf &module("QFN16_4","QFN/MLF, 16 pins, 4x4 mm, center pad is 2x2 mm, reflow", *qfn,16,0.3,1.1,0.65,5,2); # 16QFN, 6x6 # Freescale MMA6231Q # http://www.freescale.com/files/sensors/doc/data_sheet/MMA6231Q.pdf &module("QFN16_6", "QFN/MLF, 16 pins, 6x6 mm, center pad is 4.25x4.25 mm, reflow", *qfn,16,0.5,0.55,1,6,4.25); # 24QFN, 4x4, HVQFN24, small center pad, reflow only # http://www.semiconductors.philips.com/package/SOT616-1.html &module("QFN24_4_21", "QFN/MLF, 24 pins, 4x4 mm, center pad is 2.1x2.1 mm, reflow", *qfn,24,0.24,0.9,0.5,5,2.1); # 28QFN, 5x5, medium center pad, Si Labs &module("QFN28_5_315", "QFN/MLF, 28 pins, 5x5 mm, center pad is 3.15x3.15 mm", *qfn,28,0.29,0.9,0.5,6,3.15); # 32QFN, 5x5, HVQFN32, large center pad, reflow only # http://www.semiconductors.philips.com/package/SOT617-3.html &module("QFN32_5_35", "QFN/MLF, 32 pins, 5x5 mm, center pad is 3.5x3.5 mm, reflow", *qfn,32,0.29,0.9,0.5,6,3.5); # # Battery holders # # Keystone 1059 and 1060 # CR2032 battery holders, through-hole and SMT # http://www.keyelco.com/products/specs/spec138a.asp &module("Keystone_1059", "Keystone CR2032 battery holder, isolated, through-hole", *keystone_1059); &module("Keystone_1060", "Keystone CR2032 battery holder, isolated, SMT, for reflow", *keystone_1060); # Keystone 3003 # CR2032 battery holder, through-hole # http://www.keyelco.com/products/specs/spec04.asp &module("Keystone_3003", "Keystone CR2032 battery clip, negative terminal on PCB, through-hole", *keystone_3003); # # Probe pads # &module("Pad_60x60", "Rounded pad for probe clips, 60x60 mil", *probe_pad,60,60); &module("Pad_120x60", "Rounded pad for probe clips, 120x60 mil", *probe_pad,120,60); &module("Pad_2mm", "Rounded pad for probe clips, 2x0.5 mm", *probe_pad_mm,2,0.5); # # Mini-USB connector # &module("UX60_MB_5ST", "USB Mini-B SMT", *ux60_mb_st); &module("UX60RA_MB_5ST", "USB Mini-B SMT, reversed", *ux60ra_mb_st); # # Micro-USB connector # &module("ZX62_B_5PA", "USB Micro-B SMT, bottom", *zx62_b_pa); &module("ZX62R_B_5P", "USB Micro-B SMT, reversed", *zx62r_b_p); &module("ZX62M_B_5P", "USB Micro-B SMT, drop-in", *zx62m_b_p); # # Relays # &module("JS_1C", "SPDT relay, JS (22x16mm)", *relay_js_1c); &dump;