Skip to content

Commit 62c42e5

Browse files
authored
SMU3.1 fixes (#443)
ducky64/usb-source-measure#7 - slow down control loop (reduce opamp integrator gain), in particular to get it slower than the current sense RC filter. Also renames 'factor' to 'gain' and adds an intuitive meaning of the term in the docs. ducky64/usb-source-measure#8 - reduce current sense gain to 5x to allow 3A at full scale ducky64/usb-source-measure#1 - fix ramp at low voltages, previously it was calculating the divider for gate voltage relative to ground, whereas for PMOS it needs to be gate voltage relative to source = Vin. These have been tested with board component replacements and work.
1 parent 2f01e33 commit 62c42e5

File tree

5 files changed

+33
-23
lines changed

5 files changed

+33
-23
lines changed

edg/abstract_parts/OpampCircuits.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,9 @@ class IntegratorInverting(OpampApplication, KiCadSchematicBlock, KiCadImportable
363363
From https://en.wikipedia.org/wiki/Operational_amplifier_applications#Inverting_integrator:
364364
Vout = - 1/RC * int(Vin) (integrating over time)
365365
366-
Series is lower and tolerance is higher because there's a cap involved
367-
TODO - separate series for cap, and series and tolerance by decade?
366+
1/RC (in units 1/s or Hz) is the integrator gain.
367+
One intuitive interpretation is, for a DC input, one period of the frequency
368+
is the time it takes for the output voltage to change by the input voltage.
368369
"""
369370

370371
@override
@@ -387,7 +388,7 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
387388
}
388389
return mapping[symbol_name]
389390

390-
def __init__(self, factor: RangeLike, capacitance: RangeLike, *, series: IntLike = 6, tolerance: FloatLike = 0.05):
391+
def __init__(self, gain: RangeLike, capacitance: RangeLike):
391392
super().__init__()
392393

393394
self.amp = self.Block(Opamp())
@@ -398,23 +399,23 @@ def __init__(self, factor: RangeLike, capacitance: RangeLike, *, series: IntLike
398399
self.output = self.Port(AnalogSource.empty())
399400
self.reference = self.Port(AnalogSink.empty()) # negative reference for the input and output signals
400401

401-
self.factor = self.ArgParameter(factor) # output scale factor, 1/RC in units of 1/s
402+
self.gain = self.ArgParameter(gain) # 1/RC in units of 1/s
402403
self.capacitance = self.ArgParameter(capacitance)
403404

404-
self.actual_factor = self.Parameter(RangeExpr())
405+
self.actual_gain = self.Parameter(RangeExpr())
405406

406407
@override
407408
def contents(self) -> None:
408409
super().contents()
409410

410411
self.description = DescriptionString(
411-
"<b>factor:</b> ",
412-
DescriptionString.FormatUnits(self.actual_factor, ""),
412+
"<b>gain:</b> ",
413+
DescriptionString.FormatUnits(self.actual_gain, ""),
413414
" <b>of spec:</b> ",
414-
DescriptionString.FormatUnits(self.factor, ""),
415+
DescriptionString.FormatUnits(self.gain, ""),
415416
)
416417

417-
self.r = self.Block(Resistor((1 / self.factor).shrink_multiply(1 / self.capacitance)))
418+
self.r = self.Block(Resistor((1 / self.gain).shrink_multiply(1 / self.capacitance)))
418419
self.c = self.Block(Capacitor(capacitance=self.capacitance, voltage=self.output.link().voltage))
419420

420421
self.import_kicad(
@@ -427,7 +428,7 @@ def contents(self) -> None:
427428
},
428429
)
429430

430-
self.assign(self.actual_factor, 1 / self.r.actual_resistance / self.c.actual_capacitance)
431+
self.assign(self.actual_gain, 1 / self.r.actual_resistance / self.c.actual_capacitance)
431432

432433

433434
class SummingAmplifier(OpampApplication):

edg/abstract_parts/PowerCircuits.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,21 @@ def contents(self) -> None:
237237
voltage=(0 * Volt(tol=0)).hull(self.pwr_in.link().voltage),
238238
)
239239
)
240+
241+
# because PMOS is source-referenced from vin, calculate the Vgs from GND by subtracting from Vin
242+
# however, we can't calculate a fixed Vgs range for all Vin, since it would be overly restrictive,
243+
# so instead we calculate ratios at the Vin corners, then take the intersection of the ratios
244+
# this may generate intermediate negative ratios, but the intersection should clamp those
245+
# for reasonable target_vgs
246+
vgs_ratio_low = (self.pwr_in.link().voltage.lower() - self.target_vgs) / self.pwr_in.link().voltage.lower()
247+
vgs_ratio_hi = (self.pwr_in.link().voltage.upper() - self.target_vgs) / self.pwr_in.link().voltage.upper()
248+
240249
# dV/dt over a capacitor is I / C => I = Cgd * dV/dt
241250
# then calculate to get the target I: Vgs,th = I * Reff => Reff = Vgs,th / I = Vgs,th / (Cgd * dV/dt)
242251
# we assume Vgs,th is exact, and only contributing sources come from elsewhere
243252
self.div = self.Block(
244253
ResistiveDivider(
245-
ratio=self.target_vgs.shrink_multiply(1 / self.pwr_in.link().voltage),
254+
ratio=vgs_ratio_low.intersect(vgs_ratio_hi),
246255
impedance=(1 / self.target_ramp).shrink_multiply(
247256
self.drv.actual_gate_drive.lower() / (self.cap_gd.actual_capacitance)
248257
),

examples/UsbSourceMeasure/SourceMeasureControl.kicad_sch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6838,15 +6838,15 @@
68386838
(hide yes)
68396839
)
68406840
)
6841-
(property "Value2" "factor=1/4.7e-6*Ratio(tol=0.15),"
6841+
(property "Value2" "gain=100/4.7*kHertz(tol=0.15),"
68426842
(at 113.03 101.346 0)
68436843
(effects
68446844
(font
68456845
(size 1.27 1.27)
68466846
)
68476847
)
68486848
)
6849-
(property "Value3" "capacitance=1*nFarad(tol=0.1))"
6849+
(property "Value3" "capacitance=10*nFarad(tol=0.1))"
68506850
(at 113.03 103.632 0)
68516851
(effects
68526852
(font
@@ -9786,7 +9786,7 @@
97869786
(hide yes)
97879787
)
97889788
)
9789-
(property "Value2" "ratio=10*Ratio(tol=0.05))"
9789+
(property "Value2" "ratio=5*Ratio(tol=0.05))"
97909790
(at 237.49 128.016 0)
97919791
(effects
97929792
(font

examples/UsbSourceMeasure/UsbSourceMeasure.net

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@
176176
(property (name "edg_path") (value "ramp.div.top_res"))
177177
(property (name "edg_short_path") (value "ramp.div.top_res"))
178178
(property (name "edg_refdes") (value "R2"))
179-
(property (name "edg_part") (value "0603WAF2203T5E (UNI-ROYAL(Uniroyal Elec))"))
180-
(property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 220kΩ 0603 Chip Resistor - Surface Mount ROHS"))
179+
(property (name "edg_part") (value "0603WAF6803T5E (UNI-ROYAL(Uniroyal Elec))"))
180+
(property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 680kΩ 0603 Chip Resistor - Surface Mount ROHS"))
181181
(sheetpath (names "/ramp/div/") (tstamps "/043901b1/02770144/"))
182182
(tstamps "0c0c02fd"))
183183
(comp (ref "R3")
@@ -188,8 +188,8 @@
188188
(property (name "edg_path") (value "ramp.div.bottom_res"))
189189
(property (name "edg_short_path") (value "ramp.div.bottom_res"))
190190
(property (name "edg_refdes") (value "R3"))
191-
(property (name "edg_part") (value "0603WAF6803T5E (UNI-ROYAL(Uniroyal Elec))"))
192-
(property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 680kΩ 0603 Chip Resistor - Surface Mount ROHS"))
191+
(property (name "edg_part") (value "0603WAF2203T5E (UNI-ROYAL(Uniroyal Elec))"))
192+
(property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 220kΩ 0603 Chip Resistor - Surface Mount ROHS"))
193193
(sheetpath (names "/ramp/div/") (tstamps "/043901b1/02770144/"))
194194
(tstamps "175b043f"))
195195
(comp (ref "Q2")
@@ -1628,8 +1628,8 @@
16281628
(property (name "edg_path") (value "control.int.c"))
16291629
(property (name "edg_short_path") (value "control.int.c"))
16301630
(property (name "edg_refdes") (value "C52"))
1631-
(property (name "edg_part") (value "CL10B102KB8NNNC (Samsung Electro-Mechanics)"))
1632-
(property (name "edg_value") (value "50V 1nF X7R ±10% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS"))
1631+
(property (name "edg_part") (value "0603B103K500NT (FH(Guangdong Fenghua Advanced Tech))"))
1632+
(property (name "edg_value") (value "50V 10nF X7R ±10% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS"))
16331633
(sheetpath (names "/control/int/") (tstamps "/0bec0302/028e014c/"))
16341634
(tstamps "00640064"))
16351635
(comp (ref "R35")
@@ -2180,8 +2180,8 @@
21802180
(property (name "edg_path") (value "control.imeas.rg"))
21812181
(property (name "edg_short_path") (value "control.imeas.rg"))
21822182
(property (name "edg_refdes") (value "R54"))
2183-
(property (name "edg_part") (value "0603WAF5601T5E (UNI-ROYAL(Uniroyal Elec))"))
2184-
(property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 5.6kΩ 0603 Chip Resistor - Surface Mount ROHS"))
2183+
(property (name "edg_part") (value "0603WAF1202T5E (UNI-ROYAL(Uniroyal Elec))"))
2184+
(property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 12kΩ 0603 Chip Resistor - Surface Mount ROHS"))
21852185
(sheetpath (names "/control/imeas/") (tstamps "/0bec0302/062a0210/"))
21862186
(tstamps "014d00da"))
21872187
(comp (ref "Q9")

examples/test_usb_source_measure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ def contents(self) -> None:
547547
(self.ramp, self.cap_conv), _ = self.chain(
548548
self.vusb,
549549
imp.Block(
550-
RampLimiter(target_vgs=(3.7, 19) * Volt)
550+
RampLimiter(target_vgs=(3.5, 17.5) * Volt)
551551
), # avoid excess capacitance on VBus which may cause the PD source to reset
552552
imp.Block(DecouplingCapacitor(47 * uFarad(tol=0.25))),
553553
)

0 commit comments

Comments
 (0)