pull in a 40-pin DIP footprint from old pcb library
[hw/altusmetrum] / packages / fplht.py
index 14dd7088ca8dd42c193f44a75c139d81a1e41d2b..8d17148c548d9fb3aee32c4e5d4db28326b05da3 100644 (file)
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
-# Each footprint should have a parent Python script that initializes this 
-# library and provides a high-level description of the primitives required.  
-# The footprint is delivered to stdout, so the encapsulating Makefile and/or 
-# iterating wrapper script is responsible for redirecting to the desired 
+# Each footprint should have a parent Python script that initializes this
+# library and provides a high-level description of the primitives required.
+# The footprint is delivered to stdout, so the encapsulating Makefile and/or
+# iterating wrapper script is responsible for redirecting to the desired
 # <something>.lht file(s).
 #
 # all dimensions are assumed to be in mm
 
-import math
 import hashlib
 
 def mils2mm(mils):
@@ -30,7 +29,7 @@ class footprint(object):
     def __init__(self):
         self.name = ""
         self.description = ""
-        self.copyright = "Copyright 2020 by Bdale Garbee <bdale@gag.com>"
+        self.copyright = ""
         self.dist_license = "GPLv3"
         self.use_license = "Unlimited"
         self.cnt = 0
@@ -39,13 +38,13 @@ class footprint(object):
 
         # process defaults, based on greatest process minimum at our vendors
 
-        self.process_soldermask = mils2mm(3);        # space between pad and mask
-        self.process_trace = mils2mm(6);        # trace width
-        self.process_space = mils2mm(6);        # spacing
-        self.process_drill = mils2mm(13);        # drill dize
-        self.process_ring = mils2mm(7);                # annular ring
+        self.process_soldermask = mils2mm(3)    # space between pad and mask
+        self.process_trace = mils2mm(6)        # trace width
+        self.process_space = mils2mm(6)        # spacing
+        self.process_drill = mils2mm(13)        # drill dize
+        self.process_ring = mils2mm(7)                # annular ring
 
-        self.line_thickness = mils2mm(10);        # default silk line width
+        self.line_thickness = mils2mm(10)        # default silk line width
 
         # the basic plan is that each primitive function puts the object
         # definition in the relevant dictionary .. when we go to emit the
@@ -53,198 +52,198 @@ class footprint(object):
         # prototypes by iterating over the dictionaries... then output the
         # working set of required objects
 
-    def pad(self,d):
+    def pad(self, d):
         # we expect these to be provided
         #
-        # x                center of pad
+        # x             center of pad
         # y
-        # width                size of pad
+        # width         size of pad
         # height
         # name
         # number
         #
         # the following are normally computed / defaulted, but can be provided
         #
-        # x1                start of pad "line"
+        # x1             start of pad "line"
         # y1
-        # x2                end of pad "line"
+        # x2             end of pad "line"
         # y2
-        # thickness        thickness of pad "line"
+        # thickness      thickness of pad "line"
         # spacing        space between pad and other traces
-        # soldermask        space between pad and solder mask
-        # clearance        twice the spacing between pad and other traces
-        # mask                thickness of pad and solder mask
+        # soldermask     space between pad and solder mask
+        # clearance      twice the spacing between pad and other traces
+        # mask           thickness of pad and solder mask
         # options        default to 'square'
 
         # print ("adding pad")
         d['type'] = 'pad'
 
         if 'x1' not in d:
-                d['x1'] = d['x'] - max(0, (d['width'] - d['height']) /2)
+            d['x1'] = d['x'] - max(0, (d['width'] - d['height']) / 2)
         if 'x2' not in d:
-                d['x2'] = d['x'] + max(0, (d['width'] - d['height']) /2)
+            d['x2'] = d['x'] + max(0, (d['width'] - d['height']) / 2)
         if 'y1' not in d:
-                d['y1'] = d['y'] - max(0, (d['height'] - d['width']) /2)
+            d['y1'] = d['y'] - max(0, (d['height'] - d['width']) / 2)
         if 'y2' not in d:
-                d['y2'] = d['y'] + max(0, (d['height'] - d['width']) /2)
+            d['y2'] = d['y'] + max(0, (d['height'] - d['width']) / 2)
         if 'thickness' not in d:
-                d['thickness'] = min(d['width'], d['height'])
+            d['thickness'] = min(d['width'], d['height'])
         if 'spacing' not in d:
-                d['spacing'] = self.process_space
+            d['spacing'] = self.process_space
         if 'soldermask' not in d:
-                d['soldermask'] = self.process_soldermask
+            d['soldermask'] = self.process_soldermask
         if 'clearance' not in d:
-                d['clearance'] = d['spacing'] / 2
+            d['clearance'] = d['spacing'] / 2
         if 'mask' not in d:
-                d['mask'] = d['thickness'] + d['soldermask'] * 2
+            d['mask'] = d['thickness'] + d['soldermask'] * 2
         if 'options' not in d:
