#!/usr/bin/env python3 """PM_K-1 power tree (SKiDL): USB 5V -> +/-18V switcher -> ultra-low-noise +/-15V LDOs, plus the digital 3V3 rail. Run INSIDE the EDA container: cd hardware/eda && ./run.sh python3 ../eda/circuits/power_tree.py Outputs ERC + hardware/kicad/power_tree.net. WHY THIS SHAPE A switching converter is noisy; audio op-amps need quiet rails. So the TPS65131 makes RAW +/-18V (efficiently, from USB 5V), then TPS7A4901/TPS7A3001 ultra-low-noise LDOs drop that to CLEAN +/-15V for the analog section. 3V3 (digital) comes from a simple LDO. VERIFIED FROM DATASHEETS (topology + values, not guessed) * TPS65131 (TI SLVS493E): pinout p.3; Typical Application Fig 8-1 (p.11) gives the L/D/C topology; Table 8-2 (p.12) the BOM; FB equations p.13 (Vref=1.213V): Vpos=Vref(1+R1/R2); Vneg=-Vref*R3/R4. Inductors 4.7uH; D1/D2=MBRM120 Schottky. We target ~+/-18V (LDO headroom): R1=1.4M/R2=100k -> +18.2V ; R3=1.5M/R4=100k -> -18.2V. No Q1 battery switch (USB powered) -> BSW left open. PSP/PSN tied LOW = forced PWM (constant-frequency, cleaner in the audio band) -- a deliberate change from the battery-oriented example. * TPS7A4901 / TPS7A3001 (8-pin, identical pinout 1=OUT 2=FB 3=NC 4=GND 5=EN 6=NR/SS 7=DNC 8=IN + PowerPAD): Vout=Vfb(1+Rt/Rb). Vfb approx +1.194V / -1.18V -- CONFIRM the exact Vfb in each elec-char table before finalizing the divider. * AP2112K-3.3 SOT-23-5 (1=VIN 2=GND 3=EN 4=NC 5=VOUT) -- standard pinout, confirm. No SPICE here: a switcher is validated against TI's reference design + bench measurement, not a behavioral op-amp model. Layout (switch nodes, ground return) is critical -- follow the TI EVM/layout guidance. """ import os from skidl import * set_default_tool(KICAD9) P = Pin.types R = Part("Device","R", dest=TEMPLATE, footprint="Resistor_SMD:R_0805_2012Metric") def Cp(v, fp="Capacitor_SMD:C_0805_2012Metric"): return Part("Device","C", value=v, footprint=fp) L = Part("Device","L", dest=TEMPLATE, footprint="Inductor_SMD:L_Wuerth_WE-PD_Typ4_M") DS = Part("Device","D_Schottky", dest=TEMPLATE, footprint="Diode_SMD:D_SMA") FB = Part("Device","L", dest=TEMPLATE, footprint="Inductor_SMD:L_0805_2012Metric") # ferrite bead def mk(name, pins, fp, ref="U"): return Part(name=name, tool=SKIDL, dest=TEMPLATE, ref_prefix=ref, footprint=fp, pins=pins) # ---- nets ---- vbus, p5, p18, n18, p15, n15, p3v3, gnd, vref = (Net("VBUS_5V"), Net("+5V"), Net("+18V"), Net("-18V"), Net("+15V"), Net("-15V"), Net("+3V3"), Net("GND"), Net("VREF")) for n in (vbus, p5, p18, n18, p15, n15, p3v3): n.drive = POWER gnd.drive = POWER sw_boost, sw_inv, fbp, fbn = Net("SW_BOOST"), Net("SW_INV"), Net("FBP"), Net("FBN") innf = Net("INN_F") # RC-filtered +5V to the inverter input # ---- parts ---- 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),Pin(num=8,name="ENP",func=P.INPUT),Pin(num=9,name="PSP",func=P.INPUT), Pin(num=10,name="ENN",func=P.INPUT),Pin(num=11,name="PSN",func=P.INPUT), Pin(num=12,name="NC12",func=P.NOCONNECT),Pin(num=20,name="NC20",func=P.NOCONNECT), Pin(num=13,name="OUTN",func=P.PASSIVE),Pin(num=14,name="OUTN2",func=P.PASSIVE), Pin(num=15,name="VNEG",func=P.INPUT),Pin(num=16,name="FBN",func=P.INPUT),Pin(num=17,name="VREF",func=P.PWROUT), Pin(num=18,name="CN",func=P.PASSIVE),Pin(num=19,name="AGND",func=P.PWRIN),Pin(num=21,name="CP",func=P.PASSIVE), Pin(num=22,name="FBP",func=P.INPUT),Pin(num=23,name="VPOS",func=P.INPUT), Pin(num=25,name="EP",func=P.PWRIN)], "Package_DFN_QFN:QFN-24-1EP_4x4mm_P0.5mm") # LDOs share one pinout (HVSSOP-8 PowerPAD) def ldo(name): return mk(name, [Pin(num=1,name="OUT",func=P.PWROUT),Pin(num=2,name="FB",func=P.INPUT), Pin(num=3,name="NC",func=P.NOCONNECT),Pin(num=4,name="GND",func=P.PWRIN),Pin(num=5,name="EN",func=P.INPUT), Pin(num=6,name="NR",func=P.PASSIVE),Pin(num=7,name="DNC",func=P.NOCONNECT),Pin(num=8,name="IN",func=P.PWRIN), Pin(num=9,name="EP",func=P.PWRIN)], "Package_SO:HVSSOP-8-1EP_3x3mm_P0.65mm") AP2112 = mk("AP2112K-3.3", [Pin(num=1,name="VIN",func=P.PWRIN),Pin(num=2,name="GND",func=P.PWRIN), Pin(num=3,name="EN",func=P.INPUT),Pin(num=4,name="NC",func=P.NOCONNECT),Pin(num=5,name="VOUT",func=P.PWROUT)], "Package_TO_SOT_SMD:SOT-23-5") u7 = TPS65131(ref="U7"); u8 = ldo("TPS7A4901")(ref="U8"); u9 = ldo("TPS7A3001")(ref="U9"); u10 = AP2112(ref="U10") l1, l2 = L(value="4.7uH"), L(value="4.7uH") d1, d2 = DS(value="MBRM120"), DS(value="MBRM120") # ---- USB input: ferrite + bulk ---- fb1 = FB(value="600R@100MHz"); vbus += fb1[1]; fb1[2] += p5 cbulk = Cp("10uF","Capacitor_SMD:C_1206_3216Metric"); p5 += cbulk[1]; cbulk[2] += gnd # ---- TPS65131: control supply + grounds + enables ---- u7["VIN"] += p5; c2 = Cp("4.7uF"); p5 += c2[1]; c2[2] += gnd u7["PGND"] += gnd; u7["PGND2"] += gnd; u7["AGND"] += gnd; u7["EP"] += gnd u7["ENP"] += p5; u7["ENN"] += p5 # enabled u7["PSP"] += gnd; u7["PSN"] += gnd # forced PWM (low audio-band noise) # BSW, NC left unconnected (no battery switch) # boost: +5V -> L1 -> INP(switch); C1 at inductor input; D1 INP->+18V; C4 on +18V c1 = Cp("4.7uF"); p5 += c1[1]; c1[2] += gnd p5 += l1[1]; l1[2] += sw_boost; u7["INP"] += sw_boost; u7["INP2"] += sw_boost d1[2] += sw_boost; d1[1] += p18 # Device D_Schottky: pin1=K, pin2=A -> anode at SW, cathode at +18V c4 = Cp("22uF","Capacitor_SMD:C_1206_3216Metric"); p18 += c4[1]; c4[2] += gnd u7["VPOS"] += p18 # positive feedback divider (+18.2V): R1 +18->FBP (C9 feed-forward), R2 FBP->gnd r1 = R(value="1.4M"); r2 = R(value="100k"); c9 = Cp("6.8pF","Capacitor_SMD:C_0603_1608Metric") p18 += r1[1]; r1[2] += fbp; c9[1] += p18; c9[2] += fbp r2[1] += fbp; r2[2] += gnd; u7["FBP"] += fbp # inverter input: +5V -> R7 -> INN ; C3 filter r7 = R(value="100"); c3 = Cp("100nF"); p5 += r7[1]; r7[2] += innf; c3[1] += innf; c3[2] += gnd u7["INN"] += innf; u7["INN2"] += innf # inverter: OUTN -> L2 -> gnd ; D2 -18V->OUTN ; C5 on -18V u7["OUTN"] += sw_inv; u7["OUTN2"] += sw_inv; l2[1] += sw_inv; l2[2] += gnd d2[1] += sw_inv; d2[2] += n18 # anode at -18V, cathode at SW_INV c5 = Cp("22uF","Capacitor_SMD:C_1206_3216Metric"); n18 += c5[1]; c5[2] += gnd u7["VNEG"] += n18 # negative feedback: R3 -18->FBN (C10 ff), R4 VREF->FBN r3 = R(value="1.5M"); r4 = R(value="100k"); c10 = Cp("7.5pF","Capacitor_SMD:C_0603_1608Metric") n18 += r3[1]; r3[2] += fbn; c10[1] += n18; c10[2] += fbn r4[1] += vref; r4[2] += fbn; u7["FBN"] += fbn # VREF bypass + compensation u7["VREF"] += vref; c8 = Cp("220nF"); vref += c8[1]; c8[2] += gnd c7 = Cp("4.7nF","Capacitor_SMD:C_0603_1608Metric"); u7["CP"] += c7[1]; c7[2] += gnd # boost comp c6 = Cp("10nF"); u7["CN"] += c6[1]; c6[2] += gnd # inverter comp # ---- +15V LDO (TPS7A4901): IN<-+18, OUT->+15, divider, NR cap ---- u8["IN"] += p18; ci8 = Cp("1uF"); p18 += ci8[1]; ci8[2] += gnd u8["OUT"] += p15; co8 = Cp("2.2uF"); p15 += co8[1]; co8[2] += gnd u8["GND"] += gnd; u8["EP"] += gnd; u8["EN"] += p18 rt8 = R(value="116k"); rb8 = R(value="10k"); p15 += rt8[1]; rt8[2] += u8["FB"]; rb8[1] += u8["FB"]; rb8[2] += gnd cnr8 = Cp("10nF"); u8["NR"] += cnr8[1]; cnr8[2] += gnd # ---- -15V LDO (TPS7A3001): IN<--18, OUT->-15, divider, NR cap ---- u9["IN"] += n18; ci9 = Cp("1uF"); n18 += ci9[1]; ci9[2] += gnd u9["OUT"] += n15; co9 = Cp("2.2uF"); n15 += co9[1]; co9[2] += gnd u9["GND"] += gnd; u9["EP"] += gnd; u9["EN"] += n18 rt9 = R(value="117k"); rb9 = R(value="10k"); n15 += rt9[1]; rt9[2] += u9["FB"]; rb9[1] += u9["FB"]; rb9[2] += gnd cnr9 = Cp("10nF"); u9["NR"] += cnr9[1]; cnr9[2] += gnd # ---- 3V3 LDO (AP2112K): +5V -> +3V3 ---- u10["VIN"] += p5; u10["EN"] += p5; u10["GND"] += gnd; u10["VOUT"] += p3v3 ci10 = Cp("1uF"); p5 += ci10[1]; ci10[2] += gnd co10 = Cp("1uF"); p3v3 += co10[1]; co10[2] += gnd ERC() out = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "kicad", "power_tree.net")) generate_netlist(file_=out) print("Power tree netlist ->", out)