def update_package_view(self): package = self.current_package try: mod = importlib.import_module('packages.{}'.format( package['type'])) except ImportError: return # Draw package # f = tempfile.NamedTemporaryFile() f = open('tmp.svg', 'wb') import target_svg target = target_svg.get_target() target.add_package(package) process = {'F': TolLen(0, 0.05, 1), 'P': TolLen(0, 0.05, 1)} pac = mod.get_package(package['values'], 'IPC7351-B', process) pac.gen(target) target.output(f) f.flush() # Draw SVG output svg = QGraphicsSvgItem(f.name) scene = QGraphicsScene() scene.addItem(svg) self.package_ui.graphicsView.setScene(scene) f.close()
def __init__(self, part, design, process): if (isinstance(part, list)): p = part part = { 'D': TolLen(float(p[0][0]), float(p[0][1])), 'E': TolLen(float(p[1][0]), float(p[1][1])), 'e': float(p[2]), 'L': TolLen(float(p[3][0]), float(p[3][1])), 'b': TolLen(float(p[4][0]), float(p[4][1])), 'npin': int(p[5]) } part['D1'] = part['D'] part['E1'] = part['E'] part['npin1'] = part['npin'] // 4 part['npin2'] = part['npin'] // 4 # part['mark'] = 'circle' # TODO, SVG doesn't handle this yet part['deleted'] = None # IPC7351 density level A, B or C if (design[0:8] == 'IPC7351-'): density = design[8] design = ipc7351.IPC7351['Flat, No Lead'][density] else: print('Cannot handle design {}'.format(design)) return self.generator = packages.quad_row.QuadRow(part, design, process)
def parse_tollens(part): keys = list(part.keys()) for key in keys: if (key[-2:] == '_l' and key[:-2] + '_h' in part): part[key[:-2]] = TolLen(float(part[key[:-2] + '_l']), float(part[key[:-2] + '_h'])) part.pop(key[:-2] + '_l') part.pop(key[:-2] + '_h')
def on_package_value_edited(self, d, edit, text): import re match = False package = self.current_package if (d[1] == 't'): if (re.match('^\s*\d+(\.\d+)?\s*-\s*\d+(\.\d+)?\s*$', text)): match = True # Update value in package r = re.findall('([\d\.]+)', text) min = float(r[0]) max = float(r[1]) package['values'][d[0]] = TolLen(min, max) self.update_package_view() elif (d[1] == 'a'): if (re.match('^\s*\d*(\s+\d+)*\s*$', text)): match = True elif (d[1] == 'm'): if (re.match('-', text)): match = True elif (d[1] == 'f'): if (re.match('^\s*\d+(\.\d+)?\s*$', text)): match = True # Update value in package val = float(text) package['values'][d[0]] = val self.update_package_view() elif (d[1] == 'i'): if (re.match('^\s*\d+\s*$', text)): match = True # Update value in package val = int(text) package['values'][d[0]] = val self.update_package_view() if (match): edit.setStyleSheet('') else: edit.setStyleSheet('QLineEdit { background: rgb(255, 40, 40);}')
def update_package_type(self, type): try: mod = importlib.import_module('packages.{}'.format(type)) except ImportError: return self.current_package['type'] = type for d in mod.get_params(): if (d[0] not in self.current_package['values']): if (d[1] == 't'): self.current_package['values'][d[0]] = TolLen(0, 0) elif (d[1] == 'i'): self.current_package['values'][d[0]] = 0 elif (d[1] == 'f'): self.current_package['values'][d[0]] = 0.0 elif (d[1] == 'm'): self.current_package['values'][d[0]] = '-' elif (d[1] == 'a'): self.current_package['values'][d[0]] = [] elif (d[1] == 'l'): self.current_package['values'][d[ 0]] = 'Flat Ribbon L and Gull-Wing Leads (> 0.625mm pitch)'
part.pop(key[:-2] + '_l') part.pop(key[:-2] + '_h') if (__name__ == '__main__'): import sys import target_eagle from tollen import TolLen target = target_eagle.get_target() if (len(sys.argv) < 2): print('Usage: {} <library.lbr>'.format(sys.argv[0]), file=sys.stderr) fout = open(1, 'w') process = {'F': TolLen(0, 0.05, 1), 'P': TolLen(0, 0.05, 1)} conn = sqlite3.connect(sys.argv[1]) conn.row_factory = sqlite3.Row c = conn.cursor() # Print library c.execute('SELECT * FROM library') print('Library version: {}\nName: {}\n{}'.format(*c.fetchone()), file=sys.stderr) c.execute('SELECT * FROM symbols') for sym in c.fetchall(): target.add_symbol(sym['name'])
def on_packages_select(self): w = uic.loadUi('package.ui') self.package_ui = w i = self.wnd.packages.currentRow() package = self.packages[i] self.current_package = package # Add package types import packages for type in packages.__all__: w.types.addItem(type) if (type == package['type']): w.types.setCurrentIndex(w.types.count() - 1) w.types.currentTextChanged.connect(self.update_package_type) # Add package widget oldw = self.wnd.verticalLayout_2.itemAt(1) self.wnd.verticalLayout_2.removeItem(oldw) self.wnd.verticalLayout_2.addWidget(w) oldw.widget().setParent(None) # Add package values try: mod = importlib.import_module('packages.{}'.format( package['type'])) except ImportError: return x = 0 y = 0 for d in mod.get_params(): val = QLineEdit() w.grid_values.addWidget(QLabel(d[0]), y, x + 0) w.grid_values.addWidget(val, y, x + 1) val.textEdited.connect(lambda x, val=val, d=d: self. on_package_value_edited(d, val, x)) if (d[1] == 't'): min = package['values'][d[0] + '_l'] max = package['values'][d[0] + '_h'] val.setText('{} - {}'.format(min, max)) package['values'][d[0]] = TolLen(min, max) elif (d[1] == 'a'): pass else: v = package['values'][d[0]] val.setText('{}'.format(v)) x += 2 if (x > 3): x = 0 y += 1 # Add package svg w.vert34.removeWidget(w.package_info) w.package_info.setParent(None) w.package_info = QSvgWidget('packages/{}.svg'.format(package['type'])) w.vert34.addWidget(w.package_info) self.update_package_view()
target.add_package('DIOM2012') target.add_pac_pad(0, 0, (1, 1), (-1, 0), 0) target.add_pac_pad(0, 0, (1, 1), (1, 0), 1) target.add_pac_line('Courtyard', 0.1, [(-2, -1), (-2, 1), (2, 1), (2, -1), ('end', 0)]) target.add_pac_circle('Silk', 0.1, (-1, 0.75)) target.add_pac_line('Silk', 0.1, [(-0.5, -0.5), (0.5, -0.5)]) target.add_pac_line('Silk', 0.1, [(-0.5, 0.5), (0.5, 0.5)]) target.add_pac_rectangle('Silk', (-0.5, -0.5), (0, 0.5)) target.add_pac_text('Name', '>NAME', (-0.5, 0)) ## Add some packages via parameters soic8 = { 'E1': TolLen(3.9, 4.4), 'D': TolLen(4.9, 5.2), 'e': 1.27, 'E': TolLen(5.90, 6.10), 'L': TolLen(0.40, 1.27), 'b': TolLen(0.31, 0.51), 'npin': 8, 'deleted': None, 'mark': 'circle' } diode = { 'E1': TolLen(1.85, 2.15), 'D': TolLen(1.10, 1.40), 'e': 0, 'E': TolLen(1.85, 2.15),
def calculate_pattern(self): if ('S' not in self.part): self.part['S'] = self.part['E'] - self.part['L'] - self.part['L'] if ('E' not in self.part): self.part['E'] = self.part['S'] + self.part['L'] + self.part['L'] E = self.part['E'] S = self.part['S'] b = self.part['b'] J_T = TolLen(self.design['J_T'], 0, 1) J_H = TolLen(self.design['J_H'], 0, 1) J_S = TolLen(self.design['J_S'], 0, 1) CE = self.design['CE'] F = self.process['F'] P = self.process['P'] # Z if ('Z' in self.part and self.part['Z']): Z = self.part['Z'] else: # Q = E + 2*JT + F + P # Zmax = Qmax + Qtol - Etol Q = E + J_T + J_T + F + P Z = Q.max + Q.tol - E.tol # G if ('G' in self.part and self.part['G']): G = self.part['G'] else: # Q = S - 2*JH + F + P # Gmin = Qmin - Qtol + Stol Q = S - J_H - J_H + F + P G = Q.min - Q.tol + S.tol # X if ('X' in self.part and self.part['X']): X = self.part['X'] else: # Q = b + 2*JS + F + P # Xmax = Qmax + Qtol - btol Q = b + J_S + J_S + F + P X = Q.max + Q.tol - b.tol # Y if ('Y' in self.part and self.part['Y']): Y = self.part['Y'] else: Y = (Z - G) / 2 # C if ('C' in self.part and self.part['C']): C = self.part['C'] else: C = G + Y # TODO: trimming # TODO: rounding (eg 1.05, 1.10 1.15 (c=0.05) x = round(x0/c)*c self.land['C'] = round(C, 1) self.land['G'] = round(G, 1) self.land['X'] = round(X, 1) self.land['Y'] = round(Y, 1) self.land['Z'] = round(Z, 1)
def calculate_pattern(self): if ('S' not in self.part): self.part['S'] = self.part['E'] - self.part['L'] - self.part['L'] if ('E' not in self.part): self.part['E'] = self.part['S'] + self.part['L'] + self.part['L'] E = self.part['E'] S = self.part['S'] b = self.part['b'] J_T = TolLen(self.design['J_T'], 0, 1) J_H = TolLen(self.design['J_H'], 0, 1) J_S = TolLen(self.design['J_S'], 0, 1) CE = self.design['CE'] F = self.process['F'] P = self.process['P'] # Q = E + 2*JT + F + P # Zmax = Qmax + Qtol - Etol Q = E + J_T + J_T + F + P Z1 = Q.max + Q.tol - E.tol # Q = S - 2*JH + F + P # Gmin = Qmin - Qtol + Stol Q = S - J_H - J_H + F + P G1 = Q.min - Q.tol + S.tol # Q = b + 2*JS + F + P # Xmax = Qmax + Qtol - btol Q = b + J_S + J_S + F + P X = Q.max + Q.tol - b.tol Y = (Z1 - G1) / 2 # TODO, reuse in both x, y-dimensions? C1 = G1 + Y # Next dimension Q = E + J_T + J_T + F + P Z2 = Q.max + Q.tol - E.tol Q = S - J_H - J_H + F + P G2 = Q.min - Q.tol + S.tol C2 = G2 + Y # TODO: trimming # TODO: rounding (eg 1.05, 1.10 1.15 (c=0.05) x = round(x0/c)*c self.land['C1'] = round(C1, 1) self.land['C2'] = round(C2, 1) self.land['G1'] = round(G1, 1) self.land['G2'] = round(G2, 1) self.land['X'] = round(X, 1) self.land['Y'] = round(Y, 1) self.land['Z1'] = round(Z1, 1) self.land['Z2'] = round(Z2, 1)