main
John Lauer README: component table per the wiki format, open-source section, no duplicate hero; generators at gen/ 39a59ef 7d ago
#!/usr/bin/env python3
"""Adom-style IC symbols (adom-symbol create: functional pin groups, the 3D-chip outline baked in) for the
riser's ICs. Pin numbers and names from the manufacturer datasheets (TI SN74LV165A SCLS402, TI TPS3808 SBVS050,
TI SN74LVC125A SCAS290, TI TPD4E05U06 SLVSBO7, ROHM BR24H64xxx-5AC)."""
import json, os, subprocess
OUT = os.path.join(os.path.dirname(__file__), "..", "kicad", "lib", "adom-symbols")
P = lambda n, num, t, g, side=None: dict(name=n, number=str(num), type=t, group=g, **({"side": side} if side else {}))
ICS = {
 "SN74LV165APWR": dict(manufacturer="Texas Instruments", package="TSSOP-16", description="8-bit parallel-load shift register (OCP NIC 3.0 scan chain SR0)",
   datasheetUrl="https://www.ti.com/lit/ds/symlink/sn74lv165a.pdf", pins=[
   P("A", 11, "input", "PARALLEL IN", "left"), P("B", 12, "input", "PARALLEL IN", "left"), P("C", 13, "input", "PARALLEL IN", "left"),
   P("D", 14, "input", "PARALLEL IN", "left"), P("E", 3, "input", "PARALLEL IN", "left"), P("F", 4, "input", "PARALLEL IN", "left"),
   P("G", 5, "input", "PARALLEL IN", "left"), P("H", 6, "input", "PARALLEL IN", "left"),
   P("SER", 10, "input", "SERIAL", "right"), P("QH", 9, "output", "SERIAL", "right"), P("~{QH}", 7, "output", "SERIAL", "right"),
   P("SH/~{LD}", 1, "input", "CONTROL", "right"), P("CLK", 2, "input", "CONTROL", "right"), P("CLK_INH", 15, "input", "CONTROL", "right"),
   P("VCC", 16, "power_in", "POWER", "right"), P("GND", 8, "power_in", "POWER", "left")]),
 "BR24H64FJ-5ACE2": dict(manufacturer="ROHM Semiconductor", package="SOP-J8", description="64 Kbit I2C EEPROM, 2-byte addressing (OCP NIC 3.0 FRU)",
   datasheetUrl="https://fscdn.rohm.com/en/products/databook/datasheet/ic/memory/eeprom/br24h64xxx-5ac-e.pdf", pins=[
   P("A0", 1, "input", "ADDRESS", "left"), P("A1", 2, "input", "ADDRESS", "left"), P("A2", 3, "input", "ADDRESS", "left"),
   P("WP", 7, "input", "CONTROL", "left"), P("SDA", 5, "bidirectional", "I2C", "right"), P("SCL", 6, "input", "I2C", "right"),
   P("VCC", 8, "power_in", "POWER", "right"), P("GND", 4, "power_in", "POWER", "left")]),
 "TPS3808G33DBV": dict(manufacturer="Texas Instruments", package="SOT-23-6 (DBV)", description="Voltage supervisor 3.07 V with manual reset and programmable delay",
   datasheetUrl="https://www.ti.com/lit/ds/symlink/tps3808.pdf", pins=[
   P("SENSE", 5, "input", "MONITOR", "left"), P("~{MR}", 3, "input", "MONITOR", "left"), P("CT", 4, "passive", "DELAY", "left"),
   P("~{RESET}", 1, "open_collector", "OUTPUT", "right"), P("VDD", 6, "power_in", "POWER", "right"), P("GND", 2, "power_in", "POWER", "left")]),
 "SN74LVC125APWR": dict(manufacturer="Texas Instruments", package="TSSOP-14", description="Quad bus buffer with 3-state outputs, Ioff",
   datasheetUrl="https://www.ti.com/lit/ds/symlink/sn74lvc125a.pdf", pins=[
   P("1A", 2, "input", "INPUTS", "left"), P("2A", 5, "input", "INPUTS", "left"), P("3A", 9, "input", "INPUTS", "left"), P("4A", 12, "input", "INPUTS", "left"),
   P("~{1OE}", 1, "input", "ENABLES", "left"), P("~{2OE}", 4, "input", "ENABLES", "left"), P("~{3OE}", 10, "input", "ENABLES", "left"), P("~{4OE}", 13, "input", "ENABLES", "left"),
   P("1Y", 3, "tri_state", "OUTPUTS", "right"), P("2Y", 6, "tri_state", "OUTPUTS", "right"), P("3Y", 8, "tri_state", "OUTPUTS", "right"), P("4Y", 11, "tri_state", "OUTPUTS", "right"),
   P("VCC", 14, "power_in", "POWER", "right"), P("GND", 7, "power_in", "POWER", "left")]),
 "TPD4E05U06QDQARQ1": dict(manufacturer="Texas Instruments", package="USON-10 (DQA)", description="4-channel ESD protection, 0.5 pF",
   datasheetUrl="https://www.ti.com/lit/ds/symlink/tpd4e05u06.pdf", pins=[
   P("D1+", 1, "passive", "PROTECTED", "left"), P("D1-", 2, "passive", "PROTECTED", "left"), P("D2+", 4, "passive", "PROTECTED", "left"), P("D2-", 5, "passive", "PROTECTED", "left"),
   P("NC", 6, "no_connect", "NC", "right"), P("NC", 7, "no_connect", "NC", "right"), P("NC", 9, "no_connect", "NC", "right"), P("NC", 10, "no_connect", "NC", "right"),
   P("GND", 3, "power_in", "GROUND", "left"), P("GND", 8, "power_in", "GROUND", "left")]),
}
if __name__ == "__main__":
    for name, d in ICS.items():
        spec = dict(symbolName=name, pinCount=len(d["pins"]), referencePrefix="U", **d)
        jf = os.path.join(OUT, name + ".create.json")
        json.dump(spec, open(jf, "w"), indent=1)
        r = subprocess.run(["adom-symbol", "create", "--file", jf, "--out", os.path.join(OUT, name)], capture_output=True, text=True)
        tail = [l for l in (r.stdout + r.stderr).splitlines() if l.strip()][-3:]
        print(name, r.returncode, " | ".join(tail)[:300])


def snap_pins(path, grid=2.54):
    """adom-symbol 1.2.2 spaces pin groups by non-grid gaps; snap every pin end onto the grid of the first pin
    (moves of at most half a grid step) so KiCad ERC sees on-grid connection points."""
    import re
    txt = open(path).read()
    m = re.search(r'\(pin \w+ \w+ \(at ([-\d.]+) ([-\d.]+) ', txt)
    y0 = float(m.group(2))
    def fix(mm):
        x, y = float(mm.group(1)), float(mm.group(2))
        yn = y0 + round((y - y0) / grid) * grid
        return f"(at {x:.2f} {yn:.2f} "
    txt = re.sub(r'(?<=\(pin )(\w+ \w+ )\(at ([-\d.]+) ([-\d.]+) ', lambda mm: mm.group(1) + fix(type("M", (), {"group": lambda s, i: mm.group(i + 1)})()), txt)
    open(path, "w").write(txt)


if __name__ == "__main__":
    for name in ICS:
        snap_pins(os.path.join(OUT, name, name + ".kicad_sym"))
    print("pins snapped")