From 5129a5a5448012a53cb9ddae1349c2a2c8571339 Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Sun, 8 Nov 2026 18:14:54 +0100 Subject: Add KiCad 9 schematic, project libraries and datasheets Schematic (kicad/), one sheet per function as on ULX3S: - power: TLV62569 bucks for +1V1 / +3V3, AP2112K LDO for +2V5 - usb: USB-C with PTC and TVS, CH347F for JTAG and UART - fpga_power, fpga_config, fpga_banks_01/23/67: ECP5 LFE5U-25F caBGA256 (pin compatible with the 45F), quad SPI flash, 50 MHz CLOCK_50, ball assignment as in PINPLAN.md - ethernet: RTL8211F gigabit PHY, HR911130A RJ45, shield via 1M || 1nF 2kV - sdram: 32 MB W9825G6KH-6 - hdmi: TMDS from the FPGA (LVCMOS33D), AC coupled, ESD protected - user_io: SW, KEY (debounced), LEDR, LEDG, HEX0-HEX3 with DE1 names - gpio: two DE1 compatible 2x20 headers (THDB-ADA on GPIO_0), Pmod A/B, ESD arrays - testpoints: bring-up pads, M3 mounting holes All parts have LCSC numbers, MPN and manufacturer for JLCPCB assembly; footprints are cross-checked against the EasyEDA data. Libraries: ECP5 symbols generated from the Lattice pinout CSVs (kipart), CH347F, RTL8211F, SM410561N symbols, HR911130A symbol and footprint from KiCad library merge requests, generator scripts in lib/tools/. Datasheets of all parts except resistors and capacitors in datasheets/ (manufacturer copyright, not covered by the project licenses). --- kicad/lib/tools/derive_symbol.py | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100755 kicad/lib/tools/derive_symbol.py (limited to 'kicad/lib/tools/derive_symbol.py') diff --git a/kicad/lib/tools/derive_symbol.py b/kicad/lib/tools/derive_symbol.py new file mode 100755 index 0000000..1278128 --- /dev/null +++ b/kicad/lib/tools/derive_symbol.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-3.0-or-later +"""Add a pin-compatible variant of a symbol to a KiCad symbol library. + +The variant keeps the geometry of the base symbol (every pin number at the +same position), so "Change symbol" in the schematic swaps the two without +breaking wires. Pin names and the description come from the variant's kipart +CSV (as written by lattice2kipart.py). + + derive_symbol.py LIB.kicad_sym BASE_NAME VARIANT.csv > OUT.kicad_sym +""" +import csv +import re +import sys + + +def match_paren(t, i): + depth = 0 + j = i + while True: + c = t[j] + if c == '"': + j += 1 + while t[j] != '"': + j += 2 if t[j] == "\\" else 1 + elif c == "(": + depth += 1 + elif c == ")": + depth -= 1 + if depth == 0: + return j + 1 + j += 1 + + +lib_path, base, var_csv = sys.argv[1:4] +lib = open(lib_path).read() + +rows = list(csv.reader(open(var_csv, newline=""))) +variant = rows[0][0] +props = {r[0][:-1].replace("*", ""): r[1] for r in rows[1:] if r and r[0].endswith(":")} +hdr = next(i for i, r in enumerate(rows) if r and r[0] == "pin") +cols = rows[hdr] +pins = {r[cols.index("pin")]: (r[cols.index("name")], r[cols.index("type")]) + for r in rows[hdr + 1:] if r and r[0]} + +m = re.search(r'\(symbol "' + re.escape(base) + r'"', lib) +start = m.start() +block = lib[start:match_paren(lib, start)] +base_types = {n: t for t, n in re.findall(r'\(pin (\w+) \w+ .*?\(number "([^"]+)"', block, re.S)} + +new = block.replace(f'(symbol "{base}"', f'(symbol "{variant}"', 1) +new = new.replace(f'(symbol "{base}_', f'(symbol "{variant}_') +new = re.sub(r'(\(property "Value" )"[^"]*"', rf'\1"{variant}"', new, count=1) +for key in ("Description", "Source"): + if key in props: + new = re.sub(r'(\(property "' + key + r'" )"[^"]*"', lambda mm: f'{mm.group(1)}"{props[key]}"', + new, count=1) + + +def rename(mm): + num = mm.group(3) + name, typ = pins[num] + if typ != base_types[num] and not (base_types[num] == "passive"): # stacked pins are passive + sys.exit(f"pin {num}: type {typ} differs from {base_types[num]}") + return f'{mm.group(1)}(name "{name}"{mm.group(2)}(number "{num}"' + + +new, n = re.subn(r'(\(pin [^\n]*\n(?:(?!\(pin ).)*?)\(name "[^"]*"(.*?)\(number "([^"]+)"', + rename, new, flags=re.S) +if n != len(pins): + sys.exit(f"renamed {n} pins, variant has {len(pins)}") + +end = match_paren(lib, start) +sys.stdout.write(lib[:end] + "\n " + new + lib[end:]) -- cgit v1.2.3