PM_K-1 hardware: tag parts into circuit-block "sheets" for KiCad select-by-block

board.py now wraps each section in a SKiDL Group (Power/MCU/Audio/RTC/MIDI/Indicator/
Speaker/Interconnect) via inline grp()/endgrp() helpers (no reindent). The netlist now
carries a per-part (sheetpath (names "/<block>/")), so in Pcbnew you can right-click a
footprint -> Select -> Items in Same Hierarchical Sheet and move a whole block at once
instead of dragging 167 loose parts. 167 parts across 8 sheets; ERC 0 errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Me Here 2026-05-31 19:21:18 -05:00
parent 9792729be0
commit 4fb3365f36

View file

@ -26,6 +26,8 @@ D = Part("Device","D", dest=TEMPLATE, footprint="Diode_SMD:D_SOD-323")
DS = Part("Device","D_Schottky", dest=TEMPLATE, footprint="Diode_SMD:D_SOD-323") DS = Part("Device","D_Schottky", dest=TEMPLATE, footprint="Diode_SMD:D_SOD-323")
L = Part("Device","L", dest=TEMPLATE, footprint="Inductor_SMD:L_1210_3225Metric") # placeholder; set per actual inductor (Wuerth/EPCOS/Abracon) at layout L = Part("Device","L", dest=TEMPLATE, footprint="Inductor_SMD:L_1210_3225Metric") # placeholder; set per actual inductor (Wuerth/EPCOS/Abracon) at layout
def grp(n): g = Group(n); g.__enter__(); return g # tag a block as a "sheet" -> KiCad select-by-block
def endgrp(g): g.__exit__(None, None, None)
# ============================ shared nets ============================ # ============================ shared nets ============================
vbus,p5,p18,n18,p15,n15,p3v3,dvdd,gnd = (Net("VBUS_5V"),Net("+5V"),Net("+18V"),Net("-18V"), vbus,p5,p18,n18,p15,n15,p3v3,dvdd,gnd = (Net("VBUS_5V"),Net("+5V"),Net("+18V"),Net("-18V"),
Net("+15V"),Net("-15V"),Net("+3V3"),Net("DVDD"),Net("GND")) Net("+15V"),Net("-15V"),Net("+3V3"),Net("DVDD"),Net("GND"))
@ -60,6 +62,7 @@ def dcp(rail, val="100nF"):
c = C(val); rail += c[1]; c[2] += gnd c = C(val); rail += c[1]; c[2] += gnd
# ============================ POWER TREE ============================ # ============================ POWER TREE ============================
g = grp("Power")
TPS65131 = mk("TPS65131",[Pin(num=1,name="INP",func=P.PASSIVE),Pin(num=24,name="INP2",func=P.PASSIVE), TPS65131 = mk("TPS65131",[Pin(num=1,name="INP",func=P.PASSIVE),Pin(num=24,name="INP2",func=P.PASSIVE),
Pin(num=2,name="PGND",func=P.PWRIN),Pin(num=3,name="PGND2",func=P.PWRIN),Pin(num=4,name="VIN",func=P.PWRIN), Pin(num=2,name="PGND",func=P.PWRIN),Pin(num=3,name="PGND2",func=P.PWRIN),Pin(num=4,name="VIN",func=P.PWRIN),
Pin(num=5,name="INN",func=P.PASSIVE),Pin(num=6,name="INN2",func=P.PASSIVE),Pin(num=7,name="BSW",func=P.OUTPUT), Pin(num=5,name="INN",func=P.PASSIVE),Pin(num=6,name="INN2",func=P.PASSIVE),Pin(num=7,name="BSW",func=P.OUTPUT),
@ -107,7 +110,9 @@ cnn=C("10nF"); neg["NR"]+=cnn[1]; cnn[2]+=gnd
reg3["VIN"]+=p5; reg3["EN"]+=p5; reg3["GND"]+=gnd; reg3["VOUT"]+=p3v3 reg3["VIN"]+=p5; reg3["EN"]+=p5; reg3["GND"]+=gnd; reg3["VOUT"]+=p3v3
ci3=C("1uF"); p5+=ci3[1]; ci3[2]+=gnd; co3=C("1uF"); p3v3+=co3[1]; co3[2]+=gnd ci3=C("1uF"); p5+=ci3[1]; ci3[2]+=gnd; co3=C("1uF"); p3v3+=co3[1]; co3[2]+=gnd
endgrp(g)
# ============================ RP2350 CORE ============================ # ============================ RP2350 CORE ============================
g = grp("MCU")
rp = Part("MCU_RaspberryPi","RP2350A", footprint="Package_DFN_QFN:QFN-60-1EP_7x7mm_P0.4mm_EP3.4x3.4mm") rp = Part("MCU_RaspberryPi","RP2350A", footprint="Package_DFN_QFN:QFN-60-1EP_7x7mm_P0.4mm_EP3.4x3.4mm")
for n in (1,11,20,30,38,45): rp[n]+=p3v3 for n in (1,11,20,30,38,45): rp[n]+=p3v3
for n in (6,23,39): rp[n]+=dvdd for n in (6,23,39): rp[n]+=dvdd
@ -142,7 +147,9 @@ rp["GPIO19"]+=sig_led; rp["GPIO20"]+=clip_led; rp["GPIO21"]+=gndlift_sw; rp["GPI
rp["GPIO26/ADC0"]+=joy_x; rp["GPIO27/ADC1"]+=joy_y; rp["GPIO0"]+=dac_xsmt rp["GPIO26/ADC0"]+=joy_x; rp["GPIO27/ADC1"]+=joy_y; rp["GPIO0"]+=dac_xsmt
rp["GPIO4"]+=midi_tx; rp["GPIO1"]+=midi_rx rp["GPIO4"]+=midi_tx; rp["GPIO1"]+=midi_rx
endgrp(g)
# ============================ AUDIO CHAIN ============================ # ============================ AUDIO CHAIN ============================
g = grp("Audio")
THAT1240=mk("THAT1240",[Pin(num=1,name="REF",func=P.INPUT),Pin(num=2,name="IN-",func=P.INPUT),Pin(num=3,name="IN+",func=P.INPUT), THAT1240=mk("THAT1240",[Pin(num=1,name="REF",func=P.INPUT),Pin(num=2,name="IN-",func=P.INPUT),Pin(num=3,name="IN+",func=P.INPUT),
Pin(num=4,name="V-",func=P.PWRIN),Pin(num=5,name="SENSE",func=P.PASSIVE),Pin(num=6,name="OUT",func=P.OUTPUT), Pin(num=4,name="V-",func=P.PWRIN),Pin(num=5,name="SENSE",func=P.PASSIVE),Pin(num=6,name="OUT",func=P.OUTPUT),
Pin(num=7,name="V+",func=P.PWRIN),Pin(num=8,name="NC",func=P.NOCONNECT)]) Pin(num=7,name="V+",func=P.PWRIN),Pin(num=8,name="NC",func=P.NOCONNECT)])
@ -222,7 +229,9 @@ rl[1]+=gnd; rl[2]+=chassis; cl[1]+=gnd; cl[2]+=chassis; k3["COIL_A"]+=p5; k3["CO
uln["1B"]+=sel_linst; uln["1C"]+=k1d; uln["2B"]+=mute_en; uln["2C"]+=k2d; uln["3B"]+=gndlift_en; uln["3C"]+=k3d uln["1B"]+=sel_linst; uln["1C"]+=k1d; uln["2B"]+=mute_en; uln["2C"]+=k2d; uln["3B"]+=gndlift_en; uln["3C"]+=k3d
uln["GND"]+=gnd; uln["COM"]+=p5 uln["GND"]+=gnd; uln["COM"]+=p5
endgrp(g)
# ============================ RTC ============================ # ============================ RTC ============================
g = grp("RTC")
RV8803=mk("RV-8803-C7",[Pin(num=1,name="SDA",func=P.BIDIR),Pin(num=2,name="CLKOUT",func=P.OUTPUT),Pin(num=3,name="VDD",func=P.PWRIN), RV8803=mk("RV-8803-C7",[Pin(num=1,name="SDA",func=P.BIDIR),Pin(num=2,name="CLKOUT",func=P.OUTPUT),Pin(num=3,name="VDD",func=P.PWRIN),
Pin(num=4,name="CLKOE",func=P.INPUT),Pin(num=5,name="VSS",func=P.PWRIN),Pin(num=6,name="INT",func=P.OPENCOLL), Pin(num=4,name="CLKOE",func=P.INPUT),Pin(num=5,name="VSS",func=P.PWRIN),Pin(num=6,name="INT",func=P.OPENCOLL),
Pin(num=7,name="EVI",func=P.INPUT),Pin(num=8,name="SCL",func=P.INPUT)],fp="pm_k1:RV-8803-C7") Pin(num=7,name="EVI",func=P.INPUT),Pin(num=8,name="SCL",func=P.INPUT)],fp="pm_k1:RV-8803-C7")
@ -235,7 +244,9 @@ for net in (i2c_sda,i2c_scl):
rpu2=R(value="4.7k"); net+=rpu2[1]; rpu2[2]+=p3v3 rpu2=R(value="4.7k"); net+=rpu2[1]; rpu2[2]+=p3v3
rint=R(value="10k"); rtc_int+=rint[1]; rint[2]+=p3v3 rint=R(value="10k"); rtc_int+=rint[1]; rint[2]+=p3v3
endgrp(g)
# ============================ MIDI (DNP) ============================ # ============================ MIDI (DNP) ============================
g = grp("MIDI")
H11L1=mk("H11L1",[Pin(num=1,name="A",func=P.PASSIVE),Pin(num=2,name="C",func=P.PASSIVE),Pin(num=3,name="NC",func=P.NOCONNECT), H11L1=mk("H11L1",[Pin(num=1,name="A",func=P.PASSIVE),Pin(num=2,name="C",func=P.PASSIVE),Pin(num=3,name="NC",func=P.NOCONNECT),
Pin(num=4,name="GND",func=P.PWRIN),Pin(num=5,name="VO",func=P.OPENCOLL),Pin(num=6,name="VCC",func=P.PWRIN)],fp="Package_DIP:DIP-6_W7.62mm") Pin(num=4,name="GND",func=P.PWRIN),Pin(num=5,name="VO",func=P.OPENCOLL),Pin(num=6,name="VCC",func=P.PWRIN)],fp="Package_DIP:DIP-6_W7.62mm")
LVC14=mk("74LVC14",[Pin(num=1,name="1A",func=P.INPUT),Pin(num=2,name="1Y",func=P.OUTPUT),Pin(num=3,name="2A",func=P.INPUT), LVC14=mk("74LVC14",[Pin(num=1,name="1A",func=P.INPUT),Pin(num=2,name="1Y",func=P.OUTPUT),Pin(num=3,name="2A",func=P.INPUT),
@ -251,7 +262,9 @@ roa=R(value="33"); p3v3+=roa[1]; roa[2]+=mo_a
buf["3A"]+=midi_rx; buf["3Y"]+=Net(); buf["4A"]+=buf["3Y"]; rtb=R(value="33"); buf["4Y"]+=rtb[1]; rtb[2]+=mt_b buf["3A"]+=midi_rx; buf["3Y"]+=Net(); buf["4A"]+=buf["3Y"]; rtb=R(value="33"); buf["4Y"]+=rtb[1]; rtb[2]+=mt_b
rta=R(value="33"); p3v3+=rta[1]; rta[2]+=mt_a; buf["5A"]+=gnd; buf["6A"]+=gnd; buf["VCC"]+=p3v3; buf["GND"]+=gnd; dcp(p3v3) rta=R(value="33"); p3v3+=rta[1]; rta[2]+=mt_a; buf["5A"]+=gnd; buf["6A"]+=gnd; buf["VCC"]+=p3v3; buf["GND"]+=gnd; dcp(p3v3)
endgrp(g)
# ============================ INDICATOR (DNP) ============================ # ============================ INDICATOR (DNP) ============================
g = grp("Indicator")
LM393=mk("LM393",[Pin(num=1,name="OUT1",func=P.OPENCOLL),Pin(num=2,name="-IN1",func=P.INPUT),Pin(num=3,name="+IN1",func=P.INPUT), LM393=mk("LM393",[Pin(num=1,name="OUT1",func=P.OPENCOLL),Pin(num=2,name="-IN1",func=P.INPUT),Pin(num=3,name="+IN1",func=P.INPUT),
Pin(num=4,name="V-",func=P.PWRIN),Pin(num=5,name="+IN2",func=P.INPUT),Pin(num=6,name="-IN2",func=P.INPUT), Pin(num=4,name="V-",func=P.PWRIN),Pin(num=5,name="+IN2",func=P.INPUT),Pin(num=6,name="-IN2",func=P.INPUT),
Pin(num=7,name="OUT2",func=P.OPENCOLL),Pin(num=8,name="V+",func=P.PWRIN)]) Pin(num=7,name="OUT2",func=P.OPENCOLL),Pin(num=8,name="V+",func=P.PWRIN)])
@ -266,7 +279,9 @@ cmp["+IN2"]+=peak(mix_out); cmp["-IN2"]+=thr("100k","68k")
rsl=R(value="10k"); cmp["OUT1"]+=sig_led; sig_led+=rsl[1]; rsl[2]+=p3v3 rsl=R(value="10k"); cmp["OUT1"]+=sig_led; sig_led+=rsl[1]; rsl[2]+=p3v3
rcl=R(value="10k"); cmp["OUT2"]+=clip_led; clip_led+=rcl[1]; rcl[2]+=p3v3 rcl=R(value="10k"); cmp["OUT2"]+=clip_led; clip_led+=rcl[1]; rcl[2]+=p3v3
endgrp(g)
# ============================ SPEAKER (DNP) ============================ # ============================ SPEAKER (DNP) ============================
g = grp("Speaker")
PAM=mk("PAM8302A",[Pin(num=1,name="SD",func=P.INPUT),Pin(num=2,name="NC",func=P.NOCONNECT),Pin(num=3,name="IN+",func=P.INPUT), PAM=mk("PAM8302A",[Pin(num=1,name="SD",func=P.INPUT),Pin(num=2,name="NC",func=P.NOCONNECT),Pin(num=3,name="IN+",func=P.INPUT),
Pin(num=4,name="IN-",func=P.INPUT),Pin(num=5,name="VO+",func=P.OUTPUT),Pin(num=6,name="VDD",func=P.PWRIN), Pin(num=4,name="IN-",func=P.INPUT),Pin(num=5,name="VO+",func=P.OUTPUT),Pin(num=6,name="VDD",func=P.PWRIN),
Pin(num=7,name="GND",func=P.PWRIN),Pin(num=8,name="VO-",func=P.OUTPUT)]) Pin(num=7,name="GND",func=P.PWRIN),Pin(num=8,name="VO-",func=P.OUTPUT)])
@ -275,7 +290,9 @@ rsd=R(value="100k"); spk_sd+=rsd[1]; rsd[2]+=p5; amp["SD"]+=spk_sd
cia=C("1uF"); ria=R(value="68k"); mix_out+=cia[1]; cia[2]+=ria[1]; ria[2]+=amp["IN+"] cia=C("1uF"); ria=R(value="68k"); mix_out+=cia[1]; cia[2]+=ria[1]; ria[2]+=amp["IN+"]
cim=C("1uF"); amp["IN-"]+=cim[1]; cim[2]+=gnd; amp["VO+"]+=spk_p; amp["VO-"]+=spk_n cim=C("1uF"); amp["IN-"]+=cim[1]; cim[2]+=gnd; amp["VO+"]+=spk_p; amp["VO-"]+=spk_n
endgrp(g)
# ============================ INTERCONNECTS ============================ # ============================ INTERCONNECTS ============================
g = grp("Interconnect")
def hdr(name,fp): return Part("Connector_Generic",name,footprint=fp) def hdr(name,fp): return Part("Connector_Generic",name,footprint=fp)
j3=hdr("Conn_02x13_Odd_Even","Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical") j3=hdr("Conn_02x13_Odd_Even","Connector_PinHeader_2.54mm:PinHeader_2x13_P2.54mm_Vertical")
for pin,net in {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, for pin,net in {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,
@ -292,6 +309,7 @@ ESD=mk("USBLC6-2SC6",[Pin(num=1,name="IO1",func=P.PASSIVE),Pin(num=2,name="GND",
Pin(num=4,name="IO2b",func=P.PASSIVE),Pin(num=5,name="VBUS",func=P.PASSIVE),Pin(num=6,name="IO1b",func=P.PASSIVE)],fp="Package_TO_SOT_SMD:SOT-23-6") Pin(num=4,name="IO2b",func=P.PASSIVE),Pin(num=5,name="VBUS",func=P.PASSIVE),Pin(num=6,name="IO1b",func=P.PASSIVE)],fp="Package_TO_SOT_SMD:SOT-23-6")
esd=ESD(); esd[1]+=usb_dp_c; esd[6]+=usb_dp_c; esd[3]+=usb_dm_c; esd[4]+=usb_dm_c; esd[2]+=gnd; esd[5]+=vbus esd=ESD(); esd[1]+=usb_dp_c; esd[6]+=usb_dp_c; esd[3]+=usb_dm_c; esd[4]+=usb_dm_c; esd[2]+=gnd; esd[5]+=vbus
endgrp(g)
ERC() ERC()
out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "board.net")) out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "board.net"))
generate_netlist(file_=out) generate_netlist(file_=out)