Commits

Martin Vejnár committed 32a15f3

Fixed connects, pad names are now visible on pins.

Comments (0)

Files changed (3)

 
 __all__ = ['parse_schematic', 'parse_library']
 
-def _print_b(s):
+def _print_b(s, canon=False, prefix='  '):
     ss = ''.join(((ord(ch) > 0x20 and ord(ch) < 0x7f) and ch or '.' for ch in s))
-    return ':'.join(('%02x' % ord(ch) for ch in s)) + '    ' + ss
+    return prefix + ':'.join(('%02x' % ord(ch) for ch in s)) + ('    ' + ss if canon else '')
 
 def _parse_multistring(data):
     res = []
             0x26: self.rectangle, # TODO
             0x27: self.junction,
             0x2a: self.pad,
-            0x2b: self.ignore, # smd
+            0x2b: self.smd, # smd
             0x2c: self.pin,
             0x2d: self.gate,
             0x30: self.instance,
         c.rectangles.append(o)
 
     def smd(self, entry):
+        # TODO
         o = Smd()
         self.parse_name(o, entry[19:])
         c = self.pop_until(Package)
-        c.smds.append(o)
+        c.contacts.append(o)
 
     def pad(self, entry):
         o = Pad()
         o.shape, layer, o.x, o.y, o.drill, o.diameter, o.angle = unpack('<BBiiHHH', entry[2:18])
         self.parse_name(o, entry[19:])
         c = self.pop_until(Package)
-        c.pads.append(o)
+        c.contacts.append(o)
 
     def deviceset(self, entry):
         o = DeviceSet()
         self.parse_name(o, entry[13:18], 'description')
         self.parse_name(o, entry[8:13], 'prefix')
         o.value = (ord(entry[6]) & 1) != 0
-        o.connect_16b = (ord(entry[6]) & 2) != 0
-        o.device_count, = unpack('<H', entry[2:4])
+        o.connect_type = ord(entry[7])
+        #o.device_count, = unpack('<H', entry[2:4])
         c = self.pop_until(Library)
+        o.parent_lib = c
         c.devicesets.append(o)
         self.ctx.append(o)
         return o
     def device(self, entry):
         c = self.pop_until(DeviceSet)
         o = Device()
+        o.parent_devset = c
+        o.connect_entry_count, o.package_id, = unpack('<HH', entry[2:6])
         self.parse_name(o, entry[6:19], 'joined_technologies')
         self.parse_name(o, entry[19:], 'variant')
         c.devices.append(o)
 
     def connect(self, entry):
         c = self.pop_until(Device)
-        c.connect_string += entry[2:]
+        c.append_connect_info(c.parent_devset.connect_type, entry[2:])
 
     def gate(self, entry):
         o = Gate()
         o.visible = (ord(entry[2]) >> 6) & 3
 
         c = self.pop_until(Symbol)
+        o.id = len(c.pins) + 1
         c.pins.append(o)
         self.ctx.append(o)
 
+from struct import unpack
+import array
+
 #__all__ = ['Schematic', 'Layer', 'Attribute', 'Net',
 #    'Segment', 'Wire', 'Library', 'Symbol', 'Package']
 
     def __init__(self):
         self.technologies = []
         self.connect_string = ''
+        self.connects = []
 
     @property
     def joined_technologies(self):
         techs.pop(0)
         self.technologies = techs
 
+    def append_connect_info(self, connect_type, raw_connect):
+        bit_count = connect_type & 0xf
+        mask = (1<<bit_count)-1
+        if connect_type & 0x80:
+            raw_connect = array.array('B', raw_connect).tolist()
+        else:
+            raw_connect = array.array('H', raw_connect).tolist()
+        self.connects.extend([(val >> bit_count, val & mask) for val in raw_connect])
+
+    def get_contact_for_pin(self, gate_id, pin_id):
+        for i, (g, p) in enumerate(self.connects):
+            if (g, p) == (gate_id, pin_id):
+                return self.parent_devset.parent_lib.packages[self.package_id-1].contacts[i]
+        return None
+
 class Board(EagleObject):
     pass
 
 class Package(EagleObject):
     def __init__(self):
         self.circles = []
-        self.smds = []
-        self.pads = []
+        self.contacts = [] # pads and smds, order matters
         self.frames = []
         self.holes = []
         self.polygons = []
                 wire.x1, -wire.y1, wire.radius, wire.radius, angle > math.pi, 0 if wire.ccw else 1, wire.x2, -wire.y2,
                 self.color_map[layer.color], wire.width*2))
 
-    def print_pin(self, pin, mirror=False, rot=0):
+    def print_pin(self, pin, mirror=False, rot=0, device=None, gate_id=None):
         len = pin.length * 2540 * 10
 
         def _get_target(x, y, len, angle):
             o.x, o.y = _get_target_xy(pin.x, pin.y, len + text_distance, -int(7620*2.5/2), pin.angle)
             self.print_text(o, mirror=mirror, rotate=rot)
 
-        if 0 and (pin.visible & pin.PIN_VISIBLE_FLAG_PAD):
-            # TODO: we need to get the pad this pin is connected to
-            o = Text()
-            o.value = str(pin.angle)
-            # TODO: o.font, o.ratio
-            o.layer = 95
-            o.size = int(7620*2.5/2)
-            if pin.angle == 0:
-                o.angle = 0
-                o.mirror = True
-            elif pin.angle == 1:
-                o.angle = 3*0x400
-                o.mirror = True
-            elif pin.angle == 2:
-                o.angle = 0
-                o.mirror = False
-            elif pin.angle == 3:
-                o.angle = 0x400
-                o.mirror = False
+        if device and (pin.visible & pin.PIN_VISIBLE_FLAG_PAD):
+            contact = device.get_contact_for_pin(gate_id, pin.id)
+            if contact:
+                o = Text()
+                o.value = contact.name
+                # TODO: o.font, o.ratio
+                o.layer = 95
+                o.size = int(7620*2.5/2)
+                if pin.angle == 0:
+                    o.angle = 0
+                    o.mirror = True
+                elif pin.angle == 1:
+                    o.angle = 3*0x400
+                    o.mirror = True
+                elif pin.angle == 2:
+                    o.angle = 0
+                    o.mirror = False
+                elif pin.angle == 3:
+                    o.angle = 0x400
+                    o.mirror = False
 
-            o.x, o.y = _get_target_xy(pin.x, pin.y, max(0, len - 2540 * 10), 2540 if pin.angle < 2 else -2540, pin.angle)
-            self.print_text(o, mirror=mirror, rotate=rot)
+                o.x, o.y = _get_target_xy(pin.x, pin.y, max(0, min(len - max(shorten_wire, 2540*2), 2540 * 12)), 2540 if pin.angle < 2 else -2540, pin.angle)
+                self.print_text(o, mirror=mirror, rotate=rot)
 
     def print_text(self, text, mirror=False, rotate=0):
         self.update_bb(text.x - text.size, text.y - text.size)
             return
         gate = devset.gates[inst.gate_id-1]
         sym = lib.symbols[gate.symbol_id-1]
+        device = devset.devices[part.device_id-1]
 
         def _print_text(text):
             o = Text()
         self.out.append("""<g transform="%s"><use xlink:href="#g%d"/>""" % (' '.join(trans), sym.group_id))
 
         for pin in sym.pins:
-            self.print_pin(pin, mirror=inst.mirror, rot=inst.angle)
+            self.print_pin(pin, mirror=inst.mirror, rot=inst.angle, device=device, gate_id=inst.gate_id)
 
         if not inst.smashed:
             for text in sym.texts: