kicad/pcbnew/python/plugins/FPC_wizard.py

184 lines
6.6 KiB
Python

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
from __future__ import division
import pcbnew
import FootprintWizardBase
class FPC_FootprintWizard(FootprintWizardBase.FootprintWizard):
def GetName(self):
return "FPC (SMT connector)"
def GetDescription(self):
return "FPC (SMT connector) Footprint Wizard"
def GetValue(self):
pins = self.parameters["Pads"]["n"]
return "FPC_%d" % pins
def GenerateParameterList(self):
self.AddParam( "Pads", "n", self.uInteger, 40 )
self.AddParam( "Pads", "pitch", self.uMM, 0.5 )
self.AddParam( "Pads", "width", self.uMM, 0.25 )
self.AddParam( "Pads", "height", self.uMM, 1.6)
self.AddParam( "Shield", "shield_to_pad", self.uMM, 1.6 )
self.AddParam( "Shield", "from_top", self.uMM, 1.3 )
self.AddParam( "Shield", "width", self.uMM, 1.5 )
self.AddParam( "Shield", "height", self.uMM, 2 )
# build a rectangular pad
def smdRectPad(self,module,size,pos,name):
pad = pcbnew.PAD(module)
pad.SetSize(size)
pad.SetShape(pcbnew.PAD_SHAPE_RECT)
pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
pad.SetLayerSet( pad.SMDMask() )
pad.SetPosition(pos)
pad.SetName(name)
return pad
def CheckParameters(self):
#TODO implement custom parameter checking
pass
def BuildThisFootprint(self):
p = self.parameters
pad_count = int(p["Pads"]["n"])
pad_width = p["Pads"]["width"]
pad_height = p["Pads"]["height"]
pad_pitch = p["Pads"]["pitch"]
shl_width = p["Shield"]["width"]
shl_height = p["Shield"]["height"]
shl_to_pad = p["Shield"]["shield_to_pad"]
shl_from_top = p["Shield"]["from_top"]
offsetX = pad_pitch * ( pad_count-1 ) / 2
size_pad = pcbnew.VECTOR2I( int(pad_width), int(pad_height) )
size_shld = pcbnew.VECTOR2I(shl_width, shl_height)
size_text = self.GetTextSize() # IPC nominal
# Gives a position and size to ref and value texts:
textposy = pad_height/2 + pcbnew.FromMM(1) + self.GetTextThickness()
angle_degree = 0.0
self.draw.Reference( 0, textposy, size_text, angle_degree )
textposy = textposy + size_text + self.GetTextThickness()
self.draw.Value( 0, textposy, size_text )
# create a pad array and add it to the module
for n in range ( 0, pad_count ):
xpos = (int)(pad_pitch*n - offsetX)
pad = self.smdRectPad(self.module,size_pad, pcbnew.VECTOR2I( xpos, 0), str(n+1))
self.module.Add(pad)
# Mechanical shield pads: left pad and right pad
xpos = -shl_to_pad-offsetX
pad_s0_pos = pcbnew.VECTOR2I( int(xpos), int(shl_from_top) )
pad_s0 = self.smdRectPad(self.module, size_shld, pad_s0_pos, "0")
xpos = (pad_count-1) * pad_pitch+shl_to_pad - offsetX
pad_s1_pos = pcbnew.VECTOR2I( int(xpos), int(shl_from_top) )
pad_s1 = self.smdRectPad(self.module, size_shld, pad_s1_pos, "0")
self.module.Add(pad_s0)
self.module.Add(pad_s1)
# add footprint outline
self.draw.SetLineThickness( pcbnew.FromMM( 0.12 ) ) #Default per KLC F5.1 as of 12/2018
linewidth = self.draw.GetLineThickness()
margin = linewidth
# upper line
posy = -pad_height/2 - linewidth/2 - margin
xstart = - pad_pitch*0.5-offsetX
xend = pad_pitch * pad_count + xstart;
min_y = posy
max_y = posy
self.draw.Line( xstart, posy, xend, posy )
# lower line
posy = pad_height/2 + linewidth/2 + margin
max_y = max( max_y, posy )
self.draw.Line(xstart, posy, xend, posy)
# around left mechanical pad (the outline around right pad is mirrored/y axis)
yend = pad_s0_pos.y + shl_height/2 + margin
max_y = max( max_y, yend )
self.draw.Line(xstart, posy, xstart, yend)
self.draw.Line(-xstart, posy, -xstart, yend)
posy = yend
xend = pad_s0_pos.x - (shl_width/2 + linewidth + margin*2)
max_x = -xend
self.draw.Line(xstart, posy, xend, posy)
# right pad side
self.draw.Line(-xstart, posy, -xend, yend)
# set SMD attribute
self.module.SetAttributes(pcbnew.FP_SMD)
# vertical segment at left of the pad
xstart = xend
yend = posy - (shl_height + linewidth + margin*2)
self.draw.Line(xstart, posy, xend, yend)
# right pad side
self.draw.Line(-xstart, posy, -xend, yend)
max_y = max( max_y, posy )
min_y = min( min_y, yend )
# horizontal segment above the pad
xstart = xend
xend = - pad_pitch*0.5-offsetX
posy = yend
self.draw.Line(xstart, posy, xend, yend)
# right pad side
self.draw.Line(-xstart, posy,-xend, yend)
# vertical segment above the pad
xstart = xend
yend = -pad_height/2 - linewidth/2 - margin
min_y = min( min_y, yend )
self.draw.Line(xstart, posy, xend, yend)
# right pad side
self.draw.Line(-xstart, posy, -xend, yend)
# Courtyard
self.draw.SetLayer(pcbnew.F_CrtYd)
max_x = max_x + linewidth + margin
min_y = min_y - linewidth - margin
max_y = max_y + linewidth + margin
# round size to nearest 0.1mm, rectangle will thus land on a 0.05mm grid
max_x = pcbnew.PutOnGridMM(max_x, 0.05)
max_y = pcbnew.PutOnGridMM(max_y, 0.05)
min_y = pcbnew.PutOnGridMM(min_y, 0.05)
# set courtyard line thickness to the one defined in KLC
self.draw.SetLineThickness(pcbnew.FromMM(0.05))
self.draw.Line( -max_x, min_y, max_x, min_y )
self.draw.Line( max_x, min_y, max_x, max_y )
self.draw.Line( -max_x, max_y, max_x, max_y )
self.draw.Line( -max_x, min_y, -max_x, max_y )
FPC_FootprintWizard().register()