""" Generate the following SO packages: - SOIC (both EIAJ and JEDEC) - TSSOP (JEDEC MO-153) - SSOP (JEDEC MO-150 and MO-152) - TSOP (JEDEC MS-024) """ import sys from os import path from uuid import uuid4 from typing import Dict, Iterable, List, Optional from common import format_ipc_dimension as fd from common import init_cache, now, save_cache from entities.common import ( Align, Angle, Author, Category, Circle, Created, Deprecated, Description, Diameter, Fill, GeneratedBy, GrabArea, Height, Keywords, Layer, Name, Polygon, Position, Position3D, Rotation, Rotation3D, Value, Version, Vertex, Width, generate_courtyard ) from entities.package import ( AssemblyType, AutoRotate, ComponentSide, CopperClearance, Footprint, Footprint3DModel, FootprintPad, LetterSpacing, LineSpacing, Mirror, Package, Package3DModel, PackagePad, PackagePadUuid, PadFunction, Shape, ShapeRadius, Size, SolderPasteConfig, StopMaskConfig, StrokeText, StrokeWidth ) generator = 'librepcb-parts-generator (generate_so.py)' line_width = 0.25 pkg_text_height = 1.0 silkscreen_offset = 0.150 # 150 µm pin_package_offset = 0.762 # Distance between pad center and the package body # Based on IPC 7351B (Table 3-2) DENSITY_LEVELS = { # For pitch 0.625 mm and up 'A': {'toe': 0.55, 'heel': 0.45, 'side': 0.05, 'courtyard': 0.50}, 'B': {'toe': 0.35, 'heel': 0.35, 'side': 0.03, 'courtyard': 0.25}, 'C': {'toe': 0.15, 'heel': 0.25, 'side': 0.01, 'courtyard': 0.10}, } # Based on IPC 7351B (Table 3-3) DENSITY_LEVELS_SMALL = { # For pitch below 0.625 mm 'A': {'toe': 0.55, 'heel': 0.45, 'side': 0.01, 'courtyard': 0.50}, 'B': {'toe': 0.35, 'heel': 0.35, 'side': -0.02, 'courtyard': 0.25}, 'C': {'toe': 0.15, 'heel': 0.25, 'side': -0.04, 'courtyard': 0.10}, } # Initialize UUID cache uuid_cache_file = 'uuid_cache_so.csv' uuid_cache = init_cache(uuid_cache_file) def uuid(category: str, full_name: str, identifier: str) -> str: """ Return a uuid for the specified pin. Params: category: For example 'cmp' or 'pkg'. full_name: For example "SOIC127P762X120-16". identifier: For example 'pad-1' or 'pin-13'. """ key = '{}-{}-{}'.format(category, full_name, identifier).lower().replace(' ', '~') if key not in uuid_cache: uuid_cache[key] = str(uuid4()) return uuid_cache[key] def get_by_density(pitch: float, level: str, key: str) -> float: if pitch >= 0.625: table = DENSITY_LEVELS else: table = DENSITY_LEVELS_SMALL return table[level][key] def get_y(pin_number: int, pin_count: int, spacing: float, grid_align: bool) -> float: """ Return the y coordinate of the specified pin. Keep the pins grid aligned, if desired. The pin number is 1 index based. Pin 1 is at the top. The middle pin will be at or near 0. Coordinates are rounded to the next 0.001 mm. """ if grid_align: mid = float((pin_count + 1) // 2) else: mid = (pin_count + 1) / 2 y = -round(pin_number * spacing - mid * spacing, 3) if y == -0.0: # Returns true for 0.0 too, but that doesn't matter return 0.0 return y class SoConfig: def __init__( self, pin_count: int, pitch: float, body_length: float, body_width: float, total_width: float, height: float, variation: Optional[str] = None, ): self.pin_count = pin_count self.pitch = pitch self.body_length = body_length self.body_width = body_width self.total_width = total_width self.height = height self.variation = variation def generate_pkg( library: str, author: str, name: str, description: str, configs: Iterable[SoConfig], lead_width_lookup: Dict[float, float], lead_contact_length: float, generate_3d_models: bool, pkgcat: str, keywords: str, version: str, create_date: Optional[str], ) -> None: category = 'pkg' for config in configs: pitch = config.pitch pin_count = config.pin_count height = config.height body_width = config.body_width total_width = config.total_width body_length = config.body_length lead_width = lead_width_lookup[pitch] lead_length = (total_width - body_width) / 2 full_name = name.format( height=fd(height), pitch=fd(pitch), pin_count=pin_count, body_length=fd(body_length), lead_span=fd(total_width), lead_width=fd(lead_width), lead_length=fd(lead_length), ) full_description = description.format( height=height, pin_count=pin_count, pitch=pitch, body_length=body_length, body_width=body_width, lead_span=total_width, lead_width=lead_width, lead_length=lead_length, variation=config.variation, ) + "\n\nGenerated with {}".format(generator) def _uuid(identifier: str) -> str: return uuid(category, full_name, identifier) uuid_pkg = _uuid('pkg') uuid_pads = [_uuid('pad-{}'.format(p)) for p in range(1, pin_count + 1)] uuid_leads1 = [_uuid('lead-contact-{}'.format(p)) for p in range(1, pin_count + 1)] uuid_leads2 = [_uuid('lead-proj-{}'.format(p)) for p in range(1, pin_count + 1)] print('Generating {}: {}'.format(full_name, uuid_pkg)) package = Package( uuid=uuid_pkg, name=Name(full_name), description=Description(full_description), keywords=Keywords("soic{},so{},{}".format(pin_count, pin_count, keywords)), author=Author(author), version=Version(version), created=Created(create_date or now()), deprecated=Deprecated(False), generated_by=GeneratedBy(''), categories=[Category(pkgcat)], assembly_type=AssemblyType.SMT, ) for p in range(1, pin_count + 1): package.add_pad(PackagePad(uuid_pads[p - 1], Name(str(p)))) def add_footprint_variant( key: str, name: str, density_level: str, ) -> None: uuid_footprint = _uuid('footprint-{}'.format(key)) uuid_silkscreen_top = _uuid('polygon-silkscreen-{}'.format(key)) uuid_silkscreen_bot = _uuid('polygon-silkscreen2-{}'.format(key)) uuid_body = _uuid('polygon-body-{}'.format(key)) uuid_pin1_dot = _uuid('pin1-dot-{}'.format(key)) uuid_outline = _uuid('polygon-outline-{}'.format(key)) uuid_courtyard = _uuid('polygon-courtyard-{}'.format(key)) uuid_text_name = _uuid('text-name-{}'.format(key)) uuid_text_value = _uuid('text-value-{}'.format(key)) # Max boundaries (pads or body) max_x = 0.0 max_y = 0.0 # Max boundaries (copper only) max_y_copper = 0.0 footprint = Footprint( uuid=uuid_footprint, name=Name(name), description=Description(''), position_3d=Position3D.zero(), rotation_3d=Rotation3D.zero(), ) package.add_footprint(footprint) # Pad excess according to IPC density levels pad_heel = get_by_density(pitch, density_level, 'heel') pad_toe = get_by_density(pitch, density_level, 'toe') pad_side = get_by_density(pitch, density_level, 'side') # Pads pad_width = lead_width + pad_side pad_length = lead_contact_length + pad_heel + pad_toe pad_x_offset = total_width / 2 - lead_contact_length / 2 - pad_heel / 2 + pad_toe / 2 for p in range(1, pin_count + 1): mid = pin_count // 2 if p <= mid: y = get_y(p, pin_count // 2, pitch, False) pxo = -pad_x_offset else: y = -get_y(p - mid, pin_count // 2, pitch, False) pxo = pad_x_offset pad_uuid = uuid_pads[p - 1] footprint.add_pad(FootprintPad( uuid=pad_uuid, side=ComponentSide.TOP, shape=Shape.ROUNDED_RECT, position=Position(pxo, y), rotation=Rotation(0), size=Size(pad_length, pad_width), radius=ShapeRadius(0.5), stop_mask=StopMaskConfig.AUTO, solder_paste=SolderPasteConfig.AUTO, copper_clearance=CopperClearance(0.0), function=PadFunction.STANDARD_PAD, package_pad=PackagePadUuid(pad_uuid), holes=[], )) max_y_copper = max(max_y_copper, y + pad_width / 2) max_x = max(max_x, total_width / 2 + pad_toe) # Documentation: Leads lead_contact_x_offset = total_width / 2 - lead_contact_length # this is the inner side of the contact area for p in range(1, pin_count + 1): mid = pin_count // 2 if p <= mid: # left side y = get_y(p, pin_count // 2, pitch, False) lcxo_max = -lead_contact_x_offset - lead_contact_length lcxo_min = -lead_contact_x_offset body_side = -body_width / 2 else: # right side y = -get_y(p - mid, pin_count // 2, pitch, False) lcxo_min = lead_contact_x_offset lcxo_max = lead_contact_x_offset + lead_contact_length body_side = body_width / 2 y_max = y - lead_width / 2 y_min = y + lead_width / 2 lead_uuid_ctct = uuid_leads1[p - 1] # Contact area lead_uuid_proj = uuid_leads2[p - 1] # Vertical projection # Contact area footprint.add_polygon(Polygon( uuid=lead_uuid_ctct, layer=Layer('top_documentation'), width=Width(0), fill=Fill(True), grab_area=GrabArea(False), vertices=[ Vertex(Position(lcxo_min, y_max), Angle(0)), Vertex(Position(lcxo_max, y_max), Angle(0)), Vertex(Position(lcxo_max, y_min), Angle(0)), Vertex(Position(lcxo_min, y_min), Angle(0)), Vertex(Position(lcxo_min, y_max), Angle(0)), ], )) # Vertical projection, between contact area and body footprint.add_polygon(Polygon( uuid=lead_uuid_proj, layer=Layer('top_documentation'), width=Width(0), fill=Fill(True), grab_area=GrabArea(False), vertices=[ Vertex(Position(body_side, y_max), Angle(0)), Vertex(Position(lcxo_min, y_max), Angle(0)), Vertex(Position(lcxo_min, y_min), Angle(0)), Vertex(Position(body_side, y_min), Angle(0)), Vertex(Position(body_side, y_max), Angle(0)), ], )) # Silkscreen (fully outside body) # Ensure minimum clearance between copper and silkscreen y_offset = max(silkscreen_offset - (body_length / 2 - max_y_copper), 0) y_max = body_length / 2 + line_width / 2 + y_offset y_min = -body_length / 2 - line_width / 2 - y_offset short_x_offset = body_width / 2 - line_width / 2 long_x_offset = total_width / 2 - line_width / 2 + pad_toe # Pin1 marking footprint.add_polygon(Polygon( uuid=uuid_silkscreen_top, layer=Layer('top_legend'), width=Width(line_width), fill=Fill(False), grab_area=GrabArea(False), vertices=[ Vertex(Position(-long_x_offset, y_max), Angle(0)), Vertex(Position(short_x_offset, y_max), Angle(0)), ], )) footprint.add_polygon(Polygon( uuid=uuid_silkscreen_bot, layer=Layer('top_legend'), width=Width(line_width), fill=Fill(False), grab_area=GrabArea(False), vertices=[ Vertex(Position(-short_x_offset, y_min), Angle(0)), Vertex(Position(short_x_offset, y_min), Angle(0)), ], )) # Documentation body body_x_offset = body_width / 2 - line_width / 2 y_max = body_length / 2 - line_width / 2 y_min = -body_length / 2 + line_width / 2 oxo = body_x_offset # Used for shorter code lines below :) footprint.add_polygon(Polygon( uuid=uuid_body, layer=Layer('top_documentation'), width=Width(line_width), fill=Fill(False), grab_area=GrabArea(True), vertices=[ Vertex(Position(-oxo, y_max), Angle(0)), Vertex(Position(oxo, y_max), Angle(0)), Vertex(Position(oxo, y_min), Angle(0)), Vertex(Position(-oxo, y_min), Angle(0)), Vertex(Position(-oxo, y_max), Angle(0)), ], )) max_y = max(max_y, body_length / 2) # Body contour # Documentation: Pin 1 dot pin1_dot_diameter = 0.5 pin1_dot_offset = 1.0 dx = body_width / 2 - pin1_dot_offset dy = config.body_length / 2 - pin1_dot_offset pin1_dot = Circle( uuid_pin1_dot, Layer('top_documentation'), Width(0.0), Fill(True), GrabArea(False), Diameter(pin1_dot_diameter), Position(-dx, dy), ) footprint.add_circle(pin1_dot) # Package Outline dx = config.total_width / 2 dy = config.body_length / 2 footprint.add_polygon(Polygon( uuid=uuid_outline, layer=Layer('top_package_outlines'), width=Width(0), fill=Fill(False), grab_area=GrabArea(False), vertices=[ Vertex(Position(-dx, dy), Angle(0)), # NW Vertex(Position(dx, dy), Angle(0)), # NE Vertex(Position(dx, -dy), Angle(0)), # SE Vertex(Position(-dx, -dy), Angle(0)), # SW ], )) # Courtyard courtyard_excess = get_by_density(pitch, density_level, 'courtyard') footprint.add_polygon(generate_courtyard( uuid=uuid_courtyard, max_x=max_x, max_y=max_y, excess_x=courtyard_excess, excess_y=courtyard_excess, )) # Labels y_max = body_length / 2 + 1.27 y_min = -body_length / 2 - 1.27 footprint.add_text(StrokeText( uuid=uuid_text_name, layer=Layer('top_names'), height=Height(pkg_text_height), stroke_width=StrokeWidth(0.2), letter_spacing=LetterSpacing.AUTO, line_spacing=LineSpacing.AUTO, align=Align('center bottom'), position=Position(0.0, y_max), rotation=Rotation(0.0), auto_rotate=AutoRotate(True), mirror=Mirror(False), value=Value('{{NAME}}'), )) footprint.add_text(StrokeText( uuid=uuid_text_value, layer=Layer('top_values'), height=Height(pkg_text_height), stroke_width=StrokeWidth(0.2), letter_spacing=LetterSpacing.AUTO, line_spacing=LineSpacing.AUTO, align=Align('center top'), position=Position(0.0, y_min), rotation=Rotation(0.0), auto_rotate=AutoRotate(True), mirror=Mirror(False), value=Value('{{VALUE}}'), )) add_footprint_variant('density~b', 'Density Level B (median protrusion)', 'B') add_footprint_variant('density~a', 'Density Level A (max protrusion)', 'A') add_footprint_variant('density~c', 'Density Level C (min protrusion)', 'C') # Generate 3D models uuid_3d = uuid('pkg', full_name, '3d') if generate_3d_models: generate_3d(library, full_name, uuid_pkg, uuid_3d, config, lead_width, lead_contact_length) package.add_3d_model(Package3DModel(uuid_3d, Name(full_name))) for footprint in package.footprints: footprint.add_3d_model(Footprint3DModel(uuid_3d)) package.serialize(path.join('out', library, category)) def generate_3d( library: str, full_name: str, uuid_pkg: str, uuid_3d: str, config: SoConfig, lead_width: float, lead_contact_length: float, ) -> None: import cadquery as cq from cadquery_helpers import StepAssembly, StepColor print(f'Generating pkg 3D model "{full_name}": {uuid_3d}') body_standoff = 0.1 body_height = config.height - body_standoff body_chamfer = 0.15 dot_diameter = 0.8 dot_position = 1.0 dot_depth = 0.15 leg_height = 0.17 leg_z_top = body_standoff + (body_height / 2) bend_radius = 0.1 + (leg_height / 2) dot_center = ( -(config.body_width / 2) + dot_position, (config.body_length / 2) - dot_position, body_standoff + body_height - dot_depth ) body = cq.Workplane('XY', origin=(0, 0, body_standoff + (body_height / 2))) \ .box(config.body_width, config.body_length, body_height) \ .edges().chamfer(body_chamfer) \ .workplane(origin=(dot_center[0], dot_center[1]), offset=(body_height / 2) - dot_depth) \ .cylinder(5, dot_diameter / 2, centered=(True, True, False), combine='cut') dot = cq.Workplane('XY', origin=dot_center) \ .cylinder(0.05, dot_diameter / 2, centered=(True, True, False)) leg_path = cq.Workplane("XZ") \ .hLine(lead_contact_length - (leg_height / 2) - bend_radius) \ .ellipseArc(x_radius=bend_radius, y_radius=bend_radius, angle1=270, angle2=360, sense=1) \ .vLine(leg_z_top - leg_height - (2 * bend_radius)) \ .ellipseArc(x_radius=bend_radius, y_radius=bend_radius, angle1=90, angle2=180, sense=-1) \ .hLine(config.total_width - (2 * bend_radius) - (2 * lead_contact_length) + leg_height) \ .ellipseArc(x_radius=bend_radius, y_radius=bend_radius, angle1=0, angle2=90, sense=-1) \ .vLine(-(leg_z_top - leg_height - (2 * bend_radius))) \ .ellipseArc(x_radius=bend_radius, y_radius=bend_radius, angle1=180, angle2=270, sense=1) \ .hLine(lead_contact_length - (leg_height / 2) - bend_radius) leg = cq.Workplane("ZY") \ .rect(leg_height, lead_width) \ .sweep(leg_path) assembly = StepAssembly(full_name) assembly.add_body(body, 'body', StepColor.IC_BODY) assembly.add_body(dot, 'dot', StepColor.IC_PIN1_DOT) y1 = get_y(1, config.pin_count // 2, config.pitch, False) for i in range(0, config.pin_count // 2): assembly.add_body( leg, 'leg-{}'.format(i + 1), StepColor.LEAD_SMT, location=cq.Location(( -config.total_width / 2, y1 - i * config.pitch, leg_height / 2, )) ) # Save without fusing for massively better minification! out_path = path.join('out', library, 'pkg', uuid_pkg, f'{uuid_3d}.step') assembly.save(out_path, fused=False) if __name__ == '__main__': if '--help' in sys.argv or '-h' in sys.argv: print(f'Usage: {sys.argv[0]} [--3d]') print() print('Options:') print(' --3d Generate 3D models using cadquery') sys.exit(1) generate_3d_models = '--3d' in sys.argv if not generate_3d_models: warning = 'Note: Not generating 3D models unless the "--3d" argument is passed in!' print(f'\033[1;33m{warning}\033[0m') # SOIC configs: List[SoConfig] = [] for pin_count in [6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 30, 32]: for height in [1.2, 1.4, 1.7, 2.7]: pitch = 1.27 body_length = (pin_count / 2 - 1) * pitch + 2.0 body_width = 5.22 total_width = 8.42 # effective, not nominal (7.62) configs.append(SoConfig(pin_count, pitch, body_length, body_width, total_width, height)) generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', name='SOIC{pitch}P762X{height}-{pin_count}', description='{pin_count}-pin Small Outline Integrated Circuit (SOIC), ' 'standardized by EIAJ.\n\n' 'Pitch: {pitch:.2f} mm\nNominal width: 7.62mm\nHeight: {height:.2f}mm', configs=configs, lead_width_lookup={1.27: 0.4}, lead_contact_length=0.8, generate_3d_models=generate_3d_models, pkgcat='a074fabf-4912-4c29-bc6b-451bf43c2193', keywords='so,soic,small outline,smd,eiaj', version='0.3', create_date='2018-11-10T20:32:03Z', ) configs = [] for pin_count in [20, 22, 24, 28, 30, 32, 36, 40, 42, 44]: for height in [1.2, 1.4, 1.7, 2.7]: pitch = 1.27 body_length = (pin_count / 2 - 1) * pitch + 2.0 body_width = 12.84 total_width = 16.04 # effective, not nominal (15.42) configs.append(SoConfig(pin_count, pitch, body_length, body_width, total_width, height)) generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', name='SOIC{pitch}P1524X{height}-{pin_count}', description='{pin_count}-pin Small Outline Integrated Circuit (SOIC), ' 'standardized by EIAJ.\n\n' 'Pitch: {pitch:.2f} mm\nNominal width: 15.24mm\nHeight: {height:.2f}mm', configs=configs, lead_width_lookup={1.27: 0.4}, lead_contact_length=0.8, generate_3d_models=generate_3d_models, pkgcat='a074fabf-4912-4c29-bc6b-451bf43c2193', keywords='so,soic,small outline,smd,eiaj', version='0.3', create_date='2018-11-10T20:32:03Z', ) configs = [] for pin_count in [6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 30, 32, 36, 40, 42, 44, 48]: pitch = 1.27 height = 1.75 body_length = (pin_count / 2 - 1) * pitch + 1.6 body_width = 3.9 total_width = 6.0 configs.append(SoConfig(pin_count, pitch, body_length, body_width, total_width, height)) generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', name='SOIC{pitch}P600X{height}-{pin_count}', description='{pin_count}-pin Small Outline Integrated Circuit (SOIC), ' 'standardized by JEDEC (MS-012G).\n\n' 'Pitch: {pitch:.2f} mm\nNominal width: 6.00mm\nHeight: {height:.2f}mm', configs=configs, lead_width_lookup={1.27: 0.45}, lead_contact_length=0.835, generate_3d_models=generate_3d_models, pkgcat='a074fabf-4912-4c29-bc6b-451bf43c2193', keywords='so,soic,small outline,smd,jedec', version='0.3', create_date='2018-11-10T20:32:03Z', ) configs = [] for pin_count in [14, 16, 18, 20, 24, 28]: pitch = 1.27 height = 2.65 body_length = (pin_count / 2 - 1) * pitch + 1.6 body_width = 7.5 total_width = 10.3 configs.append(SoConfig(pin_count, pitch, body_length, body_width, total_width, height)) generate_pkg( library='LibrePCB_Base.lplib', author='U. Bruhin', name='SOIC{pitch}P1030X{height}-{pin_count}', description='{pin_count}-pin Small Outline Integrated Circuit (SOIC), ' 'standardized by JEDEC (MS-013F).\n\n' 'Pitch: {pitch:.2f} mm\nNominal width: 10.30mm\nHeight: {height:.2f}mm', configs=configs, lead_width_lookup={1.27: 0.45}, lead_contact_length=0.835, generate_3d_models=generate_3d_models, pkgcat='a074fabf-4912-4c29-bc6b-451bf43c2193', keywords='so,soic,small outline,smd,jedec,ms-013f', version='0.2', create_date='2020-09-15T20:46:13Z', ) # TSSOP generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', # Name according to IPC7351C name='TSSOP{pin_count}P{pitch}_{body_length}X{lead_span}X{height}L{lead_length}X{lead_width}', description='{pin_count}-pin Thin-Shrink Small Outline Package (TSSOP), ' 'standardized by JEDEC (MO-153), variation {variation}.\n\n' 'Pitch: {pitch:.2f} mm\nBody length: {body_length:.2f} mm\n' 'Body width: {body_width:.2f} mm\nLead span: {lead_span:.2f} mm\n' 'Height: {height:.2f} mm\n' 'Lead length: {lead_length:.2f} mm\nLead width: {lead_width:.2f} mm', configs=[ # pin count, pitch, body length, body width, total width, height # Symbols based on JEDEC MO-153: # N e D E1 E A # 4.40mm body width # 0.65mm pitch SoConfig( 8, 0.65, 3.0, 4.4, 6.4, 1.2, 'AA'), SoConfig(14, 0.65, 5.0, 4.4, 6.4, 1.2, 'AB-1'), SoConfig(16, 0.65, 5.0, 4.4, 6.4, 1.2, 'AB'), SoConfig(20, 0.65, 6.5, 4.4, 6.4, 1.2, 'AC'), SoConfig(24, 0.65, 7.8, 4.4, 6.4, 1.2, 'AD'), SoConfig(28, 0.65, 9.7, 4.4, 6.4, 1.2, 'AE'), # 0.5mm pitch SoConfig(20, 0.50, 5.0, 4.4, 6.4, 1.2, 'BA'), SoConfig(24, 0.50, 6.5, 4.4, 6.4, 1.2, 'BB'), SoConfig(28, 0.50, 7.8, 4.4, 6.4, 1.2, 'BC'), SoConfig(30, 0.50, 7.8, 4.4, 6.4, 1.2, 'BC-1'), SoConfig(36, 0.50, 9.7, 4.4, 6.4, 1.2, 'BD'), SoConfig(38, 0.50, 9.7, 4.4, 6.4, 1.2, 'BD-1'), SoConfig(44, 0.50, 11.0, 4.4, 6.4, 1.2, 'BE'), SoConfig(50, 0.50, 12.5, 4.4, 6.4, 1.2, 'BF'), # 0.4mm pitch SoConfig(24, 0.40, 5.0, 4.4, 6.4, 1.2, 'CA'), SoConfig(32, 0.40, 6.5, 4.4, 6.4, 1.2, 'CB'), SoConfig(36, 0.40, 7.8, 4.4, 6.4, 1.2, 'CC'), SoConfig(48, 0.40, 9.7, 4.4, 6.4, 1.2, 'CD'), # 6.10mm body width # 0.65mm pitch SoConfig(24, 0.65, 7.8, 6.1, 8.1, 1.2, 'DA'), SoConfig(28, 0.65, 9.7, 6.1, 8.1, 1.2, 'DB'), SoConfig(30, 0.65, 9.7, 6.1, 8.1, 1.2, 'DB-1'), SoConfig(32, 0.65, 11.0, 6.1, 8.1, 1.2, 'DC'), SoConfig(36, 0.65, 12.5, 6.1, 8.1, 1.2, 'DD'), SoConfig(38, 0.65, 12.5, 6.1, 8.1, 1.2, 'DD-1'), SoConfig(40, 0.65, 14.0, 6.1, 8.1, 1.2, 'DE'), # 0.5mm pitch SoConfig(28, 0.50, 7.8, 6.1, 8.1, 1.2, 'EA'), SoConfig(36, 0.50, 9.7, 6.1, 8.1, 1.2, 'EB'), SoConfig(40, 0.50, 11.0, 6.1, 8.1, 1.2, 'EC'), SoConfig(44, 0.50, 11.0, 6.1, 8.1, 1.2, 'EC-1'), SoConfig(48, 0.50, 12.5, 6.1, 8.1, 1.2, 'ED'), SoConfig(56, 0.50, 14.0, 6.1, 8.1, 1.2, 'EE'), SoConfig(64, 0.50, 17.0, 6.1, 8.1, 1.2, 'EF'), # 0.4mm pitch SoConfig(36, 0.40, 7.8, 6.1, 8.1, 1.2, 'FA'), SoConfig(48, 0.40, 9.7, 6.1, 8.1, 1.2, 'FB'), SoConfig(52, 0.40, 11.0, 6.1, 8.1, 1.2, 'FC'), SoConfig(56, 0.40, 12.5, 6.1, 8.1, 1.2, 'FD'), SoConfig(64, 0.40, 14.0, 6.1, 8.1, 1.2, 'FE'), SoConfig(80, 0.40, 17.0, 6.1, 8.1, 1.2, 'FF'), # 8.00mm body width # 0.65mm pitch SoConfig(28, 0.65, 9.7, 8.0, 10.0, 1.2, 'GA'), SoConfig(32, 0.65, 11.0, 8.0, 10.0, 1.2, 'GB'), SoConfig(36, 0.65, 12.5, 8.0, 10.0, 1.2, 'GC'), SoConfig(40, 0.65, 14.0, 8.0, 10.0, 1.2, 'GD'), # 0.5mm pitch SoConfig(36, 0.50, 9.7, 8.0, 10.0, 1.2, 'HA'), SoConfig(40, 0.50, 11.0, 8.0, 10.0, 1.2, 'HB'), SoConfig(48, 0.50, 12.5, 8.0, 10.0, 1.2, 'HC'), SoConfig(56, 0.50, 14.0, 8.0, 10.0, 1.2, 'HD'), # 0.4mm pitch SoConfig(48, 0.40, 9.7, 8.0, 10.0, 1.2, 'JA'), SoConfig(52, 0.40, 11.0, 8.0, 10.0, 1.2, 'JB'), SoConfig(56, 0.40, 12.5, 8.0, 10.0, 1.2, 'JC'), SoConfig(60, 0.40, 12.5, 8.0, 10.0, 1.2, 'JC-1'), SoConfig(64, 0.40, 14.0, 8.0, 10.0, 1.2, 'JD'), SoConfig(68, 0.40, 14.0, 8.0, 10.0, 1.2, 'JD-1'), ], lead_width_lookup={ 0.65: 0.3, 0.5: 0.27, 0.4: 0.23, }, lead_contact_length=0.6, generate_3d_models=generate_3d_models, pkgcat='241d9d5d-8f74-4740-8901-3cf51cf50091', keywords='so,sop,tssop,small outline package,smd', version='0.3', create_date='2019-06-16T12:46:54Z', ) # SSOP generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', # Name according to IPC7351C name='SSOP{pin_count}P{pitch}_{body_length}X{lead_span}X{height}L{lead_length}X{lead_width}', description='{pin_count}-pin Plastic Shrink Small Outline Package (SSOP), ' 'standardized by JEDEC (MO-152), variation {variation}.\n\n' 'Pitch: {pitch:.2f} mm\nBody length: {body_length:.2f} mm\n' 'Body width: {body_width:.2f} mm\nLead span: {lead_span:.2f} mm\n' 'Height: {height:.2f} mm\n' 'Lead length: {lead_length:.2f} mm\nLead width: {lead_width:.2f} mm', configs=[ # pin count, pitch, body length, body width, total width, height # Symbols based on JEDEC MO-152: # N e D E1 E A # 4.40mm body width # 0.65mm pitch SoConfig( 8, 0.65, 3.0, 4.4, 6.4, 2.0, 'AA'), SoConfig(14, 0.65, 5.0, 4.4, 6.4, 2.0, 'AB-1'), SoConfig(16, 0.65, 5.0, 4.4, 6.4, 2.0, 'AB'), SoConfig(20, 0.65, 6.5, 4.4, 6.4, 2.0, 'AC'), SoConfig(24, 0.65, 7.8, 4.4, 6.4, 2.0, 'AD'), SoConfig(28, 0.65, 9.7, 4.4, 6.4, 2.0, 'AE'), # 0.5mm pitch SoConfig(20, 0.50, 5.0, 4.4, 6.4, 2.0, 'BA'), SoConfig(24, 0.50, 6.5, 4.4, 6.4, 2.0, 'BB'), SoConfig(28, 0.50, 7.8, 4.4, 6.4, 2.0, 'BC'), SoConfig(36, 0.50, 9.7, 4.4, 6.4, 2.0, 'BD'), # 0.4mm pitch SoConfig(24, 0.40, 5.0, 4.4, 6.4, 2.0, 'CA'), SoConfig(32, 0.40, 6.5, 4.4, 6.4, 2.0, 'CB'), SoConfig(36, 0.40, 7.8, 4.4, 6.4, 2.0, 'CC'), SoConfig(48, 0.40, 9.7, 4.4, 6.4, 2.0, 'CD'), # 6.10mm body width # 0.65mm pitch SoConfig(24, 0.65, 7.8, 6.1, 8.1, 2.0, 'DA'), SoConfig(28, 0.65, 9.7, 6.1, 8.1, 2.0, 'DB'), SoConfig(30, 0.65, 9.7, 6.1, 8.1, 2.0, 'DB-1'), SoConfig(32, 0.65, 11.0, 6.1, 8.1, 2.0, 'DC'), SoConfig(36, 0.65, 12.5, 6.1, 8.1, 2.0, 'DD'), SoConfig(40, 0.65, 14.0, 6.1, 8.1, 2.0, 'DE'), # 0.5mm pitch SoConfig(28, 0.50, 7.8, 6.1, 8.1, 2.0, 'EA'), SoConfig(36, 0.50, 9.7, 6.1, 8.1, 2.0, 'EB'), SoConfig(40, 0.50, 11.0, 6.1, 8.1, 2.0, 'EC'), SoConfig(44, 0.50, 11.0, 6.1, 8.1, 2.0, 'EC-1'), SoConfig(48, 0.50, 12.5, 6.1, 8.1, 2.0, 'ED'), SoConfig(56, 0.50, 14.0, 6.1, 8.1, 2.0, 'EE'), SoConfig(64, 0.50, 17.0, 6.1, 8.1, 2.0, 'EF'), # 0.4mm pitch SoConfig(36, 0.40, 7.8, 6.1, 8.1, 2.0, 'FA'), SoConfig(48, 0.40, 9.7, 6.1, 8.1, 2.0, 'FB'), SoConfig(52, 0.40, 11.0, 6.1, 8.1, 2.0, 'FC'), SoConfig(56, 0.40, 12.5, 6.1, 8.1, 2.0, 'FD'), SoConfig(64, 0.40, 14.0, 6.1, 8.1, 2.0, 'FE'), SoConfig(80, 0.40, 17.0, 6.1, 8.1, 2.0, 'FF'), # 8.00mm body width # 0.65mm pitch SoConfig(28, 0.65, 9.7, 8.0, 10.0, 2.0, 'GA'), SoConfig(32, 0.65, 11.0, 8.0, 10.0, 2.0, 'GB'), SoConfig(36, 0.65, 12.5, 8.0, 10.0, 2.0, 'GC'), SoConfig(40, 0.65, 14.0, 8.0, 10.0, 2.0, 'GD'), # 0.5mm pitch SoConfig(36, 0.50, 9.7, 8.0, 10.0, 2.0, 'HA'), SoConfig(40, 0.50, 11.0, 8.0, 10.0, 2.0, 'HB'), SoConfig(48, 0.50, 12.5, 8.0, 10.0, 2.0, 'HC'), SoConfig(56, 0.50, 14.0, 8.0, 10.0, 2.0, 'HD'), # 0.4mm pitch SoConfig(48, 0.40, 9.7, 8.0, 10.0, 2.0, 'JA'), SoConfig(52, 0.40, 11.0, 8.0, 10.0, 2.0, 'JB'), SoConfig(56, 0.40, 12.5, 8.0, 10.0, 2.0, 'JC'), SoConfig(60, 0.40, 12.5, 8.0, 10.0, 2.0, 'JC-1'), SoConfig(64, 0.40, 14.0, 8.0, 10.0, 2.0, 'JD'), SoConfig(68, 0.40, 14.0, 8.0, 10.0, 2.0, 'JD-1'), ], lead_width_lookup={ 0.65: 0.30, 0.50: 0.27, 0.40: 0.23, }, lead_contact_length=0.6, generate_3d_models=generate_3d_models, pkgcat='3627bf02-2e6e-4d68-9ada-743fa69a4f8c', keywords='so,sop,ssop,small outline package,smd,jedec,mo-152', version='0.2', create_date='2019-07-21T12:55:20Z', ) generate_pkg( library='LibrePCB_Base.lplib', author='Danilo B.', # Name according to IPC7351C name='SSOP{pin_count}P{pitch}_{body_length}X{lead_span}X{height}L{lead_length}X{lead_width}', description='{pin_count}-pin Plastic Shrink Small Outline Package (SSOP), ' 'standardized by JEDEC (MO-150), variation {variation}.\n\n' 'Pitch: {pitch:.2f} mm\nBody length: {body_length:.2f} mm\n' 'Body width: {body_width:.2f} mm\nLead span: {lead_span:.2f} mm\n' 'Height: {height:.2f} mm\n' 'Lead length: {lead_length:.2f} mm\nLead width: {lead_width:.2f} mm', configs=[ # pin count, pitch, body length, body width, total width, height # Symbols based on JEDEC MO-150: # N e D E1 E A SoConfig( 8, 0.65, 3.0, 5.3, 7.8, 2.0, 'AA'), SoConfig(14, 0.65, 6.2, 5.3, 7.8, 2.0, 'AB'), SoConfig(16, 0.65, 6.2, 5.3, 7.8, 2.0, 'AC'), SoConfig(18, 0.65, 7.2, 5.3, 7.8, 2.0, 'AD'), SoConfig(20, 0.65, 7.2, 5.3, 7.8, 2.0, 'AE'), SoConfig(22, 0.65, 8.2, 5.3, 7.8, 2.0, 'AF'), SoConfig(24, 0.65, 8.2, 5.3, 7.8, 2.0, 'AG'), SoConfig(28, 0.65, 10.2, 5.3, 7.8, 2.0, 'AH'), SoConfig(30, 0.65, 10.2, 5.3, 7.8, 2.0, 'AJ'), SoConfig(38, 0.65, 12.6, 5.3, 7.8, 2.0, 'AK'), ], lead_width_lookup={ 0.65: 0.38, }, lead_contact_length=0.75, generate_3d_models=generate_3d_models, pkgcat='3627bf02-2e6e-4d68-9ada-743fa69a4f8c', keywords='so,sop,ssop,small outline package,smd,jedec,mo-150', version='0.2', create_date='2019-07-21T12:55:20Z', ) # TSOP generate_pkg( library='LibrePCB_Base.lplib', author='Tubbles', # Name extrapolated from IPC7351C name='TSOP{pin_count}P{pitch}_{body_length}X{lead_span}X{height}L{lead_length}X{lead_width}', description='{pin_count}-pin Thin Small Outline Package (TSOP), ' 'standardized by JEDEC (MS-024), Type II (pins on longer side), variation {variation}.\n\n' 'Pitch: {pitch:.2f} mm\nBody length: {body_length:.2f} mm\n' 'Body width: {body_width:.2f} mm\nLead span: {lead_span:.2f} mm\n' 'Height: {height:.2f} mm\n' 'Lead length: {lead_length:.2f} mm\nLead width: {lead_width:.2f} mm', configs=[ # pin count, pitch, body length, body width, total width, height # Symbols based on JEDEC MS-024: # N e D E1 E A SoConfig(28, 1.27, 18.41, 10.16, 11.76, 1.2, 'AA'), SoConfig(32, 1.27, 20.95, 10.16, 11.76, 1.2, 'BA'), SoConfig(50, 0.80, 20.95, 10.16, 11.76, 1.2, 'BC'), SoConfig(80, 0.50, 20.95, 10.16, 11.76, 1.2, 'BD'), SoConfig(36, 1.27, 23.49, 10.16, 11.76, 1.2, 'CA'), SoConfig(70, 0.65, 23.49, 10.16, 11.76, 1.2, 'CB'), SoConfig(40, 1.27, 26.03, 10.16, 11.76, 1.2, 'DA'), SoConfig(70, 0.80, 28.57, 10.16, 11.76, 1.2, 'EA'), SoConfig(54, 0.80, 22.22, 10.16, 11.76, 1.2, 'FA'), SoConfig(86, 0.50, 22.22, 10.16, 11.76, 1.2, 'FB'), SoConfig(66, 0.65, 22.22, 10.16, 11.76, 1.2, 'FC'), SoConfig(54, 0.40, 11.20, 10.16, 11.76, 1.2, 'GA'), ], lead_width_lookup={ 0.40: 0.18, 0.50: 0.22, 0.65: 0.30, 0.80: 0.375, 1.27: 0.41, }, lead_contact_length=0.5, generate_3d_models=generate_3d_models, pkgcat='7993abb0-fb0a-4157-8f83-1db890755836', keywords='so,sop,tsop,small outline package,smd', version='0.2', create_date='2020-12-26T16:14:30Z', ) save_cache(uuid_cache_file, uuid_cache)