- self.units = "mm"
- self.name = ""
- self.description = ""
- self.dist_license = "GPLv3"
- self.use_license = "Unlimited"
- self.author = "Bdale Garbee <bdale@gag.com>"
- self.cnt = 0
-
- # primitive objects
- # (proposed argument lists taken from pcb land_patterns doc)
- # -- can probably collapse sflags+nflags->flags?
-
- # the basic plan is that each primitive function puts the object
- # definition in the relevant dictionary .. when we go to emit the
- # part, we'll do things like work out the minimum set of padstack
- # prototypes by iterating over the dictionaries... then output the
- # working set of required objects
-
- ## for copper layers
- # def pad():
- # x1, y1, x2, y2, thickness, clearance, mask, name, number, sflags, nflags
- # def pin():
- # x, y, thickness, clearance, mask, drill, name, number, sflags, nflags
- # def slot():
-
- ## for silk layers
- # def line():
- # x1, y1, x2, y2, thickness
- # def arc():
- # x, y, width, height, startangle, deltaangle, thickness
+ self.name = ""
+ self.description = ""
+ self.copyright = ""
+ self.dist_license = "GPLv3"
+ self.use_license = "Unlimited"
+ 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.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
+ # part, we'll do things like work out the minimum set of padstack
+ # prototypes by iterating over the dictionaries... then output the
+ # working set of required objects
+
+ def pad(self, d):
+ # we expect these to be provided
+ #
+ # x center of pad
+ # y
+ # width size of pad
+ # height
+ # name
+ # number
+ #
+ # the following are normally computed / defaulted, but can be provided
+ #
+ # x1 start of pad "line"
+ # y1
+ # x2 end of pad "line"
+ # y2
+ # 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
+ # 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)
+ if 'x2' not in d:
+ 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)
+ if 'y2' not in d:
+ d['y2'] = d['y'] + max(0, (d['height'] - d['width']) / 2)
+ if 'thickness' not in d:
+ d['thickness'] = min(d['width'], d['height'])
+ if 'spacing' not in d:
+ d['spacing'] = self.process_space
+ if 'soldermask' not in d:
+ d['soldermask'] = self.process_soldermask
+ if 'clearance' not in d:
+ d['clearance'] = d['spacing'] / 2
+ if 'mask' not in d:
+ d['mask'] = d['thickness'] + d['soldermask'] * 2
+ if 'options' not in d:
+ d['options'] = 'square'
+
+ self.items = self.items + [d]
+
+ def pin(self, d):
+ # we expect these to be provided
+ #
+ # x center of pin
+ # y
+ # 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")
+ d['type'] = 'pin'
+
+ if 'spacing' not in d:
+ d['spacing'] = self.process_space
+ if 'ring' not in d:
+ d['ring'] = self.process_ring
+ if 'soldermask' not in d:
+ d['soldermask'] = self.process_soldermask
+ if 'clearance' not in d:
+ d['clearance'] = d['spacing'] * 2
+ if 'mask' not in d:
+ 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
+ if 'mask' not in d:
+ d['mask'] = d['thickness'] + d['soldermask'] * 2
+
+ self.items = self.items + [d]
+
+ def slot(self, d):
+ # we expect these to be provided
+ #
+ # x center of slot
+ # y
+ # width size of slot
+ # height
+ # name
+ # number
+ #
+ # the following are normally computed / defaulted, but can be provided
+ #
+ # x1 start of slot "line"
+ # y1
+ # 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
+
+ # print ("adding slot")
+ d['type'] = 'slot'
+
+ if 'x1' not in d:
+ 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)
+ if 'y1' not in d:
+ 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)
+ if 'spacing' not in d:
+ d['spacing'] = self.process_space
+ if 'thickness' not in d:
+ d['thickness'] = d['width'] + self.process_ring * 2
+ if 'soldermask' not in d:
+ d['soldermask'] = self.process_soldermask
+ if 'clearance' not in d:
+ d['clearance'] = d['spacing'] / 2
+ if 'mask' not in d:
+ d['mask'] = d['thickness'] + d['soldermask'] * 2
+
+ self.items = self.items + [d]
+
+ # for silk layers
+ def line(self, d):
+ # we expect these to be provided
+ #
+ # x1 start of silk line
+ # y1
+ # x2 end of silk line
+ # y2
+ #
+ # the following are normally defaulted, but can be provided
+ #
+ # thickness thickness of silk line
+
+ print("adding line")
+ d['type'] = 'line'
+
+ if 'thickness' not in d:
+ d['thickness'] = self.line_thickness
+
+ self.items = self.items + [d]
+
+ def arc(self, d):
+ # we expect these to be provided
+ #
+ # x center of silk arc
+ # y
+ # width
+ # height
+ # startangle
+ # deltaangle
+ #
+ # the following are normally defaulted, but can be provided
+ #
+ # thickness thickness of silk line
+
+ print("adding arc")
+ d['type'] = 'arc'
+
+ if 'thickness' not in d:
+ 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(" }")
+
+ def write_pin_circle(size):
+ print(" ha:ps_circ {")
+ print(" x = 0")
+ print(" y = 0")
+ print(" dia = $u mm" % size)
+ print(" }")
+
+ 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'])
+ else:
+ write_pin_circle(p['copper'])
+ print(" ha:layer_mask {")
+ print(" copper = 1")
+ print(" $s = 1" % layer)
+ print(" }")
+ print(" }")