-                d['options'] = 'square'
+            d['options'] = 'square'
 
         self.items = self.items + [d]
 
-    def pin():
+    def pin(self, d):
         # we expect these to be provided
         #
-        # x                center of pin
+        # x             center of pin
         # y
-        # drill                diameter of drill hole
+        # drill         diameter of drill hole
         # name
         # number
         #
         # the following are normally computed / defaulted, but can be provided
         #
-        # ring                width of annular ring around hole
-        # spacing        space between pin and other traces
-        # soldermask        space between pin and solder mask
-        # thickness        thickness of pin "line"
-        # clearance        twice the spacing between pad and other traces
-        # mask                thickness of pad and solder mask
-        # options        default to 'square' for pin number 1
+        # ring          width of annular ring around hole
+        # spacing       space between pin and other traces
+        # soldermask    space between pin and solder mask
+        # thickness     thickness of pin "line"
+        # clearance     twice the spacing between pad and other traces
+        # mask          thickness of pad and solder mask
+        # options       default to 'square' for pin number 1
 
         # print ("adding pin")
         d['type'] = 'pin'
 
         if 'spacing' not in d:
-                d['spacing'] = self.process_space
+            d['spacing'] = self.process_space
         if 'ring' not in d:
-                d['ring'] = self.process_ring
+            d['ring'] = self.process_ring
         if 'soldermask' not in d:
-                d['soldermask'] = self.process_soldermask
+            d['soldermask'] = self.process_soldermask
         if 'clearance' not in d:
-                d['clearance'] = d['spacing'] * 2
+            d['clearance'] = d['spacing'] * 2
         if 'mask' not in d:
-                d['mask'] = d['thickness'] + d['soldermask'] * 2
+            d['mask'] = d['thickness'] + d['soldermask'] * 2
         if 'options' not in d:                # default pin 1 to square ring
             if d['number'] == '1':
                 d['options'] = 'square'
             else:
                 d['options'] = ''
         if 'thickness' not in d:
-                d['thickness'] = d['drill'] + d['ring'] * 2
+            d['thickness'] = d['drill'] + d['ring'] * 2
         if 'mask' not in d:
-                d['mask'] = d['thickness'] + d['soldermask'] * 2
+            d['mask'] = d['thickness'] + d['soldermask'] * 2
 
         self.items = self.items + [d]
-    
-    def slot(self,d):
+
+    def slot(self, d):
         # we expect these to be provided
         #
-        # x                center of slot
+        # x             center of slot
         # y
-        # width                size of slot
+        # width         size of slot
         # height
         # name
         # number
         #
         # the following are normally computed / defaulted, but can be provided
         #
-        # x1                start of slot "line"
+        # x1            start of slot "line"
         # y1
-        # x2                end of slot "line"
+        # x2            end of slot "line"
         # y2
-        # spacing        space between slot copper and other traces
-        # thickness        width of copper edge to edge across slot
-        # soldermask        space between slot copper and solder mask
-        # clearance        twice the spacing between slot copper and other traces
-        # mask                thickness of slot copper and solder mask
+        # spacing       space between slot copper and other traces
+        # thickness     width of copper edge to edge across slot
+        # soldermask    space between slot copper and solder mask
+        # clearance     twice the spacing between slot copper and other traces
+        # mask          thickness of slot copper and solder mask
 
         # print ("adding slot")
         d['type'] = 'slot'
 
         if 'x1' not in d:
-                d['x1'] = d['x'] - max(0, (d['width'] - d['height']) /2)
+            d['x1'] = d['x'] - max(0, (d['width'] - d['height']) / 2)
         if 'x2' not in d:
-                d['x2'] = d['x'] + max(0, (d['width'] - d['height']) /2)
+            d['x2'] = d['x'] + max(0, (d['width'] - d['height']) / 2)
         if 'y1' not in d:
-                d['y1'] = d['y'] - max(0, (d['height'] - d['width']) /2)
+            d['y1'] = d['y'] - max(0, (d['height'] - d['width']) / 2)
         if 'y2' not in d:
-                d['y2'] = d['y'] + max(0, (d['height'] - d['width']) /2)
+            d['y2'] = d['y'] + max(0, (d['height'] - d['width']) / 2)
         if 'spacing' not in d:
-                d['spacing'] = self.process_space
+            d['spacing'] = self.process_space
         if 'thickness' not in d:
-                d['thickness'] = d['width'] + self.process_ring * 2
+            d['thickness'] = d['width'] + self.process_ring * 2
         if 'soldermask' not in d:
-                d['soldermask'] = self.process_soldermask
+            d['soldermask'] = self.process_soldermask
         if 'clearance' not in d:
-                d['clearance'] = d['spacing'] / 2
+            d['clearance'] = d['spacing'] / 2
         if 'mask' not in d:
