Wire sexp pin fallback into connectivity engine

_build_connectivity() used sch.list_component_pins() which returns
empty for custom library symbols. Added a second pass that falls back
to parse_lib_symbol_pins() + transform_pin_to_schematic() for any
component that returned 0 pins from the API. This brings custom IC
pins (e.g. ESP32-P4's 105 pins) into the union-find net graph.
This commit is contained in:
Ryan Malloy 2026-03-04 17:30:05 -07:00
parent e610bf3871
commit b347679c67

View File

@ -178,6 +178,7 @@ def _build_connectivity(
# --- 2. Map component pin positions to coordinates ---
pin_at: dict[tuple[float, float], list[dict[str, str]]] = {}
all_pins: list[tuple[str, str, tuple[float, float]]] = []
refs_with_pins: set[str] = set()
for comp in getattr(sch, "components", []):
ref = getattr(comp, "reference", None)
@ -190,9 +191,42 @@ def _build_connectivity(
entry = {"reference": str(ref), "pin": str(pin_num)}
pin_at.setdefault(coord, []).append(entry)
all_pins.append((str(ref), str(pin_num), coord))
refs_with_pins.add(str(ref))
except Exception:
pass
# 2b. Fallback: for components where list_component_pins() returned
# nothing (custom library symbols), extract pins from the raw
# (lib_symbols ...) section via the S-expression parser.
if schematic_path:
for comp in getattr(sch, "components", []):
ref = getattr(comp, "reference", None)
if not ref or str(ref) in refs_with_pins:
continue
lib_id = getattr(comp, "lib_id", None)
if not lib_id:
continue
sexp_pins = parse_lib_symbol_pins(schematic_path, str(lib_id))
if not sexp_pins:
continue
comp_pos = getattr(comp, "position", None)
comp_rot = float(getattr(comp, "rotation", 0) or 0)
comp_mirror = getattr(comp, "mirror", None)
mirror_x = comp_mirror in ("x", True) if comp_mirror else False
cx = float(comp_pos.x) if comp_pos is not None and hasattr(comp_pos, "x") else 0.0
cy = float(comp_pos.y) if comp_pos is not None and hasattr(comp_pos, "y") else 0.0
for sp in sexp_pins:
sx, sy = transform_pin_to_schematic(
sp["x"], sp["y"], cx, cy, comp_rot, mirror_x
)
coord = _rc(sx, sy)
_find(coord)
entry = {"reference": str(ref), "pin": sp["number"]}
pin_at.setdefault(coord, []).append(entry)
all_pins.append((str(ref), sp["number"], coord))
# --- 3. Map labels to coordinates (labels name nets) ---
label_at: dict[tuple[float, float], str] = {}