← Back to team overview

kicad-developers team mailing list archive

Re: kicad footprint plugins wizard in windows

 

Hi,

I attached a patch that is implementing epad and thermal vias on qfp_wizard.

the script is almost completed ...
I have three kind of questions:
1) how could I eliminate front silk on thermal via (pads)? I couldn't find a class to do it 2) is there a way to reduce solder Mask on bottom layer for vias? I couldn't find a class to do it 3) in which order the Parameters list is created? I don't know how to put similar inputs close each others
 (e.g. epad thermal w pitch, epad thermal l, epad solder paste ratio)

I used as reference the microchip qfn 64 as in:
http://www.microchip.com/mymicrochip/filehandler.aspx?ddocname=en012702
http://ww1.microchip.com/downloads/en/PackagingSpec/00000049BY.pdf
at page 397,398
64-Lead Plastic Quad Flat, No Lead Package (MR) – 9x9x0.9 mm Body [QFN]
With 7.70 x 7.70 Exposed Pad [QFN]

than you
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-08-29 21:25:33.516578500 +0200
+++ qfp_wizard.py	2015-08-31 14:54:31.031976300 +0200
@@ -24,22 +24,33 @@
 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 thermal w pitch", self.uMM, 1.0)
+        self.AddParam("Pads", "epad thermal l pitch", self.uMM, 1.0)
+        self.AddParam("Pads", "epad solder paste ratio", self.uNatural, 0.8)
+
+        self.AddParam("Pads", "epad thermal via diam", self.uMM, 0.3)
+        self.AddParam("Pads", "epad thermal via size", self.uMM, 0.5)
+
 
-        self.AddParam("Pads", "package width", self.uMM, 14)
-        self.AddParam("Pads", "package height", self.uMM, 14)
 
     def CheckParameters(self):
 
@@ -57,6 +68,16 @@
         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_th_pitch_w = self.parameters["Pads"]["epad thermal w pitch"]
+        epad_th_pitch_l = self.parameters["Pads"]["epad thermal l pitch"]
+        epad_paste_ratio = pads["*epad solder paste ratio"]
+
+        epad_th_via_dm = self.parameters["Pads"]["epad thermal via diam"]
+        epad_th_via_sz = self.parameters["Pads"]["epad thermal via size"]
+
         v_pitch = pads["vertical pitch"]
         h_pitch = pads["horizontal pitch"]
 
@@ -99,6 +120,39 @@
         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(0)
+            array.SetFirstPadInArray(pads["*n"]+1)
+            array.AddPadsToModule(self.draw)
+
+            epad_width_part_size_w = epad_th_pitch_w*epad_paste_ratio  #size of one part of exposed pad
+            epad_width_part_size_l = epad_th_pitch_l*epad_paste_ratio
+            n_epad_parts_w = int(epad_width/epad_th_pitch_w)
+            n_epad_parts_l = int(epad_length/epad_th_pitch_l)
+            epad_paste = PA.PadMaker(self.module).SMDPad(
+            epad_width_part_size_w, epad_width_part_size_l, shape=pcbnew.PAD_SHAPE_RECT)
+
+            array_epad = PA.PadThermalArray(epad_paste, n_epad_parts_w, n_epad_parts_l,
+                                 epad_th_pitch_w, epad_th_pitch_l, epadPos)
+            array_epad.SetFirstPadInArray(pads["*n"]+1)
+
+            array_epad.AddPadsToModule(self.draw)
+            
+            epad_th_pad = PA.PadMaker(self.module).THRoundPad(
+                    epad_th_via_sz,
+                    epad_th_via_dm)
+            
+            array_epad_th = PA.PadThermalArray(epad_th_pad, n_epad_parts_w, n_epad_parts_l,
+                                         epad_th_pitch_w, epad_th_pitch_l, epadPos)
+            array_epad_th.SetFirstPadInArray(pads["*n"]+1)
+            array_epad_th.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-08-31 14:58:33.000000000 +0200
+++ PadArray.py	2015-08-31 14:54:51.558786000 +0200
@@ -76,6 +76,28 @@
         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
+
+    ##def SMDePadPaste(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.SMDMask())
+    ##    pad.SetPadName("100")
+    ##
+    ##    return pad
 
 class PadArray:
 
@@ -257,3 +279,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