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:
+247
-254
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user