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:
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
description = "KiCad schematic generator for TPS61088 boost converter";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs }:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells.${system}.default = pkgs.mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.python313
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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.")
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user