#!/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.")