Source code for jitxexamples.components.power_switchmode.texas_instruments_TPS62933DRLR

"""
Texas Instruments TPS62933DRLR
===============================

3.8-V to 30-V, 3-A, 200-kHz to 2.2-MHz, low-IQ synchronous buck converter in
SOT-583 package.
"""

import eseries
from jitx import Circuit, Net
from jitx.anchor import Anchor
from jitx.component import Component
from jitx.constraints import Tag, design_constraint
from jitx.feature import Courtyard, Custom, Paste, Silkscreen, Soldermask
from jitx.landpattern import Landpattern, Pad
from jitx.landpattern import PadMapping
from jitx.net import Port
from jitx.common import Power
from jitx.shapes.composites import rectangle
from jitx.shapes.primitive import Arc, ArcPolyline, Circle, Polyline, Text
from jitx.symbol import Direction, Pin, Symbol
from jitx.symbol import SymbolMapping
from jitx.toleranced import Toleranced
from jitx.transform import Transform
from jitx.units import ohm, pct
from jitxlib.parts import (
    Capacitor,
    CapacitorQuery,
    Inductor,
    Resistor,
    ResistorQuery,
)
from jitxlib.voltage_divider import (
    VoltageDividerConstraints,
    voltage_divider_from_constraints,
)


# Option 1: Custom Tags for power nets
[docs] class PowerNetTag(Tag): """Tag for power nets"""
# Option 2: Simple custom tags for specific nets
[docs] class SwTag(Tag): """Switch node net"""
[docs] class BstTag(Tag): """Bootstrap net"""
[docs] class RectangleSmdPad(Pad): shape = rectangle(0.28, 0.68) paste = [ Paste(rectangle(0.382, 0.782)), ] soldermask = [ Soldermask(rectangle(0.382, 0.782)), ]
[docs] class LandpatternSOT_583_8_L2_1_W1_2_P0_50_LS1_6_BR(Landpattern): p = { 1: RectangleSmdPad().at(Transform((0.64, -0.75), 90)), 2: RectangleSmdPad().at(Transform((0.64, -0.25), 90)), 3: RectangleSmdPad().at(Transform((0.64, 0.25), 90)), 4: RectangleSmdPad().at(Transform((0.64, 0.75), 90)), 5: RectangleSmdPad().at(Transform((-0.64, 0.75), 90)), 6: RectangleSmdPad().at(Transform((-0.64, 0.25), 90)), 7: RectangleSmdPad().at(Transform((-0.64, -0.25), 90)), 8: RectangleSmdPad().at(Transform((-0.64, -0.75), 90)), } customlayer = [ Custom(Text(">VALUE", 0.5, Anchor.W).at((-0.75, 1.9756)), name="Fab"), Custom(ArcPolyline(0.06, [Arc((0.8, -1.05), 0.03, 0, -360)]), name="Fab"), Custom(ArcPolyline(0.2, [Arc((0.762, -0.762), 0.1, 0, -360)]), name="Fab"), ] silkscreen = [ Silkscreen(Text(">REF", 0.5, Anchor.W).at((-0.75, 2.9756))), Silkscreen(Polyline(0.254, [(0.508, 1.143), (-0.508, 1.143)])), Silkscreen(Polyline(0.254, [(-0.508, -1.143), (0.508, -1.143)])), Silkscreen(ArcPolyline(0.15, [Arc((0.85, -1.199), 0.075, 0, -360)])), ] courtyard = [ Courtyard(rectangle(1.662, 2.54)), ]
[docs] class SymbolTPS62933DRLR(Symbol): pin_name_size = 0.7874 pad_name_size = 0.7874 FB = Pin((4, 4), 2, Direction.Right) SS = Pin((4, 2), 2, Direction.Right) BST = Pin((4, 0), 2, Direction.Right) SW = Pin((4, -2), 2, Direction.Right) GND = Pin((-6, -2), 2, Direction.Left) VIN = Pin((-6, 0), 2, Direction.Left) EN = Pin((-6, 2), 2, Direction.Left) RT = Pin((-6, 4), 2, Direction.Left) shapes = [ Text(">VALUE", 0.56, Anchor.C).at((0, 6.08741)), Text(">REF", 0.56, Anchor.C).at((0, 6.87481)), rectangle(10, 10).at(-1, 1), Circle(radius=0.3).at(-5, 5), ]
[docs] class TPS62933DRLR(Component): name = "C3200405" description = ( "Step-down type Adjustable 3.8V~30V 3A 0.8V~22V SOT-583 DC-DC Converters ROHS" ) manufacturer = "Texas Instruments" mpn = "TPS62933DRLR" datasheet = "https://wmsc.lcsc.com/wmslc/upload/file/pdf/v2/lcsc/2302220500_Texas-Instruments-TPS62933DRLR_C3200405.pdf" reference_designator_prefix = "U" landpattern = LandpatternSOT_583_8_L2_1_W1_2_P0_50_LS1_6_BR() FB = Port() SS = Port() BST = Port() SW = Port() GND = Port() VIN = Port() EN = Port() RT = Port() symbol = SymbolTPS62933DRLR() mappings = [ SymbolMapping( { FB: symbol.FB, SS: symbol.SS, BST: symbol.BST, SW: symbol.SW, GND: symbol.GND, VIN: symbol.VIN, EN: symbol.EN, RT: symbol.RT, } ), PadMapping( { FB: landpattern.p[8], SS: landpattern.p[7], BST: landpattern.p[6], SW: landpattern.p[5], GND: landpattern.p[4], VIN: landpattern.p[3], EN: landpattern.p[2], RT: landpattern.p[1], } ), ]
[docs] class FeedbackCircuit(Circuit): inp: Port out: Port lo: Port def __init__(self, v_in, v_out, current): self.inp = Port() self.out = Port() self.lo = Port() self.IN = Net(name="IN") self.OUT = Net(name="OUT") self.GND = Net(name="GND") resQuery = ResistorQuery(mounting="smd", case=["0402"], min_stock=10) cons = VoltageDividerConstraints( v_in=v_in, v_out=v_out, current=current, prec_series=[1.00, 0.10], base_query=resQuery, ) self.sol = voltage_divider_from_constraints( cons, name="feedback divider vout -> fb" ) self.IN += self.sol.hi + self.inp self.OUT += self.sol.out + self.out self.GND += self.sol.lo + self.lo
[docs] class TPS62933DRLRCircuit(Circuit): vin = Power() vout = Power() # resQueryDefaults = ResistorQuery( # mounting="smd", case=["0805", "0603", "0402", "0201"] # ) # capQueryDefaults = CapacitorQuery(mounting="smd") # indQueryDefaults = InductorQuery(current_rating=5.0) def __init__( self, output_voltage=3.3, input_voltage=25.0, soft_start=2.0e-3, output_current=3.0, ripple=50.0e-3, debug=False, ): self.nets = [] self.GND = Net(name="GND") self.VOUT = Net(name="VOUT") self.VIN = Net(name="VIN") self.buck = TPS62933DRLR() self.buck.EN.no_connect() self.VIN += self.vin.Vp + self.buck.VIN self.GND += self.buck.GND + self.vin.Vn self.RT_res = Resistor(resistance=0 * ohm).insert( self.buck.RT, self.GND, short_trace=True ) self.fb_vdiv_ckt = FeedbackCircuit( Toleranced.exact(output_voltage), Toleranced.percent(0.800, 3.0), 0.800 / 10.0e3, ) self.VOUT += self.fb_vdiv_ckt.inp + self.vout.Vp self.GND += self.vout.Vn self.nets.append(self.fb_vdiv_ckt.out + self.buck.FB) self.GND += self.fb_vdiv_ckt.lo with CapacitorQuery.refine(type="ceramic", case="0402", tolerance=10.0 * pct): self.css = eseries.find_nearest( eseries.E12, soft_start * 5.5e-6 / 0.8 ) # 2.0 ms soft start per datasheet self.c_ss = Capacitor(capacitance=self.css).insert( self.buck.SS, self.GND, short_trace=True ) # Bootstrap circuit: C4 (100nF) between SW and BST through R4 (0Ω) per schematic self.cbst = Capacitor( capacitance=0.1e-6, rated_voltage=16.0, temperature_coefficient_code="X7R", ) self.rbst = Resistor(resistance=0.0) # R4=0Ω per schematic # Create nets for bootstrap circuit connections self.SW_NODE = Net(name="SW_NODE") self.BST_MID = Net(name="BST_MID") # Connect the bootstrap circuit: SW -> C4 -> R4 -> BST self.SW_NODE += self.buck.SW + self.cbst.p1 # SW pin to bootstrap cap self.BST_MID += self.cbst.p2 + self.rbst.p1 # Bootstrap cap to R4 self.nets.append(self.rbst.p2 + self.buck.BST) # R4 to BST pin fsw = 1.2e6 K = float(40.0 * pct) L = eseries.find_nearest( eseries.E6, output_voltage / input_voltage * (input_voltage - output_voltage) / (fsw * K * output_current), ) # Current calculations ripple_current = ( output_voltage / input_voltage * (input_voltage - output_voltage) / (fsw * L) ) peak_current = output_current + ripple_current / 2.0 rms_current = pow( pow(output_current, 2.0) + pow(ripple_current, 2.0) / 12.0, 0.5 ) # Additional calculations from comments if debug: print( f"Inductor: L: {L}H, RMS: {rms_current}A, Ripple: {ripple_current}A, Peak: {peak_current}A" ) # self.Ind = Inductor(mpn="WPN4020H6R8MT", manufacturer="Sunlord").insert(self.buck.SW, self.VOUT, short_trace=True) self.Ind = Inductor(inductance=L, current_rating=output_current).insert( self.buck.SW, self.VOUT, short_trace=True ) # check for minimum on time and relation to vout/vin ratio min_on_time = output_voltage / (input_voltage * fsw) if min_on_time < 70.0e-9: if debug: print( f"Minimum ON time specification violated: {min_on_time} < 70.0e-9" ) raise ValueError( f"Minimum ON time specification violated: {min_on_time:.2e}s < 70.0ns. " f"Reduce input voltage or increase output voltage." ) # Output capacitance D = output_voltage / input_voltage cout_min = ( ripple_current / (fsw * ripple * K) * ((1.0 - D) * (1.0 + K) + pow(K, 2.0) / 12.0 * (2.0 - D)) ) derated_capacitance = cout_min * 3.0 # Output capacitors out_c = 22.0e-6 with CapacitorQuery.refine( temperature_coefficient_code="X7R", rated_voltage=output_voltage * 2.0 ): min_output_caps = int(derated_capacitance / out_c) + 1 # Create output capacitors (C6, C7 = 22uF each) if debug: print( f"Output Cap: count: {min_output_caps} derated-cap: {derated_capacitance} cap:{out_c}" ) self.output_caps = [] for _ in range(min_output_caps): output_cap = Capacitor(case="0805", capacitance=out_c).insert( self.vout.Vp, self.buck.GND, short_trace=True ) self.output_caps.append(output_cap) # Additional 100nF output capacitor (C8) per schematic self.c_out_100n = Capacitor(case="0402", capacitance=100.0e-9).insert( self.vout.Vp, self.buck.GND, short_trace=True ) # Input capacitance - 10uF per schematic (C1, C2) self.input_caps = [] with CapacitorQuery.refine( temperature_coefficient_code="X7R", rated_voltage=input_voltage * 2.0 ): for _ in range(2): c_inp_reg = Capacitor(capacitance=10.0e-6).insert( self.buck.VIN, self.buck.GND, short_trace=True ) self.input_caps.append(c_inp_reg) # Small input cap self.c_inp_sm = Capacitor(capacitance=0.1e-6).insert( self.buck.VIN, self.buck.GND, short_trace=True ) # Feedforward cap - 10pF (marked DNP in schematic) with CapacitorQuery.refine(case="0402", temperature_coefficient_code="C0G"): self.c_ff = Capacitor(capacitance=10.0e-12).insert( self.fb_vdiv_ckt.inp, self.fb_vdiv_ckt.out ) # Mark as DNP (Do Not Place) per schematic self.c_ff.in_bom = False self.c_ff.schematic_x_out = True self.c_ff.soldered = False # Apply tags to nets # Option 1: PowerNetTag for VIN and VOUT PowerNetTag().assign(self.VIN) PowerNetTag().assign(self.VOUT) # Option 2: Specific tags for SW_NODE and BST_MID SwTag().assign(self.SW_NODE) BstTag().assign(self.BST_MID) # Design rule constraints # 0.5mm clearance for SW_NODE (switch node needs clearance from other nets) self.sw_clearance_rule = design_constraint(SwTag(), True).clearance(0.25) # 0.5mm clearance for BST_MID (bootstrap node needs clearance from other nets) self.bst_clearance_rule = design_constraint(BstTag(), True).clearance(0.25) # 1.0mm trace width for VIN and VOUT power nets self.power_trace_rule = design_constraint(PowerNetTag()).trace_width(0.25)
Device: type[TPS62933DRLRCircuit] = TPS62933DRLRCircuit