def generate_dev( dirpath: str, diameter: float, height: float, pitch: float, lead_width: float, author: str, version: str, create_date: Optional[str], ) -> None: name = 'Capacitor Radial ⌀{}x{}/{}mm'.format(diameter, height, pitch) variant = get_variant(diameter, height, pitch, lead_width) def _uuid(identifier: str) -> str: return uuid('dev', variant, identifier) device = Device( uuid=_uuid('dev'), name=Name(name), description=Description( 'Generic polarized radial electrolytic capacitor.\\n\\n' + 'Diameter: {} mm\\n'.format(diameter) + 'Height: {} mm\\n'.format(height) + 'Lead Spacing: {} mm\\n'.format(pitch) + 'Max. Lead Diameter: {} mm\\n\\n'.format(lead_width) + 'Generated with {}'.format(generator)), keywords=Keywords( 'electrolytic,capacitor,polarized,radial,c,cap,cpol'), author=Author(author), version=Version(version), created=Created(create_date or now()), deprecated=Deprecated(False), category=Category('c011cc6b-b762-498e-8494-d1994f3043cf'), component_uuid=ComponentUUID('c54375c5-7149-4ded-95c5-7462f7301ee7'), package_uuid=PackageUUID(uuid('pkg', variant, 'pkg')), ) device.add_pad( ComponentPad( uuid=uuid('pkg', variant, 'pad-plus'), signal=SignalUUID('e010ecbb-6210-4da3-9270-ebd58656dbf0'), )) device.add_pad( ComponentPad( uuid=uuid('pkg', variant, 'pad-minus'), signal=SignalUUID('af3ffca8-0085-4edb-a775-fcb759f63411'), )) # write files pkg_dir_path = path.join(dirpath, device.uuid) if not (path.exists(pkg_dir_path) and path.isdir(pkg_dir_path)): makedirs(pkg_dir_path) with open(path.join(pkg_dir_path, '.librepcb-dev'), 'w') as f: f.write('0.1\n') with open(path.join(pkg_dir_path, 'device.lp'), 'w') as f: f.write(str(device)) f.write('\n') print('Wrote device {}'.format(name))
def test_component_pad() -> None: component_pad = ComponentPad( '67a7b034-b30b-4644-b8d3-d7a99606efdc', SignalUUID('9bccea5e-e23f-4b88-9de1-4be00dc0c12a')) assert str( component_pad ) == '(pad 67a7b034-b30b-4644-b8d3-d7a99606efdc (signal 9bccea5e-e23f-4b88-9de1-4be00dc0c12a))'
def test_component() -> None: component = Component( '00c36da8-e22b-43a1-9a87-c3a67e863f49', Name('Generic Connector 1x27'), Description(r'A 1x27 soldered wire connector.\n\nNext line'), Keywords('connector, 1x27'), Author('Test R.'), Version('0.2'), Created('2018-10-17T19:13:41Z'), Deprecated(False), Category('d0618c29-0436-42da-a388-fdadf7b23892'), SchematicOnly(False), DefaultValue(''), Prefix('J')) component.add_signal( Signal('f46a4643-fc68-4593-a889-3d987bfe3544', Name('1'), Role.PASSIVE, Required(False), Negated(False), Clock(False), ForcedNet(''))) gate = Gate('c1e4b542-a1b1-44d5-bec3-070776143a29', SymbolUUID('8f1a97f2-4cdf-43da-b38d-b3787c47b5ad'), Position(0.0, 0.0), Rotation(0.0), Required(True), Suffix('')) gate.add_pin_signal_map( PinSignalMap('0189aafc-f88a-4e65-8fb4-09a047a3e334', SignalUUID('46f7e0e2-74a6-442b-9a5c-1bd4ea3da59c'), TextDesignator.SYMBOL_PIN_NAME)) variant = Variant('abeeeed0-6e9a-4fdc-bc2b-e2c5b06bbe3a', Norm.EMPTY, Name('default'), Description(''), gate) component.add_variant(variant) assert str(component ) == """(librepcb_component 00c36da8-e22b-43a1-9a87-c3a67e863f49
def test_component_gate() -> None: gate = Gate('c1e4b542-a1b1-44d5-bec3-070776143a29', SymbolUUID('8f1a97f2-4cdf-43da-b38d-b3787c47b5ad'), Position(0.0, 0.0), Rotation(0.0), Required(True), Suffix('')) gate.add_pin_signal_map( PinSignalMap('0189aafc-f88a-4e65-8fb4-09a047a3e334', SignalUUID('46f7e0e2-74a6-442b-9a5c-1bd4ea3da59c'), TextDesignator.SYMBOL_PIN_NAME)) assert str(gate) == """(gate c1e4b542-a1b1-44d5-bec3-070776143a29
def test_component_pin_signal_map() -> None: pin_signal_map = PinSignalMap( '0189aafc-f88a-4e65-8fb4-09a047a3e334', SignalUUID('46f7e0e2-74a6-442b-9a5c-1bd4ea3da59c'), TextDesignator.SYMBOL_PIN_NAME) assert str( pin_signal_map ) == '(pin 0189aafc-f88a-4e65-8fb4-09a047a3e334 (signal 46f7e0e2-74a6-442b-9a5c-1bd4ea3da59c) (text pin))'
def generate_dev(mcu: MCU, symbol_map: Dict[str, str], base_lib_path: str, debug: bool = False) -> None: """ A device will be generated for every MCU ref. """ (placement, pin_mapping) = mcu.generate_placement_data(debug) name = mcu.ref dev_version = '0.1' package_uuid_mapping = { 'LQFP32': 'd1944164-969d-421f-8b46-1e79fc368195', # LQFP80P900X900X140-32 'LQFP44': 'b373f788-8d26-4e3d-9256-89851d962373', # LQFP80P1200X1200X140-44 'LQFP48': '584b7c26-5a8e-4a2b-807a-977edd1df991', # LQFP50P900X900X140-48 'LQFP64': '54cc857c-3af1-4af3-82b0-fba7a121bcb1', # LQFP50P1200X1200X140-64 'LQFP80': 'fde7e4d0-0548-4c0a-aa3e-6f8ce25e751c', # LQFP65P1600X1600X140-80 'LQFP100': 'f74cdcb2-833d-4877-876f-56d4c15b5cb8', # LQFP50P1600X1600X140-100 'LQFP144': '2fc34b46-a86d-40e3-9dd1-def143ac3318', # LQFP50P2200X2200X140-144 'LQFP176': '43ab9eca-7912-433f-afaa-61d3ec6c84b2', # LQFP50P2600X2600X140-176 'LQFP208': '422600f0-a868-49b6-92f7-22c1874258bb', # LQFP50P3000X3000X140-208 'SO8': 'ffbf2bed-9155-45a9-b154-2f766c7f9019', # SOIC127P600X175-8 'SO8N': 'ffbf2bed-9155-45a9-b154-2f766c7f9019', # SOIC127P600X175-8 'TSSOP14': 'fb8c2dc2-9812-4383-a810-b2fdbd525b4e', # TSSOP14P65_500X640X120L100X30 'TSSOP20': 'a040fccc-54e5-4f95-a5db-20044d8b37a5', # TSSOP20P65_650X640X120L100X30 } if mcu.package not in package_uuid_mapping: print('Skipping dev {} (missing package {})'.format(name, mcu.package)) return pad_uuid_mapping = common.get_pad_uuids(base_lib_path, package_uuid_mapping[mcu.package]) device = Device( uuid('dev', mcu.ref, 'dev'), Name(mcu.ref), Description(mcu.description), mcu.keywords, author, Version(dev_version), Created('2020-03-01T01:55:20Z'), Deprecated(False), cmpcat, ComponentUUID(uuid('cmp', mcu.component_identifier, 'cmp')), PackageUUID(package_uuid_mapping[mcu.package]), ) for pin in mcu.pins: pad_uuid = pad_uuid_mapping[pin.number] device.add_pad(ComponentPad( pad_uuid, SignalUUID(uuid('cmp', mcu.component_identifier, 'signal-{}'.format(pin.name))), )) device.serialize('out/stm_mcu/dev') print('Wrote dev {}'.format(name))
def test_component_variant() -> None: gate = Gate('c1e4b542-a1b1-44d5-bec3-070776143a29', SymbolUUID('8f1a97f2-4cdf-43da-b38d-b3787c47b5ad'), Position(0.0, 0.0), Rotation(0.0), Required(True), Suffix('')) gate.add_pin_signal_map( PinSignalMap('0189aafc-f88a-4e65-8fb4-09a047a3e334', SignalUUID('46f7e0e2-74a6-442b-9a5c-1bd4ea3da59c'), TextDesignator.SYMBOL_PIN_NAME)) variant = Variant('abeeeed0-6e9a-4fdc-bc2b-e2c5b06bbe3a', Norm.EMPTY, Name('default'), Description(''), gate) assert str( variant) == """(variant abeeeed0-6e9a-4fdc-bc2b-e2c5b06bbe3a (norm "")
def test_device() -> None: device = Device( '00652f30-9f89-4027-91f5-7bd684eee751', Name('Foo'), Description('Bar'), Keywords('foo, bar'), Author('J. Rando'), Version('0.1'), Created('2018-10-17T19:13:41Z'), Deprecated(False), Category('ade6d8ff-3c4f-4dac-a939-cc540c87c280'), ComponentUUID('bc911fcc-8b5c-4728-b596-d644797c55da'), PackageUUID('b4e92c64-18c4-44a6-aa39-d1be3e8c29bd'), ) device.add_pad( ComponentPad('aec3f475-28c4-4508-ab4f-e1b618a0d77d', SignalUUID('726fd1ce-a01b-4287-bb61-e3ff165a0644'))) device.add_pad( ComponentPad('67a7b034-b30b-4644-b8d3-d7a99606efdc', SignalUUID('9bccea5e-e23f-4b88-9de1-4be00dc0c12a'))) assert str( device) == """(librepcb_device 00652f30-9f89-4027-91f5-7bd684eee751
def generate_cmp( name: str, mcus: List[MCU], symbol_map: Dict[str, str], debug: bool = False, ) -> None: """ When generating components, to reduce the number of components, they are merged as follows: - For every MCU, the "ref without flash" is calculated by replacing the 11th character in the ref name with an `x` and cutting off everything after the package character. - MCUs that share the same pinout will be merged if their ref names without flash are the same - The name of the component will be generated as follows: STM32F429IEHx + STM32F429IGHx + STM32F429IIHx = STM32F429I[EGI]Hx. - To achieve a stable UUID even if new MCUs are added, the "ref without flash" is combined with the SHA1 hash of the pins. Because renaming the pinout might result in a different UUID, when upgrading the stm-pinout database, changes (but not additions) must be analyzed manually. """ components = [] for mcu in mcus: (placement, pin_mapping) = mcu.generate_placement_data(debug) cmp_version = '0.1' component = Component( uuid('cmp', mcu.component_identifier, 'cmp'), Name(name), Description(mcu.component_description), mcu.keywords, author, Version(cmp_version), Created('2020-01-30T20:55:23Z'), Deprecated(False), cmpcat, SchematicOnly(False), DefaultValue('{{PARTNUMBER or DEVICE or COMPONENT}}'), Prefix('U'), ) # Add signals signals = sorted({pin.name for pin in mcu.pins}, key=human_sort_key) for signal in signals: component.add_signal(Signal( # Use original signal name, so that changing the cleanup function # does not influence the identifier. uuid('cmp', mcu.component_identifier, 'signal-{}'.format(signal)), # Use cleaned up signal name for name Name(signal), Role.PASSIVE, Required(False), Negated(False), Clock(False), ForcedNet(''), )) # Add symbol variant gate = Gate( uuid('cmp', mcu.component_identifier, 'variant-single-gate1'), SymbolUUID(uuid('sym', mcu.symbol_identifier, 'sym')), Position(0, 0), Rotation(0.0), Required(True), Suffix(''), ) for generic, concrete in pin_mapping.items(): gate.add_pin_signal_map(PinSignalMap( uuid('sym', mcu.symbol_identifier, 'pin-{}'.format(generic)), SignalUUID(uuid('cmp', mcu.component_identifier, 'signal-{}'.format(concrete))), TextDesignator.SIGNAL_NAME, )) component.add_variant(Variant( uuid('cmp', mcu.component_identifier, 'variant-single'), Norm.EMPTY, Name('single'), Description('Symbol with all MCU pins'), gate, )) components.append(component) # Make sure all grouped components are identical assert len(set([str(c) for c in components])) == 1 components[0].serialize('out/stm_mcu/cmp') print('Wrote cmp {}'.format(name))
def generate_cmp( dirpath: str, author: str, name: str, name_lower: str, kind: str, cmpcat: str, keywords: str, default_value: str, rows: int, min_pads: int, max_pads: int, version: str, create_date: Optional[str], ) -> None: category = 'cmp' assert rows in [1, 2] for i in range(min_pads, max_pads + 1, rows): per_row = i // rows variant = '{}x{}'.format(rows, per_row) def _uuid(identifier: str) -> str: return uuid(category, kind, variant, identifier) uuid_cmp = _uuid('cmp') uuid_pins = [ uuid('sym', kind, variant, 'pin-{}'.format(p)) for p in range(i) ] uuid_signals = [_uuid('signal-{}'.format(p)) for p in range(i)] uuid_variant = _uuid('variant-default') uuid_gate = _uuid('gate-default') uuid_symbol = uuid('sym', kind, variant, 'sym') # General info component = Component( uuid_cmp, Name('{} {}x{:02d}'.format(name, rows, per_row)), Description('A {}x{} {}.\\n\\n' 'Generated with {}'.format(rows, per_row, name_lower, generator)), Keywords('connector, {}x{}, {}'.format(rows, per_row, keywords)), Author(author), Version(version), Created(create_date or now()), Deprecated(False), Category(cmpcat), SchematicOnly(False), DefaultValue(default_value), Prefix('J'), ) for p in range(1, i + 1): component.add_signal( Signal( uuid_signals[p - 1], Name(str(p)), Role.PASSIVE, Required(False), Negated(False), Clock(False), ForcedNet(''), )) gate = Gate( uuid_gate, SymbolUUID(uuid_symbol), Position(0.0, 0.0), Rotation(0.0), Required(True), Suffix(''), ) for p in range(1, i + 1): gate.add_pin_signal_map( PinSignalMap( uuid_pins[p - 1], SignalUUID(uuid_signals[p - 1]), TextDesignator.SYMBOL_PIN_NAME, )) component.add_variant( Variant(uuid_variant, Norm.EMPTY, Name('default'), Description(''), gate)) component.serialize(dirpath) print('{}x{} {}: Wrote component {}'.format(rows, per_row, kind, uuid_cmp))