← Back to team overview

kicad-developers team mailing list archive

Re: kicad footprint plugins wizard in windows

 

Hi JP,

here is the patch with one exposed pad not on solder paste (but on solder mask) + this array of pads on solder paste. the same pad name for all of them, and pads optional in wizard (assigning epad subdivision to 0 epad array won't be generated;
 assigning epad width or lenght to 0, epad  won't be generated).

Maurice

On 30/08/2015 20.27, jp charras wrote:
Le 30/08/2015 19:21, nnn a écrit :
It may be better to make exposed pad as array of smaller pads for better
application of solder paste. This will also allow to easily change the
pad into array of tht pads for improved power dissipation. Below - how I
did it in C (full code here:
https://github.com/michal777/KiCad_Footprint_Generator). I think exposed
pad should be numbered max+1 because sometimes there are more exposed pads.

Exactly one exposed pad not on solder paste (but on solder mask) + this
array of pads on solder paste.

Keep the same pad name for all of them, and make them optional in wizard.

--- qfp_wizard-old.py	2015-09-03 15:04:44.826058400 +0200
+++ qfp_wizard.py	2015-09-03 15:13:51.682393300 +0200
@@ -24,22 +24,29 @@
 class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):

     def GetName(self):
-        return "QFP"
+        return "QFP/QFN"

     def GetDescription(self):
-        return "QFP Footprint Wizard"
+        return "QFP/QFN Footprint Wizard"

     def GenerateParameterList(self):
-        self.AddParam("Pads", "n", self.uNatural, 100)
+
+        self.AddParam("Pads", "n", self.uNatural, 64)
         self.AddParam("Pads", "pad pitch", self.uMM, 0.5)
-        self.AddParam("Pads", "pad width", self.uMM, 0.25)
-        self.AddParam("Pads", "pad length", self.uMM, 1.5)
-        self.AddParam("Pads", "vertical pitch", self.uMM, 15)
-        self.AddParam("Pads", "horizontal pitch", self.uMM, 15)
-        self.AddParam("Pads", "oval", self.uBool, True)
+        self.AddParam("Pads", "pad width", self.uMM, 0.3)
+        self.AddParam("Pads", "pad length", self.uMM, 0.9)
+        self.AddParam("Pads", "vertical pitch", self.uMM, 8.9)
+        self.AddParam("Pads", "horizontal pitch", self.uMM, 8.9)
+        self.AddParam("Pads", "oval", self.uBool, False)
+        self.AddParam("Pads", "package width", self.uMM, 9)
+        self.AddParam("Pads", "package height", self.uMM, 9)
+        self.AddParam("Pads", "epad width", self.uMM, 7.5)
+        self.AddParam("Pads", "epad length", self.uMM, 7.5)
+        self.AddParam("Pads", "epad subdivision h", self.uNatural, 2)
+        self.AddParam("Pads", "epad subdivision v", self.uNatural, 2)
+        self.AddParam("Pads", "Name prefix QFP/QFN", self.uString, 'QFN')
+        self.AddParam("Pads", "epad solder paste ratio", self.uNatural, 0.8)

-        self.AddParam("Pads", "package width", self.uMM, 14)
-        self.AddParam("Pads", "package height", self.uMM, 14)

     def CheckParameters(self):

@@ -47,16 +54,24 @@
         self.CheckParamBool("Pads", "*oval")

     def GetValue(self):
-        return "QFP_%d" % self.parameters["Pads"]["*n"]
+        return "%s_%d" % (self.parameters["Pads"]["*Name prefix QFP/QFN"], self.parameters["Pads"]["*n"])

     def BuildThisFootprint(self):

         pads = self.parameters["Pads"]

+        module_prefix = pads["*Name prefix QFP/QFN"]
         pad_pitch = pads["pad pitch"]
         pad_length = self.parameters["Pads"]["pad length"]
         pad_width = self.parameters["Pads"]["pad width"]

+        epad_length = self.parameters["Pads"]["epad length"]
+        epad_width = self.parameters["Pads"]["epad width"]
+        epad_subd_l = pads["*epad subdivision h"]
+        epad_subd_w = pads["*epad subdivision v"]
+
+        epad_paste_ratio = pads["*epad solder paste ratio"]
+
         v_pitch = pads["vertical pitch"]
         h_pitch = pads["horizontal pitch"]

@@ -99,6 +114,29 @@
         array.SetFirstPadInArray(3*pads_per_row + 1)
         array.AddPadsToModule(self.draw)

+        #epad
+        if epad_length!=0 and epad_width!=0:  #there is exposed pad
+            e_pad = PA.PadMaker(self.module).SMDePad(
+            epad_width, epad_length, shape=pcbnew.PAD_SHAPE_RECT)
+            epadPos = pcbnew.wxPoint (0, 0)
+            array = PA.PadLineArray(e_pad, 1, 1, False,
+                                    epadPos)
+            array.SetFirstPadInArray(pads["*n"]+1)
+            array.AddPadsToModule(self.draw)
+
+            if epad_subd_l!=0 and epad_subd_w!=0:
+            #if we want epad
+                epad_width_part_size_w = epad_width / epad_subd_w  #size of one part of exposed pad
+                epad_width_part_size_l = epad_length / epad_subd_l
+                epad_paste = PA.PadMaker(self.module).SMDPad(
+                epad_width_part_size_w*epad_paste_ratio, epad_width_part_size_l*epad_paste_ratio, shape=pcbnew.PAD_SHAPE_RECT)
+
+                array_epad = PA.PadThermalArray(epad_paste, epad_subd_l, epad_subd_w,
+                                    epad_width_part_size_l, epad_width_part_size_w, epadPos)
+
+                array_epad.SetFirstPadInArray(pads["*n"]+1)
+                array_epad.AddPadsToModule(self.draw)
+
         lim_x = pads["package width"] / 2
         lim_y = pads["package height"] / 2
         inner = (row_len / 2) + pad_pitch
--- PadArray-old.py	2015-09-03 15:04:38.426732100 +0200
+++ PadArray.py	2015-09-03 14:02:17.346140600 +0200
@@ -76,6 +76,16 @@
         pad = self.SMDPad(size, size, shape=pcbnew.PAD_SHAPE_CIRCLE)
         return pad

+    def SMDePad(self, w, l, shape=pcbnew.PAD_SHAPE_RECT):
+        pad = pcbnew.D_PAD(self.module)
+        pad.SetSize(pcbnew.wxSize(l, w))
+
+        pad.SetShape(shape)
+
+        pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD)
+        pad.SetLayerSet(pad.ConnSMDMask())
+
+        return pad

 class PadArray:

