refactor(schematic): redesign TPS61088 boost converter layout for clarity

Reorganize component placement with clean left-to-right power flow,
segmented rail wires for proper ERC connections, correct KiCad Device:C
pin positions (±3.81mm), and FB label instead of long crossing wire.
0 ERC errors.
This commit is contained in:
2026-04-20 16:41:00 -04:00
parent e3873251b3
commit c86a05dd2e
2 changed files with 718 additions and 759 deletions
+247 -254
View File
@@ -5,7 +5,7 @@ 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 Reference design for driving a stepper motor (via A4988) at 12V/2A
from a 5V Raspberry Pi power bus. from a 5V Raspberry Pi power bus.
All coordinates are multiples of 1.27mm to stay on KiCad's grid. Layout: clean left-to-right power flow, modeled after TI datasheet Fig 8-1.
Output: tps61088_boost.kicad_sch Output: tps61088_boost.kicad_sch
""" """
@@ -17,12 +17,6 @@ def uid():
return str(uuid.uuid4()) 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 ────────────────────────────────────── # ── Symbol library definitions ──────────────────────────────────────
LIB_TPS61088 = """\ LIB_TPS61088 = """\
@@ -156,12 +150,12 @@ LIB_CAPACITOR = """\
) )
(symbol "C_1_1" (symbol "C_1_1"
(pin passive line (pin passive line
(at 0 2.54 270) (length 2.54) (at 0 3.81 270) (length 2.794)
(name "~" (effects (font (size 1.27 1.27)))) (name "~" (effects (font (size 1.27 1.27))))
(number "1" (effects (font (size 1.27 1.27)))) (number "1" (effects (font (size 1.27 1.27))))
) )
(pin passive line (pin passive line
(at 0 -2.54 90) (length 2.54) (at 0 -3.81 90) (length 2.794)
(name "~" (effects (font (size 1.27 1.27)))) (name "~" (effects (font (size 1.27 1.27))))
(number "2" (effects (font (size 1.27 1.27)))) (number "2" (effects (font (size 1.27 1.27))))
) )
@@ -380,10 +374,6 @@ LIB_PWR_FLAG = """\
(at 0 0 0) (at 0 0 0)
(effects (font (size 1.27 1.27)) (hide yes)) (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" (symbol "PWR_FLAG_0_0"
(pin power_out line (pin power_out line
(at 0 0 90) (length 0) (at 0 0 90) (length 0)
@@ -401,7 +391,7 @@ LIB_PWR_FLAG = """\
)""" )"""
# ── Schematic element builders ────────────────────────────────────── # ── Schematic builder ───────────────────────────────────────────────
class Schematic: class Schematic:
def __init__(self): def __init__(self):
@@ -420,7 +410,6 @@ class Schematic:
return f"#PWR{self._pwr_idx:02d}" return f"#PWR{self._pwr_idx:02d}"
def place(self, lib_id, ref, value, x, y, rot=0, pins=None): 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() u = uid()
if pins is None: if pins is None:
pins = {} pins = {}
@@ -470,7 +459,6 @@ class Schematic:
)""") )""")
def pwr(self, lib_id, value, x, y): def pwr(self, lib_id, value, x, y):
"""Place a power symbol."""
ref = self._next_pwr() ref = self._next_pwr()
u = uid() u = uid()
self.symbols.append(f"""\ self.symbols.append(f"""\
@@ -516,6 +504,53 @@ class Schematic:
) )
)""") )""")
def pwr_flag(self, x, y):
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 wire(self, x1, y1, x2, y2): def wire(self, x1, y1, x2, y2):
self.wires.append(f"""\ self.wires.append(f"""\
(wire (wire
@@ -550,54 +585,6 @@ class Schematic:
(uuid "{uid()}") (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): def no_connect(self, x, y):
self.no_connects.append(f"""\ self.no_connects.append(f"""\
(no_connect (no_connect
@@ -605,6 +592,16 @@ class Schematic:
(uuid "{uid()}") (uuid "{uid()}")
)""") )""")
def cap_down(self, ref, value, x, rail_y):
"""Place a cap hanging down from a rail. Top pin on rail, GND below.
Cap pins at ±3.81 from center (matching KiCad Device:C library)."""
cy = rail_y + 6.35 # cap center (so top pin at cy-3.81 = rail_y+2.54)
self.place("Device:C", ref, value, x, cy,
pins={"1": uid(), "2": uid()})
self.wire(x, cy - 3.81, x, rail_y) # top pin to rail
self.pwr("power:GND", "GND", x, cy + 6.35)
self.wire(x, cy + 3.81, x, cy + 6.35) # bottom pin to GND
def render(self): def render(self):
sections = [] sections = []
sections.append(f"""\ sections.append(f"""\
@@ -634,8 +631,8 @@ class Schematic:
sections.append(lb) sections.append(lb)
for n in self.notes: for n in self.notes:
sections.append(n) sections.append(n)
for s in self.symbols: for sym in self.symbols:
sections.append(s) sections.append(sym)
sections.append("""\ sections.append("""\
(sheet_instances (sheet_instances
(path "/" (path "/"
@@ -647,236 +644,232 @@ class Schematic:
return "\n".join(sections) return "\n".join(sections)
# ── Schematic layout ───────────────────────────────────────────────
def generate(): def generate():
s = Schematic() s = Schematic()
# All coordinates in mm, on 1.27mm grid # ================================================================
# IC center # IC placement — center of schematic
cx, cy = 101.6, 76.2 # ================================================================
cx, cy = 127.0, 76.2
# ── TPS61088 pin absolute positions ── # IC pin absolute positions
# Left side (input is at IC x - 12.7) VIN = (cx - 12.7, cy - 10.16) # (114.3, 66.04)
pin_vin = (cx - 12.7, cy - 10.16) # VIN EN = (cx - 12.7, cy - 5.08) # (114.3, 71.12)
pin_en = (cx - 12.7, cy - 5.08) # EN SS = (cx - 12.7, cy) # (114.3, 76.2)
pin_ss = (cx - 12.7, cy) # SS/TR COMP = (cx - 12.7, cy + 5.08) # (114.3, 81.28)
pin_comp = (cx - 12.7, cy + 5.08) # COMP FB = (cx - 12.7, cy + 10.16) # (114.3, 86.36)
pin_fb = (cx - 12.7, cy + 10.16) # FB SW = (cx + 12.7, cy - 10.16) # (139.7, 66.04)
BST = (cx + 12.7, cy - 5.08) # (139.7, 71.12)
VOUT = (cx + 12.7, cy) # (139.7, 76.2)
PG = (cx + 12.7, cy + 5.08) # (139.7, 81.28)
PGND = (cx, cy + 15.24) # (127.0, 91.44)
AGND = (cx - 5.08, cy + 15.24) # (121.92, 91.44)
# Right side # Place IC
pin_sw = (cx + 12.7, cy - 10.16) # SW ic_pins = {str(i): uid() for i in
pin_bst = (cx + 12.7, cy - 5.08) # BST [1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15]}
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) 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 # INPUT SECTION — left side, +5V rail flowing right into VIN
vin_bus_x = cx - 20.32 # 81.28 - left extent of VIN bus # ================================================================
vin_rail_y = VIN[1] # 66.04 — horizontal rail
# Wire from VIN pin leftward # +5V source (far left)
s.wire(pin_vin[0], pin_vin[1], vin_bus_x, vin_rail_y) pwr5v_x = 86.36
s.pwr("power:+5V", "+5V", pwr5v_x, vin_rail_y - 5.08)
s.wire(pwr5v_x, vin_rail_y - 5.08, pwr5v_x, vin_rail_y)
# EN tied to VIN (always on) # PWR_FLAG on +5V net (tells ERC this is externally supplied)
s.wire(pin_en[0], pin_en[1], vin_bus_x, pin_en[1]) s.pwr_flag(pwr5v_x + 5.08, vin_rail_y)
s.wire(vin_bus_x, pin_en[1], vin_bus_x, vin_rail_y) s.wire(pwr5v_x, vin_rail_y, pwr5v_x + 5.08, vin_rail_y)
s.junc(vin_bus_x, vin_rail_y)
# +5V power symbol above VIN bus # Component X positions (declared before wiring)
pwr5v_x = vin_bus_x c1_x = 91.44
pwr5v_y = vin_rail_y - 5.08 c2_x = 99.06
s.pwr("power:+5V", "+5V", pwr5v_x, pwr5v_y) en_tap_x = 106.68
s.wire(pwr5v_x, pwr5v_y, pwr5v_x, vin_rail_y)
# ── Input caps C1, C2 (22µF) ── # VIN rail: segmented so each T-junction is at a wire endpoint
# Capacitor pin 1 (top) at y = center - 2.54, pin 2 (bot) at y = center + 2.54 s.wire(pwr5v_x, vin_rail_y, c1_x, vin_rail_y)
c1_x = vin_bus_x - 7.62 s.wire(c1_x, vin_rail_y, c2_x, vin_rail_y)
c1_y = vin_rail_y + 7.62 # center of cap s.wire(c2_x, vin_rail_y, en_tap_x, vin_rail_y)
s.place("Device:C", "C1", "22uF", c1_x, c1_y, s.wire(en_tap_x, vin_rail_y, VIN[0], vin_rail_y)
# Input cap C1 (22µF) — hanging down from rail
s.cap_down("C1", "22uF", c1_x, vin_rail_y)
# Input cap C2 (22µF) — second cap, spaced right
s.cap_down("C2", "22uF", c2_x, vin_rail_y)
# PWR_FLAG on GND net (on C1's GND connection)
c1_gnd_y = vin_rail_y + 6.35 + 6.35 # cap center + GND offset
s.pwr_flag(c1_x + 5.08, c1_gnd_y)
s.wire(c1_x, c1_gnd_y, c1_x + 5.08, c1_gnd_y)
s.junc(c1_x, c1_gnd_y)
# EN tied to VIN rail (always enabled)
s.wire(EN[0], EN[1], en_tap_x, EN[1]) # EN pin left to tap point
s.wire(en_tap_x, EN[1], en_tap_x, vin_rail_y) # tap up to rail
# ================================================================
# SOFT-START — C3 hanging below SS pin
# ================================================================
ss_wire_x = 106.68
s.wire(SS[0], SS[1], ss_wire_x, SS[1]) # SS pin left to C3
c3_y = SS[1] + 6.35 # cap center (top pin at c3_y - 3.81)
s.place("Device:C", "C3", "22nF", ss_wire_x, c3_y,
pins={"1": uid(), "2": uid()}) pins={"1": uid(), "2": uid()})
# Top of C1 to VIN rail s.wire(ss_wire_x, SS[1], ss_wire_x, c3_y - 3.81) # wire to cap top
s.wire(c1_x, c1_y - 2.54, c1_x, vin_rail_y) s.pwr("power:GND", "GND", ss_wire_x, c3_y + 6.35)
s.wire(c1_x, vin_rail_y, vin_bus_x, vin_rail_y) s.wire(ss_wire_x, c3_y + 3.81, ss_wire_x, c3_y + 6.35)
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 # COMPENSATION — R1 + C4 series from COMP pin to GND
s.place("Device:C", "C2", "22uF", c2_x, c2_y, # ================================================================
comp_wire_x = 99.06
s.wire(COMP[0], COMP[1], comp_wire_x, COMP[1]) # COMP pin left
# R1 below COMP
r1_y = COMP[1] + 6.35 # 87.63
s.place("Device:R", "R1", "30.1k", comp_wire_x, r1_y,
pins={"1": uid(), "2": uid()}) pins={"1": uid(), "2": uid()})
s.wire(c2_x, c2_y - 2.54, c2_x, vin_rail_y) s.wire(comp_wire_x, COMP[1], comp_wire_x, r1_y - 3.81) # to R1 top
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) ── # C4 below R1
c3_x = vin_bus_x - 7.62 c4_y = r1_y + 10.16 # enough space for R1 bottom pin + gap + C4 top pin
c3_y = pin_ss[1] + 7.62 s.place("Device:C", "C4", "47pF", comp_wire_x, c4_y,
s.place("Device:C", "C3", "22nF", c3_x, c3_y,
pins={"1": uid(), "2": uid()}) pins={"1": uid(), "2": uid()})
s.wire(pin_ss[0], pin_ss[1], c3_x, pin_ss[1]) s.wire(comp_wire_x, r1_y + 3.81, comp_wire_x, c4_y - 3.81) # R1 bot to C4 top
s.wire(c3_x, c3_y - 2.54, c3_x, pin_ss[1]) s.pwr("power:GND", "GND", comp_wire_x, c4_y + 6.35)
s.pwr("power:GND", "GND", c3_x, c3_y + 5.08) s.wire(comp_wire_x, c4_y + 3.81, comp_wire_x, c4_y + 6.35)
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 # IC GROUND — PGND and AGND tied together
# R pin 1 (top) at y = center - 3.81, pin 2 (bot) at y = center + 3.81 # ================================================================
r1_y = pin_comp[1] + 5.08 gnd_y = PGND[1] + 5.08 # 96.52
s.place("Device:R", "R1", "30.1k", r1_x, r1_y, s.pwr("power:GND", "GND", PGND[0], gnd_y)
s.wire(PGND[0], PGND[1], PGND[0], gnd_y)
s.wire(AGND[0], AGND[1], AGND[0], gnd_y)
s.wire(AGND[0], gnd_y, PGND[0], gnd_y)
s.junc(PGND[0], gnd_y)
# ================================================================
# OUTPUT SECTION — SW → L1 → VOUT rail → +12V
# ================================================================
# Inductor L1 (2.2µH, horizontal, between SW and VOUT rail)
# Rotated 90°: pin1 at (x-3.81, y), pin2 at (x+3.81, y)
# (90° CCW rotation: original top pin goes left)
l1_x = 149.86
l1_y = SW[1] # 66.04
l1_pin1 = (l1_x - 3.81, l1_y) # 146.05 — connects to SW net
l1_pin2 = (l1_x + 3.81, l1_y) # 153.67 — connects to VOUT rail
s.place("Device:L", "L1", "2.2uH 10A", l1_x, l1_y, rot=90,
pins={"1": uid(), "2": uid()}) 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 # Bootstrap cap C5 (100nF) — vertical, between SW wire and BST pin
c4_y = r1_y + 8.89 c5_x = 144.78
s.place("Device:C", "C4", "47pF", c4_x, c4_y,
# Wire SW pin → through C5 junction → to L1 pin1 (segmented)
s.wire(SW[0], SW[1], c5_x, SW[1])
s.wire(c5_x, SW[1], l1_pin1[0], l1_pin1[1])
c5_y = SW[1] + 3.81 # center so top pin (c5_y-3.81) lands on SW wire
s.place("Device:C", "C5", "100nF", c5_x, c5_y,
pins={"1": uid(), "2": uid()}) pins={"1": uid(), "2": uid()})
s.wire(r1_x, r1_y + 3.81, c4_x, c4_y - 2.54) # C5 top pin at (c5_x, SW[1]) sits on SW wire
s.pwr("power:GND", "GND", c4_x, c4_y + 5.08) s.junc(c5_x, SW[1])
s.wire(c4_x, c4_y + 2.54, c4_x, c4_y + 5.08) # C5 bottom pin at (c5_x, c5_y+3.81) — wire to BST pin
s.wire(c5_x, c5_y + 3.81, BST[0], BST[1])
# ── GND for IC ── # VOUT rail — vertical line on the right
gnd_y = pin_pgnd[1] + 5.08 vout_rail_x = 162.56
s.pwr("power:GND", "GND", pin_pgnd[0], gnd_y) # L1 output → VOUT rail top
s.wire(pin_pgnd[0], pin_pgnd[1], pin_pgnd[0], gnd_y) s.wire(l1_pin2[0], l1_pin2[1], vout_rail_x, l1_y)
# AGND connects to same GND node # VOUT pin → VOUT rail bottom
s.wire(pin_agnd[0], pin_agnd[1], pin_agnd[0], gnd_y) s.wire(VOUT[0], VOUT[1], vout_rail_x, VOUT[1])
s.wire(pin_agnd[0], gnd_y, pin_pgnd[0], gnd_y) # Connect top to bottom
s.junc(pin_pgnd[0], gnd_y) s.wire(vout_rail_x, l1_y, vout_rail_x, VOUT[1])
# ── Inductor L1 (2.2µH): SW to VOUT rail ── # Output caps and +12V — segmented output rail
# Rotated 90°: pin 1 at x = center - 3.81, pin 2 at x = center + 3.81 c6_x = 167.64
l1_x = cx + 22.86 c7_x = 175.26
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) # Output rail segments
vout_rail_x = l1_x + 10.16 s.wire(vout_rail_x, l1_y, c6_x, l1_y)
vout_rail_y = l1_y s.wire(c6_x, l1_y, c7_x, 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 # Output cap C6 (22µF)
s.wire(pin_vout[0], pin_vout[1], vout_rail_x, pin_vout[1]) s.cap_down("C6", "22uF", c6_x, l1_y)
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 ── # Output cap C7 (22µF)
c5_x = cx + 17.78 s.cap_down("C7", "22uF", c7_x, l1_y)
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 # +12V output symbol
s.pwr("power:+12V", "+12V", c7_x, vout_rail_y - 5.08) s.pwr("power:+12V", "+12V", c7_x, l1_y - 5.08)
s.wire(c7_x, vout_rail_y, c7_x, vout_rail_y - 5.08) s.wire(c7_x, l1_y, c7_x, l1_y - 5.08)
s.junc(c7_x, vout_rail_y) s.junc(c7_x, l1_y)
# ── Feedback divider: R2 (190k) + R3 (10k) ── # ================================================================
# VOUT -> R2 -> FB_tap -> R3 -> GND # FEEDBACK DIVIDER — R2 (190k) / R3 (10k) sets VOUT = 12V
# FB_tap connects to IC FB pin # Connected to FB pin via label (avoids long crossing wire)
fb_x = vout_rail_x + 2.54 # ================================================================
r2_y = cy + 2.54 fb_x = vout_rail_x # 162.56 — hangs off VOUT rail
# R2 (top resistor, VOUT to FB tap)
r2_y = VOUT[1] + 6.35 # 82.55
s.place("Device:R", "R2", "190k", fb_x, r2_y, s.place("Device:R", "R2", "190k", fb_x, r2_y,
pins={"1": uid(), "2": uid()}) pins={"1": uid(), "2": uid()})
# R2 top to VOUT rail s.wire(fb_x, VOUT[1], fb_x, r2_y - 3.81) # VOUT rail down to R2 top
s.wire(fb_x, r2_y - 3.81, fb_x, vout_rail_y) s.junc(fb_x, VOUT[1]) # T-junction on VOUT vertical rail
s.wire(vout_rail_x, vout_rail_y, fb_x, vout_rail_y)
r3_y = r2_y + 10.16 # R3 (bottom resistor, FB tap to GND)
r3_y = r2_y + 10.16 # 92.71
s.place("Device:R", "R3", "10k", fb_x, r3_y, s.place("Device:R", "R3", "10k", fb_x, r3_y,
pins={"1": uid(), "2": uid()}) pins={"1": uid(), "2": uid()})
# R2 bottom to R3 top (FB tap point) s.wire(fb_x, r2_y + 3.81, fb_x, r3_y - 3.81) # R2 bottom to R3 top
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 # FB tap label at divider midpoint
s.wire(fb_x, fb_tap_y, pin_fb[0], fb_tap_y) fb_tap_y = r2_y + 3.81 # 86.36 — R2 bottom pin
s.wire(pin_fb[0], fb_tap_y, pin_fb[0], pin_fb[1]) s.wire(fb_x, fb_tap_y, fb_x + 5.08, fb_tap_y)
s.label(fb_x + 5.08, fb_tap_y, "FB")
s.junc(fb_x, fb_tap_y) s.junc(fb_x, fb_tap_y)
# FB label at IC pin (connects by name)
s.wire(FB[0], FB[1], FB[0] - 5.08, FB[1])
s.label(FB[0] - 5.08, FB[1], "FB", rot=180)
# R3 bottom to GND # R3 bottom to GND
s.pwr("power:GND", "GND", fb_x, r3_y + 6.35) 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) 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]) # PGOOD — no connect (optional, wire if monitoring needed)
# ================================================================
s.no_connect(PG[0], 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) # DESIGN NOTES — below the circuit, well separated
s.wire(pwr5v_x + 5.08, vin_rail_y, pwr5v_x, vin_rail_y) # ================================================================
s.junc(pwr5v_x, vin_rail_y) nx = 78.74
ny = 116.84
s.pwr_flag(c1_x + 5.08, c1_y + 5.08) s.note(nx, ny, "TPS61088 Boost Converter Reference Design")
s.wire(c1_x + 5.08, c1_y + 5.08, c1_x, c1_y + 5.08) s.note(nx, ny + 5, "Input: +5V from Raspberry Pi 5V bus")
s.junc(c1_x, c1_y + 5.08) s.note(nx, ny + 8, "Output: +12V @ 2A for A4988 stepper driver (VMOT)")
s.note(nx, ny + 13, "VOUT = 0.6V x (1 + R2/R3) = 0.6 x (1 + 190k/10k) = 12.06V")
# ── Design notes ── s.note(nx, ny + 18, "Component Selection:")
nx, ny = 40.64, 40.64 s.note(nx, ny + 21, " L1: 2.2uH, >=10A Isat, low DCR (Coilcraft XAL7030-222ME)")
s.note(nx, ny, "TPS61088 Boost Converter: 5V to 12V @ 2A") s.note(nx, ny + 24, " C1-C2, C6-C7: 22uF 25V X5R ceramic (input & output)")
s.note(nx, ny + 3, "Input: +5V from Raspberry Pi bus") s.note(nx, ny + 27, " C5: 100nF bootstrap (ceramic)")
s.note(nx, ny + 6, "Output: +12V for A4988 stepper driver (VMOT)") s.note(nx, ny + 30, " C3: 22nF soft-start (sets startup ramp time)")
s.note(nx, ny + 11, "Component Notes:") s.note(nx, ny + 33, " R1, C4: Loop compensation (see TPS61088 datasheet Table 2)")
s.note(nx, ny + 14, "L1: 2.2uH, >=10A saturation, low DCR") s.note(nx, ny + 38, "PCB Layout Notes:")
s.note(nx, ny + 17, " (Coilcraft XAL7030-222ME or Wurth 744311220)") s.note(nx, ny + 41, " - Keep SW node, BST cap, and inductor loop as tight as possible")
s.note(nx, ny + 20, "C1,C2,C6,C7: 22uF 25V X5R/X7R ceramic") s.note(nx, ny + 44, " - Place input and output caps directly adjacent to IC pins")
s.note(nx, ny + 23, "R2/R3: VOUT = 0.6V x (1 + 190k/10k) = 12.06V") s.note(nx, ny + 47, " - Solid ground plane under IC with thermal vias to EP pad")
s.note(nx, ny + 26, "R1,C4: Compensation - see TPS61088 datasheet Table 2") s.note(nx, ny + 50, " - Route FB trace far from SW/inductor (sensitive to noise)")
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() return s.render()
+471 -505
View File
File diff suppressed because it is too large Load Diff