-                d['mask'] = d['thickness'] + d['soldermask'] * 2
+            d['mask'] = d['thickness'] + d['soldermask'] * 2
 
         self.items = self.items + [d]
 
-    ## for silk layers
-    def line():
+    # for silk layers
+    def line(self, d):
         # we expect these to be provided
         #
-        # x1                start of silk line
+        # x1            start of silk line
         # y1
-        # x2                end of silk line
+        # x2            end of silk line
         # y2
         #
         # the following are normally defaulted, but can be provided
         #
-        # thickness        thickness of silk line
+        # thickness     thickness of silk line
 
-        print ("adding line")
+        print("adding line")
         d['type'] = 'line'
 
         if 'thickness' not in d:
-                d['thickness'] = self.line_thickness
-        
+            d['thickness'] = self.line_thickness
+
         self.items = self.items + [d]
 
-    def arc():
+    def arc(self, d):
         # we expect these to be provided
         #
-        # x                center of silk arc
+        # x             center of silk arc
         # y
-        # width        
+        # width
         # height
         # startangle
         # deltaangle
         #
         # the following are normally defaulted, but can be provided
         #
-        # thickness        thickness of silk line
+        # thickness     thickness of silk line
 
-        print ("adding arc")
+        print("adding arc")
         d['type'] = 'arc'
 
         if 'thickness' not in d:
-                d['thickness'] = self.line_thickness
-        
+            d['thickness'] = self.line_thickness
+
         self.items = self.items + [d]
 
     def write_pin_square(size):
         print("       li:ps_poly {")
         print("        %u mm" % -size / 2)
         print("        %u mm" % -size / 2)
-        print("        %u mm" %  size / 2)
+        print("        %u mm" % size / 2)
         print("        %u mm" % -size / 2)
-        print("        %u mm" %  size / 2)
-        print("        %u mm" %  size / 2)
+        print("        %u mm" % size / 2)
+        print("        %u mm" % size / 2)
         print("        %u mm" % -size / 2)
-        print("        %u mm" %  size / 2)
+        print("        %u mm" % size / 2)
         print("       }")
 
     def write_pin_circle(size):
@@ -254,13 +253,13 @@ class footprint(object):
         print("        dia = $u mm" % size)
         print("       }")
 
-    def write_pin_shape(p, layer):
+    def write_stack_shape(p, layer):
         print("      ha:ps_shape_v4 {")
         print("       clearance = %u mm" % p['clearance'])
         if p['options'] == 'square':
-            write_pin_square(p['copper']) 
+            write_pin_square(p['copper'])
         else:
-            write_pin_circle(p['copper']) 
+            write_pin_circle(p['copper'])
         print("       ha:layer_mask {")
         print("        copper = 1")
         print("        $s = 1" % layer)
@@ -268,7 +267,7 @@ class footprint(object):
         print("      }")
 
     def emit_padstack_prototypes(self):
-        # iterate over copper items creating min set of padstack prototypes, 
+        # iterate over copper items creating min set of padstack prototypes,
         # and annotating items with their prototype number as we go
         protocount = 0
         for i in self.items:
@@ -292,7 +291,7 @@ class footprint(object):
         # print ("%u unique prototypes found" % protocount)
 
         # now that we have the set of prototypes, emit them
-        print ("   li:padstack_prototypes {")
+        print("   li:padstack_prototypes {")
         for thisp in self.padstacks:
             p = self.padstacks[thisp]
             if p['type'] == 'pin':
@@ -317,7 +316,18 @@ class footprint(object):
                 print("     }")
                 print("    }")
 
-        print ("   }")
+            if p['type'] == 'slot':
+                # this is just a copy of the 'pad' code for now
+                print("    ha:ps_proto_v4.%u {" % p['prototypenumber'])
+                print("     htop = 0")
+                print("     hbottom = 0")
+                print("     hplated = 1")
+                print("     hdia = %u mm" % 0)         # bogus to the max
+                print("     li:shape {")
+                print("     }")
+                print("    }")
+
+        print("   }")
 
     def emit_padstacks(self):
         print("padstacks will go here")
@@ -355,9 +365,9 @@ class footprint(object):
         print("      virtual = 1")
         print("     }")
         print("     li:objects {")
-        self.emit_line("origin", self.cnt, 0, 0, 0, 0, "mm");
-        self.emit_line("x", self.cnt, 0, 0, 1, 0, "mm");
-        self.emit_line("y", self.cnt, 0, 0, 0, 1, "mm");
+        self.emit_line("origin", self.cnt, 0, 0, 0, 0, "mm")
+        self.emit_line("x", self.cnt, 0, 0, 1, 0, "mm")
+        self.emit_line("y", self.cnt, 0, 0, 0, 1, "mm")
         print("     }")
         print("    }")
 
@@ -385,4 +395,4 @@ class footprint(object):
         print("   }")
         print("  }")
         print(" }")
-        print("}")
+        print("}")
\ No newline at end of file