@@ -257,3 +267,44 @@
             pad.SetPadName(self.GetName(i))

             self.AddPad(pad)
+
+
+
+class PadThermalArray(PadArray):
+
+    def __init__(self, pad, nx, ny, px, py, centre=pcbnew.wxPoint(0, 0)):
+        PadArray.__init__(self)
+        # this pad is more of a "context", we will use it as a source of
+        # pad data, but not actually add it
+        self.pad = pad
+        self.nx = int(nx)
+        self.ny = int(ny)
+        self.px = px
+        self.py = py
+        self.centre = centre
+
+    # right to left, top to bottom
+    def NamingFunction(self, x, y):
+        return self.firstPadNum
+
+    #relocate the pad and add it as many times as we need
+    def AddPadsToModule(self, dc):
+
+        pin1posX = self.centre.x - self.px * (self.nx - 1) / 2
+        pin1posY = self.centre.y - self.py * (self.ny - 1) / 2
+
+        for x in range(0, self.nx):
+
+            posX = pin1posX + (x * self.px)
+
+            for y in range(self.ny):
+                posY = pin1posY + (self.py * y)
+
+                pos = dc.TransformPoint(posX, posY)
+
+                pad = self.GetPad(x == 0 and y == 0, pos)
+
+                pad.SetPadName(self.GetName(x,y))
+
+                self.AddPad(pad)
+

References