feat(schematic): add TPS61088 5V-to-12V boost converter reference schematic

Python generator script produces a KiCad 9 schematic for the TPS61088
boost converter circuit (5V input, 12V/2A output) with feedback divider,
compensation network, bootstrap cap, and input/output filtering.
Includes a nix flake for the build environment.
This commit is contained in:
2026-04-20 13:15:28 -04:00
parent 9f00fe4a9b
commit e3873251b3
3 changed files with 2774 additions and 0 deletions
+890
View File
@@ -0,0 +1,890 @@
#!/usr/bin/env python3
"""
Generate a KiCad 9 schematic for a TPS61088 5V-to-12V boost converter.
Reference design for driving a stepper motor (via A4988) at 12V/2A
from a 5V Raspberry Pi power bus.
All coordinates are multiples of 1.27mm to stay on KiCad's grid.
Output: tps61088_boost.kicad_sch
"""
import uuid
def uid():
return str(uuid.uuid4())
# Grid helper: snap to 1.27mm grid
def g(n):
"""Round to nearest 1.27mm grid point."""
return round(round(n / 1.27) * 1.27, 2)
# ── Symbol library definitions ──────────────────────────────────────
LIB_TPS61088 = """\
(symbol "custom:TPS61088"
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "U"
(at 0 16.51 0)
(effects (font (size 1.27 1.27)))
)
(property "Value" "TPS61088"
(at 0 13.97 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" "Package_DFN_QFN:QFN-20-1EP_3.5x3.5mm_P0.5mm_EP2.1x2.1mm"
(at 0 -20.32 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" "https://www.ti.com/lit/ds/symlink/tps61088.pdf"
(at 0 -22.86 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" "10A Fully-Integrated Synchronous Boost Converter"
(at 0 -25.4 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(symbol "TPS61088_0_1"
(rectangle
(start -10.16 12.7)
(end 10.16 -12.7)
(stroke (width 0.254) (type default))
(fill (type background))
)
)
(symbol "TPS61088_1_1"
(pin power_in line
(at -12.7 10.16 0) (length 2.54)
(name "VIN" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin input line
(at -12.7 5.08 0) (length 2.54)
(name "EN" (effects (font (size 1.27 1.27))))
(number "3" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at -12.7 0 0) (length 2.54)
(name "SS/TR" (effects (font (size 1.27 1.27))))
(number "4" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at -12.7 -5.08 0) (length 2.54)
(name "COMP" (effects (font (size 1.27 1.27))))
(number "5" (effects (font (size 1.27 1.27))))
)
(pin input line
(at -12.7 -10.16 0) (length 2.54)
(name "FB" (effects (font (size 1.27 1.27))))
(number "6" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at 12.7 10.16 180) (length 2.54)
(name "SW" (effects (font (size 1.27 1.27))))
(number "12" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at 12.7 5.08 180) (length 2.54)
(name "BST" (effects (font (size 1.27 1.27))))
(number "11" (effects (font (size 1.27 1.27))))
)
(pin power_out line
(at 12.7 0 180) (length 2.54)
(name "VOUT" (effects (font (size 1.27 1.27))))
(number "9" (effects (font (size 1.27 1.27))))
)
(pin open_collector line
(at 12.7 -5.08 180) (length 2.54)
(name "PGOOD" (effects (font (size 1.27 1.27))))
(number "8" (effects (font (size 1.27 1.27))))
)
(pin power_in line
(at 0 -15.24 90) (length 2.54)
(name "PGND" (effects (font (size 1.27 1.27))))
(number "15" (effects (font (size 1.27 1.27))))
)
(pin power_in line
(at -5.08 -15.24 90) (length 2.54)
(name "AGND" (effects (font (size 1.27 1.27))))
(number "7" (effects (font (size 1.27 1.27))))
)
)
)"""
LIB_CAPACITOR = """\
(symbol "Device:C"
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "C"
(at 1.27 0 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "C"
(at 1.27 -2.54 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" ""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" "~"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" "Unpolarized capacitor"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(symbol "C_0_1"
(polyline
(pts (xy -2.032 -0.762) (xy 2.032 -0.762))
(stroke (width 0.508) (type default))
(fill (type none))
)
(polyline
(pts (xy -2.032 0.762) (xy 2.032 0.762))
(stroke (width 0.508) (type default))
(fill (type none))
)
)
(symbol "C_1_1"
(pin passive line
(at 0 2.54 270) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at 0 -2.54 90) (length 2.54)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)"""
LIB_RESISTOR = """\
(symbol "Device:R"
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "R"
(at 2.032 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "R"
(at 0 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" ""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" "~"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" "Resistor"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(symbol "R_0_1"
(rectangle
(start -1.016 -2.54)
(end 1.016 2.54)
(stroke (width 0.254) (type default))
(fill (type none))
)
)
(symbol "R_1_1"
(pin passive line
(at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)"""
LIB_INDUCTOR = """\
(symbol "Device:L"
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "L"
(at -1.016 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Value" "L"
(at 1.016 0 90)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" ""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" "~"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" "Inductor"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(symbol "L_0_1"
(arc
(start 0 -2.54) (mid 0.6323 -1.905) (end 0 -1.27)
(stroke (width 0) (type default))
(fill (type none))
)
(arc
(start 0 -1.27) (mid 0.6323 -0.635) (end 0 0)
(stroke (width 0) (type default))
(fill (type none))
)
(arc
(start 0 0) (mid 0.6323 0.635) (end 0 1.27)
(stroke (width 0) (type default))
(fill (type none))
)
(arc
(start 0 1.27) (mid 0.6323 1.905) (end 0 2.54)
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "L_1_1"
(pin passive line
(at 0 3.81 270) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
(pin passive line
(at 0 -3.81 90) (length 1.27)
(name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27))))
)
)
)"""
def lib_power(name, shape_text):
return f"""\
(symbol "power:{name}"
(power)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "#PWR"
(at 0 -3.81 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Value" "{name}"
(at 0 3.81 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" ""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" ""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" "Power symbol creates a global label with name \\"{name}\\""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
{shape_text}
)"""
POWER_UP_SHAPE = """\
(symbol "{name}_0_1"
(polyline
(pts (xy -0.762 1.27) (xy 0 2.54))
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts (xy 0 0) (xy 0 2.54))
(stroke (width 0) (type default))
(fill (type none))
)
(polyline
(pts (xy 0 2.54) (xy 0.762 1.27))
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "{name}_1_1"
(pin power_in line
(at 0 0 90) (length 0)
(name "{name}" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
)"""
GND_SHAPE = """\
(symbol "GND_0_1"
(polyline
(pts (xy 0 0) (xy 0 -1.27) (xy 1.27 -1.27) (xy 0 -2.54) (xy -1.27 -1.27) (xy 0 -1.27))
(stroke (width 0) (type default))
(fill (type none))
)
)
(symbol "GND_1_1"
(pin power_in line
(at 0 0 270) (length 0)
(name "GND" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
)"""
LIB_PLUS5V = lib_power("+5V", POWER_UP_SHAPE.format(name="+5V"))
LIB_PLUS12V = lib_power("+12V", POWER_UP_SHAPE.format(name="+12V"))
LIB_GND = lib_power("GND", GND_SHAPE)
LIB_PWR_FLAG = """\
(symbol "power:PWR_FLAG"
(power)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(property "Reference" "#FLG"
(at 0 1.905 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Value" "PWR_FLAG"
(at 0 3.81 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" ""
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" "~"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" "Special symbol for telling ERC where power comes from"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "ki_keywords" "power-flag"
(at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(symbol "PWR_FLAG_0_0"
(pin power_out line
(at 0 0 90) (length 0)
(name "pwr" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27))))
)
)
(symbol "PWR_FLAG_0_1"
(polyline
(pts (xy 0 0) (xy 0 1.27) (xy -1.016 1.905) (xy 0 2.54) (xy 1.016 1.905) (xy 0 1.27))
(stroke (width 0) (type default))
(fill (type none))
)
)
)"""
# ── Schematic element builders ──────────────────────────────────────
class Schematic:
def __init__(self):
self.root_uuid = uid()
self.symbols = []
self.wires = []
self.junctions = []
self.labels = []
self.notes = []
self.no_connects = []
self._pwr_idx = 0
self._flg_idx = 0
def _next_pwr(self):
self._pwr_idx += 1
return f"#PWR{self._pwr_idx:02d}"
def place(self, lib_id, ref, value, x, y, rot=0, pins=None):
"""Place a component. pins is a dict of pin_number -> uuid."""
u = uid()
if pins is None:
pins = {}
pin_str = ""
for pnum in sorted(pins.keys(), key=lambda k: int(k) if k.isdigit() else k):
pin_str += f' (pin "{pnum}"\n (uuid "{pins[pnum]}")\n )\n'
self.symbols.append(f"""\
(symbol
(lib_id "{lib_id}")
(at {x} {y} {rot})
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(uuid "{u}")
(property "Reference" "{ref}"
(at {x + 2.54} {y - 2.54} 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Value" "{value}"
(at {x + 2.54} {y + 2.54} 0)
(effects (font (size 1.27 1.27)) (justify left))
)
(property "Footprint" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
{pin_str}\
(instances
(project ""
(path "/{self.root_uuid}"
(reference "{ref}")
(unit 1)
)
)
)
)""")
def pwr(self, lib_id, value, x, y):
"""Place a power symbol."""
ref = self._next_pwr()
u = uid()
self.symbols.append(f"""\
(symbol
(lib_id "{lib_id}")
(at {x} {y} 0)
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(uuid "{u}")
(property "Reference" "{ref}"
(at {x} {y - 2.54} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Value" "{value}"
(at {x} {y + 3.81} 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(pin "1"
(uuid "{uid()}")
)
(instances
(project ""
(path "/{self.root_uuid}"
(reference "{ref}")
(unit 1)
)
)
)
)""")
def wire(self, x1, y1, x2, y2):
self.wires.append(f"""\
(wire
(pts (xy {x1} {y1}) (xy {x2} {y2}))
(stroke (width 0) (type default))
(uuid "{uid()}")
)""")
def junc(self, x, y):
self.junctions.append(f"""\
(junction
(at {x} {y})
(diameter 0)
(color 0 0 0 0)
(uuid "{uid()}")
)""")
def label(self, x, y, name, rot=0):
self.labels.append(f"""\
(label "{name}"
(at {x} {y} {rot})
(effects (font (size 1.27 1.27)))
(uuid "{uid()}")
)""")
def note(self, x, y, text):
self.notes.append(f"""\
(text "{text}"
(exclude_from_sim no)
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (justify left))
(uuid "{uid()}")
)""")
def pwr_flag(self, x, y):
"""Place a PWR_FLAG to tell ERC this net is externally powered."""
self._flg_idx += 1
ref = f"#FLG{self._flg_idx:02d}"
u = uid()
self.symbols.append(f"""\
(symbol
(lib_id "power:PWR_FLAG")
(at {x} {y} 0)
(unit 1)
(exclude_from_sim no)
(in_bom yes)
(on_board yes)
(dnp no)
(uuid "{u}")
(property "Reference" "{ref}"
(at {x} {y - 2.54} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Value" "PWR_FLAG"
(at {x} {y + 3.81} 0)
(effects (font (size 1.27 1.27)))
)
(property "Footprint" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Datasheet" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(property "Description" ""
(at {x} {y} 0)
(effects (font (size 1.27 1.27)) (hide yes))
)
(pin "1"
(uuid "{uid()}")
)
(instances
(project ""
(path "/{self.root_uuid}"
(reference "{ref}")
(unit 1)
)
)
)
)""")
def no_connect(self, x, y):
self.no_connects.append(f"""\
(no_connect
(at {x} {y})
(uuid "{uid()}")
)""")
def render(self):
sections = []
sections.append(f"""\
(kicad_sch
(version 20250114)
(generator "python_gen")
(generator_version "9.0")
(uuid "{self.root_uuid}")
(paper "A3")
(lib_symbols
{LIB_TPS61088}
{LIB_CAPACITOR}
{LIB_RESISTOR}
{LIB_INDUCTOR}
{LIB_PLUS5V}
{LIB_PLUS12V}
{LIB_GND}
{LIB_PWR_FLAG}
)""")
for j in self.junctions:
sections.append(j)
for nc in self.no_connects:
sections.append(nc)
for w in self.wires:
sections.append(w)
for lb in self.labels:
sections.append(lb)
for n in self.notes:
sections.append(n)
for s in self.symbols:
sections.append(s)
sections.append("""\
(sheet_instances
(path "/"
(page "1")
)
)
(embedded_fonts no)
)""")
return "\n".join(sections)
def generate():
s = Schematic()
# All coordinates in mm, on 1.27mm grid
# IC center
cx, cy = 101.6, 76.2
# ── TPS61088 pin absolute positions ──
# Left side (input is at IC x - 12.7)
pin_vin = (cx - 12.7, cy - 10.16) # VIN
pin_en = (cx - 12.7, cy - 5.08) # EN
pin_ss = (cx - 12.7, cy) # SS/TR
pin_comp = (cx - 12.7, cy + 5.08) # COMP
pin_fb = (cx - 12.7, cy + 10.16) # FB
# Right side
pin_sw = (cx + 12.7, cy - 10.16) # SW
pin_bst = (cx + 12.7, cy - 5.08) # BST
pin_vout = (cx + 12.7, cy) # VOUT
pin_pg = (cx + 12.7, cy + 5.08) # PGOOD
# Bottom
pin_pgnd = (cx, cy + 15.24) # PGND
pin_agnd = (cx - 5.08, cy + 15.24) # AGND
# Place TPS61088
ic_pins = {}
for pn in ["1", "3", "4", "5", "6", "7", "8", "9", "11", "12", "15"]:
ic_pins[pn] = uid()
s.place("custom:TPS61088", "U1", "TPS61088", cx, cy, pins=ic_pins)
# ── VIN rail (horizontal bus at pin_vin y level) ──
vin_rail_y = pin_vin[1] # 66.04
vin_bus_x = cx - 20.32 # 81.28 - left extent of VIN bus
# Wire from VIN pin leftward
s.wire(pin_vin[0], pin_vin[1], vin_bus_x, vin_rail_y)
# EN tied to VIN (always on)
s.wire(pin_en[0], pin_en[1], vin_bus_x, pin_en[1])
s.wire(vin_bus_x, pin_en[1], vin_bus_x, vin_rail_y)
s.junc(vin_bus_x, vin_rail_y)
# +5V power symbol above VIN bus
pwr5v_x = vin_bus_x
pwr5v_y = vin_rail_y - 5.08
s.pwr("power:+5V", "+5V", pwr5v_x, pwr5v_y)
s.wire(pwr5v_x, pwr5v_y, pwr5v_x, vin_rail_y)
# ── Input caps C1, C2 (22µF) ──
# Capacitor pin 1 (top) at y = center - 2.54, pin 2 (bot) at y = center + 2.54
c1_x = vin_bus_x - 7.62
c1_y = vin_rail_y + 7.62 # center of cap
s.place("Device:C", "C1", "22uF", c1_x, c1_y,
pins={"1": uid(), "2": uid()})
# Top of C1 to VIN rail
s.wire(c1_x, c1_y - 2.54, c1_x, vin_rail_y)
s.wire(c1_x, vin_rail_y, vin_bus_x, vin_rail_y)
s.junc(vin_bus_x, vin_rail_y)
# Bottom of C1 to GND
s.pwr("power:GND", "GND", c1_x, c1_y + 5.08)
s.wire(c1_x, c1_y + 2.54, c1_x, c1_y + 5.08)
c2_x = vin_bus_x - 15.24
c2_y = c1_y
s.place("Device:C", "C2", "22uF", c2_x, c2_y,
pins={"1": uid(), "2": uid()})
s.wire(c2_x, c2_y - 2.54, c2_x, vin_rail_y)
s.wire(c2_x, vin_rail_y, c1_x, vin_rail_y)
s.junc(c1_x, vin_rail_y)
s.pwr("power:GND", "GND", c2_x, c2_y + 5.08)
s.wire(c2_x, c2_y + 2.54, c2_x, c2_y + 5.08)
# ── SS/TR cap C3 (22nF) ──
c3_x = vin_bus_x - 7.62
c3_y = pin_ss[1] + 7.62
s.place("Device:C", "C3", "22nF", c3_x, c3_y,
pins={"1": uid(), "2": uid()})
s.wire(pin_ss[0], pin_ss[1], c3_x, pin_ss[1])
s.wire(c3_x, c3_y - 2.54, c3_x, pin_ss[1])
s.pwr("power:GND", "GND", c3_x, c3_y + 5.08)
s.wire(c3_x, c3_y + 2.54, c3_x, c3_y + 5.08)
# ── COMP network: R1 (30.1k) + C4 (47pF) in series ──
r1_x = vin_bus_x - 7.62
# R pin 1 (top) at y = center - 3.81, pin 2 (bot) at y = center + 3.81
r1_y = pin_comp[1] + 5.08
s.place("Device:R", "R1", "30.1k", r1_x, r1_y,
pins={"1": uid(), "2": uid()})
s.wire(pin_comp[0], pin_comp[1], r1_x, pin_comp[1])
s.wire(r1_x, r1_y - 3.81, r1_x, pin_comp[1])
c4_x = r1_x
c4_y = r1_y + 8.89
s.place("Device:C", "C4", "47pF", c4_x, c4_y,
pins={"1": uid(), "2": uid()})
s.wire(r1_x, r1_y + 3.81, c4_x, c4_y - 2.54)
s.pwr("power:GND", "GND", c4_x, c4_y + 5.08)
s.wire(c4_x, c4_y + 2.54, c4_x, c4_y + 5.08)
# ── GND for IC ──
gnd_y = pin_pgnd[1] + 5.08
s.pwr("power:GND", "GND", pin_pgnd[0], gnd_y)
s.wire(pin_pgnd[0], pin_pgnd[1], pin_pgnd[0], gnd_y)
# AGND connects to same GND node
s.wire(pin_agnd[0], pin_agnd[1], pin_agnd[0], gnd_y)
s.wire(pin_agnd[0], gnd_y, pin_pgnd[0], gnd_y)
s.junc(pin_pgnd[0], gnd_y)
# ── Inductor L1 (2.2µH): SW to VOUT rail ──
# Rotated 90°: pin 1 at x = center - 3.81, pin 2 at x = center + 3.81
l1_x = cx + 22.86
l1_y = pin_sw[1]
s.place("Device:L", "L1", "2.2uH", l1_x, l1_y, rot=90,
pins={"1": uid(), "2": uid()})
# SW net to L1 pin 1 (route from junction point, not directly from IC pin)
sw_junc_x = pin_sw[0] + 2.54 # defined again here for clarity
s.wire(sw_junc_x, pin_sw[1], l1_x - 3.81, l1_y)
# VOUT rail node (right of inductor)
vout_rail_x = l1_x + 10.16
vout_rail_y = l1_y
# L1 pin 2 to VOUT rail
s.wire(l1_x + 3.81, l1_y, vout_rail_x, vout_rail_y)
# VOUT pin connects to VOUT rail
s.wire(pin_vout[0], pin_vout[1], vout_rail_x, pin_vout[1])
s.wire(vout_rail_x, pin_vout[1], vout_rail_x, vout_rail_y)
s.junc(vout_rail_x, vout_rail_y)
# ── Bootstrap cap C5 (100nF): BST to SW ──
c5_x = cx + 17.78
c5_y = pin_bst[1]
s.place("Device:C", "C5", "100nF", c5_x, c5_y, rot=90,
pins={"1": uid(), "2": uid()})
# C5 pin 1 (at x+2.54 when rot=90) connects to BST
# When rotated 90°: pin 1 at (cx+2.54, cy), pin 2 at (cx-2.54, cy)
# Actually with rot=90: pin1 goes from 270° direction -> right side
# pin1 at x+2.54, pin2 at x-2.54
s.wire(pin_bst[0], pin_bst[1], c5_x + 2.54, c5_y)
# C5 pin 2 to SW node (junction at SW + 2.54)
sw_junc_x = pin_sw[0] + 2.54
s.wire(c5_x - 2.54, c5_y, sw_junc_x, c5_y)
s.wire(sw_junc_x, c5_y, sw_junc_x, pin_sw[1])
# Connect SW pin to junction
s.wire(pin_sw[0], pin_sw[1], sw_junc_x, pin_sw[1])
s.junc(sw_junc_x, pin_sw[1])
# ── Output caps C6, C7 (22µF) ──
c6_x = vout_rail_x + 7.62
c6_y = vout_rail_y + 7.62
s.place("Device:C", "C6", "22uF", c6_x, c6_y,
pins={"1": uid(), "2": uid()})
s.wire(c6_x, c6_y - 2.54, c6_x, vout_rail_y)
s.wire(vout_rail_x, vout_rail_y, c6_x, vout_rail_y)
s.junc(vout_rail_x, vout_rail_y)
s.pwr("power:GND", "GND", c6_x, c6_y + 5.08)
s.wire(c6_x, c6_y + 2.54, c6_x, c6_y + 5.08)
c7_x = c6_x + 7.62
c7_y = c6_y
s.place("Device:C", "C7", "22uF", c7_x, c7_y,
pins={"1": uid(), "2": uid()})
s.wire(c7_x, c7_y - 2.54, c7_x, vout_rail_y)
s.wire(c6_x, vout_rail_y, c7_x, vout_rail_y)
s.junc(c6_x, vout_rail_y)
s.pwr("power:GND", "GND", c7_x, c7_y + 5.08)
s.wire(c7_x, c7_y + 2.54, c7_x, c7_y + 5.08)
# +12V output symbol
s.pwr("power:+12V", "+12V", c7_x, vout_rail_y - 5.08)
s.wire(c7_x, vout_rail_y, c7_x, vout_rail_y - 5.08)
s.junc(c7_x, vout_rail_y)
# ── Feedback divider: R2 (190k) + R3 (10k) ──
# VOUT -> R2 -> FB_tap -> R3 -> GND
# FB_tap connects to IC FB pin
fb_x = vout_rail_x + 2.54
r2_y = cy + 2.54
s.place("Device:R", "R2", "190k", fb_x, r2_y,
pins={"1": uid(), "2": uid()})
# R2 top to VOUT rail
s.wire(fb_x, r2_y - 3.81, fb_x, vout_rail_y)
s.wire(vout_rail_x, vout_rail_y, fb_x, vout_rail_y)
r3_y = r2_y + 10.16
s.place("Device:R", "R3", "10k", fb_x, r3_y,
pins={"1": uid(), "2": uid()})
# R2 bottom to R3 top (FB tap point)
fb_tap_y = r2_y + 3.81
r3_top_y = r3_y - 3.81
s.wire(fb_x, fb_tap_y, fb_x, r3_top_y)
# FB tap to IC FB pin
s.wire(fb_x, fb_tap_y, pin_fb[0], fb_tap_y)
s.wire(pin_fb[0], fb_tap_y, pin_fb[0], pin_fb[1])
s.junc(fb_x, fb_tap_y)
# R3 bottom to GND
s.pwr("power:GND", "GND", fb_x, r3_y + 6.35)
s.wire(fb_x, r3_y + 3.81, fb_x, r3_y + 6.35)
# ── PGOOD: no connect (optional, user can wire if needed) ──
s.no_connect(pin_pg[0], pin_pg[1])
# ── PWR_FLAG for +5V and GND (tells ERC these nets are externally powered) ──
s.pwr_flag(pwr5v_x + 5.08, vin_rail_y)
s.wire(pwr5v_x + 5.08, vin_rail_y, pwr5v_x, vin_rail_y)
s.junc(pwr5v_x, vin_rail_y)
s.pwr_flag(c1_x + 5.08, c1_y + 5.08)
s.wire(c1_x + 5.08, c1_y + 5.08, c1_x, c1_y + 5.08)
s.junc(c1_x, c1_y + 5.08)
# ── Design notes ──
nx, ny = 40.64, 40.64
s.note(nx, ny, "TPS61088 Boost Converter: 5V to 12V @ 2A")
s.note(nx, ny + 3, "Input: +5V from Raspberry Pi bus")
s.note(nx, ny + 6, "Output: +12V for A4988 stepper driver (VMOT)")
s.note(nx, ny + 11, "Component Notes:")
s.note(nx, ny + 14, "L1: 2.2uH, >=10A saturation, low DCR")
s.note(nx, ny + 17, " (Coilcraft XAL7030-222ME or Wurth 744311220)")
s.note(nx, ny + 20, "C1,C2,C6,C7: 22uF 25V X5R/X7R ceramic")
s.note(nx, ny + 23, "R2/R3: VOUT = 0.6V x (1 + 190k/10k) = 12.06V")
s.note(nx, ny + 26, "R1,C4: Compensation - see TPS61088 datasheet Table 2")
s.note(nx, ny + 31, "PCB Layout Critical:")
s.note(nx, ny + 34, "- Keep SW, BST, inductor loop tight and short")
s.note(nx, ny + 37, "- Input/output caps close to IC pins")
s.note(nx, ny + 40, "- Solid ground plane under IC")
s.note(nx, ny + 43, "- FB trace away from SW/inductor noise")
return s.render()
if __name__ == "__main__":
sch = generate()
outfile = "tps61088_boost.kicad_sch"
with open(outfile, "w") as f:
f.write(sch)
print(f"Generated {outfile}")
print("Open in KiCad Schematic Editor to review.")