# 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):
def __init__(self):
self.name = ""
self.description = ""
+ self.copyright = ""
self.dist_license = "GPLv3"
self.use_license = "Unlimited"
- self.author = "Bdale Garbee <bdale@gag.com>"
self.cnt = 0
self.items = []
self.padstacks = dict()
# 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
# 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")
+ # 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
-
- print ("adding pin")
+ # 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")
+ # 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):
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)
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:
# 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':
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")
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(" }")
print(" ha:subc.0 {")
print(" ha:attributes {")
print(" description = %s" % self.description)
+ print(" copyright = %s" % self.copyright)
print(" dist_license = %s" % self.dist_license)
print(" use_license = %s" % self.use_license)
- print(" author = %s" % self.author)
print(" }")
print(" uid = %s" % self.create_uuid())
print(" ha:data {")
print(" }")
print(" }")
print(" }")
- print("}")
+ print("}")
\ No newline at end of file