From 4fb3365f36384272ac13d509e07ec72b2d73033f Mon Sep 17 00:00:00 2001 From: Me Here Date: Sun, 31 May 2026 19:21:18 -0500 Subject: [PATCH] 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 "//")), 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) --- hardware/eda/circuits/board.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hardware/eda/circuits/board.py b/hardware/eda/circuits/board.py index 656a6b7..10ac951 100644 --- a/hardware/eda/circuits/board.py +++ b/hardware/eda/circuits/board.py @@ -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") 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 ============================ 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")) @@ -60,6 +62,7 @@ def dcp(rail, val="100nF"): c = C(val); rail += c[1]; c[2] += gnd # ============================ POWER TREE ============================ +g = grp("Power") 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=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 ci3=C("1uF"); p5+=ci3[1]; ci3[2]+=gnd; co3=C("1uF"); p3v3+=co3[1]; co3[2]+=gnd +endgrp(g) # ============================ RP2350 CORE ============================ +g = grp("MCU") 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 (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["GPIO4"]+=midi_tx; rp["GPIO1"]+=midi_rx +endgrp(g) # ============================ 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), 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)]) @@ -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["GND"]+=gnd; uln["COM"]+=p5 +endgrp(g) # ============================ 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), 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") @@ -235,7 +244,9 @@ for net in (i2c_sda,i2c_scl): rpu2=R(value="4.7k"); net+=rpu2[1]; rpu2[2]+=p3v3 rint=R(value="10k"); rtc_int+=rint[1]; rint[2]+=p3v3 +endgrp(g) # ============================ 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), 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), @@ -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 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) ============================ +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), 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)]) @@ -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 rcl=R(value="10k"); cmp["OUT2"]+=clip_led; clip_led+=rcl[1]; rcl[2]+=p3v3 +endgrp(g) # ============================ 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), 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)]) @@ -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+"] cim=C("1uF"); amp["IN-"]+=cim[1]; cim[2]+=gnd; amp["VO+"]+=spk_p; amp["VO-"]+=spk_n +endgrp(g) # ============================ INTERCONNECTS ============================ +g = grp("Interconnect") 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") 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") 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() out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "board.net")) generate_netlist(file_=out)