PM_K-1 hardware: interconnects (digital ribbon + analog + MIDI headers + USB-C/ESD)

circuits/interconnect.py maps the board nets onto connectors per DESIGN.md s7:
- J3 digital ribbon 2x13 (Pico-pinout): display SPI, touch I2C, joystick ADC, buttons,
  WS2812, panel-switch inputs, SIG/CLIP LED lines, power.
- J4 analog 2x5: balanced out hot/cold, shield, balanced in hot/cold, speaker (kept off
  the fast digital ribbon).
- J5 MIDI 1x8: OUT/IN/THRU loops + power (DNP MIDI only).
- J1 USB-C receptacle (KiCad lib symbol) + USBLC6-2SC6 ESD + 5.1k CC pulldowns; D+/D-
  from the core's 27R series, VBUS to the power tree.
ERC 0 errors; netlist 0 errors. Confirm USB-C connector variant (24-pin sym vs 16-pin
GCT USB4085) + USBLC6 footprint at layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-30 23:33:21 -05:00
parent 8f662598e4
commit 7eea02f1d2

View file

@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""PM_K-1 interconnects (SKiDL): digital ribbon + analog header + MIDI header + USB-C sub-block.
Run INSIDE the EDA container:
cd hardware/eda && ./run.sh python3 ../eda/circuits/interconnect.py
Outputs ERC + hardware/kicad/interconnect.net.
Maps the named board nets onto the physical connectors (pinouts per DESIGN.md s7):
J3 digital ribbon (2x13, Pico-pinout) -- display SPI, touch I2C, joystick ADC, buttons,
LED, panel-switch inputs, SIG/CLIP LED lines, power.
J4 analog header (2x5) -- balanced out hot/cold, shield, balanced in hot/cold, speaker.
J5 MIDI header (1x8) -- OUT/IN/THRU loops + 5V + GND (used only if DNP MIDI fitted).
J1 USB-C receptacle + USBLC6-2SC6 ESD + CC pulldowns. D+/D- come from the core's 27R
series (USB_DP_CONN/USB_DM_CONN); VBUS feeds the power tree.
USB_C_Receptacle = authoritative KiCad symbol (24-pin; SS pins unused for USB2.0). If a
16-pin USB2.0 connector (GCT USB4085, in BOM) is used, swap symbol+footprint at layout.
USBLC6-2SC6 hand-defined to the standard ST SOT-23-6 pinout (I/O1=1,6 / GND=2 / I/O2=3,4 /
VBUS=5) -- confirm at layout.
"""
import os
from skidl import *
set_default_tool(KICAD9)
P = Pin.types
R = Part("Device","R", dest=TEMPLATE, footprint="Resistor_SMD:R_0402_1005Metric")
# ---- rails + every signal that crosses to a face ----
p5, p3v3, gnd = Net("+5V"), Net("+3V3"), Net("GND")
for n in (p5, p3v3): n.drive = POWER
gnd.drive = POWER
N = lambda s: Net(s)
spi_sck,spi_mosi,lcd_cs,lcd_dc,lcd_rst = N("SPI_SCK"),N("SPI_MOSI"),N("LCD_CS"),N("LCD_DC"),N("LCD_RST")
i2c_sda,i2c_scl,joy_x,joy_y,btn_a,btn_b,ws2812 = N("I2C_SDA"),N("I2C_SCL"),N("JOY_X"),N("JOY_Y"),N("BTN_A"),N("BTN_B"),N("WS2812")
gndlift_sw,lineinst_sw,sig_led,clip_led = N("GNDLIFT_SW"),N("LINEINST_SW"),N("SIG_LED"),N("CLIP_LED")
aout_hot,aout_cold,chassis,ain_hot,ain_cold,spkp,spkn = (N("AOUT_HOT"),N("AOUT_COLD"),N("CHASSIS"),
N("AIN_HOT"),N("AIN_COLD"),N("SPK_P"),N("SPK_N"))
mo_a,mo_b,mi_a,mi_b,mt_a,mt_b = N("MIDI_OUT_A"),N("MIDI_OUT_B"),N("MIDI_IN_A"),N("MIDI_IN_B"),N("MIDI_THRU_A"),N("MIDI_THRU_B")
vbus,usb_dp_c,usb_dm_c = N("VBUS_5V"),N("USB_DP_CONN"),N("USB_DM_CONN")
vbus.drive = POWER
def hdr(name, fp, ref): return Part("Connector_Generic", name, footprint=fp, ref=ref)
# ---- J3 digital ribbon (2x13, Pico-pinout) -- DESIGN.md s7.1 ----
j3 = hdr("Conn_02x13_Odd_Even","Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical","J3")
dmap = {1:p5,2:gnd,3:p3v3,4:gnd,5:spi_sck,6:gnd,7:spi_mosi,8:lcd_cs,9:lcd_dc,10:lcd_rst,
11:gnd,12:i2c_sda,13:i2c_scl,14:gnd,15:joy_x,16:joy_y,17:btn_a,18:btn_b,19:ws2812,20:gnd,
21:gndlift_sw,22:lineinst_sw,23:sig_led,24:clip_led,25:gnd,26:gnd}
for pin,net in dmap.items(): j3[pin] += net
# ---- J4 analog header (2x5) -- DESIGN.md s7.2 (kept away from the digital ribbon) ----
j4 = hdr("Conn_02x05_Odd_Even","Connector_PinHeader_2.54mm:PinHeader_2x05_P2.54mm_Vertical","J4")
amap = {1:aout_hot,2:gnd,3:aout_cold,4:chassis,5:ain_hot,6:gnd,7:ain_cold,8:spkp,9:gnd,10:spkn}
for pin,net in amap.items(): j4[pin] += net
# ---- J5 MIDI header (1x8) -- OUT/IN/THRU + power (DNP MIDI only) ----
j5 = hdr("Conn_01x08","Connector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_Vertical","J5")
mmap = {1:mo_a,2:mo_b,3:mi_a,4:mi_b,5:mt_a,6:mt_b,7:p5,8:gnd}
for pin,net in mmap.items(): j5[pin] += net
# ---- J1 USB-C receptacle (USB2.0 subset of the 24-pin symbol) ----
j1 = Part("Connector","USB_C_Receptacle",
footprint="Connector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12", ref="J1")
j1["VBUS"] += vbus; j1["GND"] += gnd; j1["SHIELD"] += chassis
j1["D+"] += usb_dp_c; j1["D-"] += usb_dm_c # name returns both A/B-side pins
rcc1 = R(value="5.1k"); rcc2 = R(value="5.1k") # UFP/device CC pulldowns
j1["CC1"] += rcc1[1]; rcc1[2] += gnd
j1["CC2"] += rcc2[1]; rcc2[2] += gnd
# ---- USBLC6-2SC6 ESD (standard ST SOT-23-6 pinout) ----
ESD = Part(name="USBLC6-2SC6", tool=SKIDL, dest=TEMPLATE, ref_prefix="U",
footprint="Package_TO_SOT_SMD:SOT-23-6",
pins=[Pin(num=1,name="IO1",func=P.PASSIVE),Pin(num=2,name="GND",func=P.PWRIN),Pin(num=3,name="IO2",func=P.PASSIVE),
Pin(num=4,name="IO2b",func=P.PASSIVE),Pin(num=5,name="VBUS",func=P.PASSIVE),Pin(num=6,name="IO1b",func=P.PASSIVE)])
esd = ESD(ref="U10")
esd[1] += usb_dp_c; esd[6] += usb_dp_c # I/O1 (D+) clamp
esd[3] += usb_dm_c; esd[4] += usb_dm_c # I/O2 (D-) clamp
esd[2] += gnd; esd[5] += vbus
ERC()
out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "interconnect.net"))
generate_netlist(file_=out)
print("Interconnect netlist ->", out)