diff --git a/edg/abstract_parts/OpampCircuits.py b/edg/abstract_parts/OpampCircuits.py
index 2b0a7a4d9..1cf848e41 100644
--- a/edg/abstract_parts/OpampCircuits.py
+++ b/edg/abstract_parts/OpampCircuits.py
@@ -363,8 +363,9 @@ class IntegratorInverting(OpampApplication, KiCadSchematicBlock, KiCadImportable
From https://en.wikipedia.org/wiki/Operational_amplifier_applications#Inverting_integrator:
Vout = - 1/RC * int(Vin) (integrating over time)
- Series is lower and tolerance is higher because there's a cap involved
- TODO - separate series for cap, and series and tolerance by decade?
+ 1/RC (in units 1/s or Hz) is the integrator gain.
+ One intuitive interpretation is, for a DC input, one period of the frequency
+ is the time it takes for the output voltage to change by the input voltage.
"""
@override
@@ -387,7 +388,7 @@ def symbol_pinning(self, symbol_name: str) -> Dict[str, BasePort]:
}
return mapping[symbol_name]
- def __init__(self, factor: RangeLike, capacitance: RangeLike, *, series: IntLike = 6, tolerance: FloatLike = 0.05):
+ def __init__(self, gain: RangeLike, capacitance: RangeLike):
super().__init__()
self.amp = self.Block(Opamp())
@@ -398,23 +399,23 @@ def __init__(self, factor: RangeLike, capacitance: RangeLike, *, series: IntLike
self.output = self.Port(AnalogSource.empty())
self.reference = self.Port(AnalogSink.empty()) # negative reference for the input and output signals
- self.factor = self.ArgParameter(factor) # output scale factor, 1/RC in units of 1/s
+ self.gain = self.ArgParameter(gain) # 1/RC in units of 1/s
self.capacitance = self.ArgParameter(capacitance)
- self.actual_factor = self.Parameter(RangeExpr())
+ self.actual_gain = self.Parameter(RangeExpr())
@override
def contents(self) -> None:
super().contents()
self.description = DescriptionString(
- "factor: ",
- DescriptionString.FormatUnits(self.actual_factor, ""),
+ "gain: ",
+ DescriptionString.FormatUnits(self.actual_gain, ""),
" of spec: ",
- DescriptionString.FormatUnits(self.factor, ""),
+ DescriptionString.FormatUnits(self.gain, ""),
)
- self.r = self.Block(Resistor((1 / self.factor).shrink_multiply(1 / self.capacitance)))
+ self.r = self.Block(Resistor((1 / self.gain).shrink_multiply(1 / self.capacitance)))
self.c = self.Block(Capacitor(capacitance=self.capacitance, voltage=self.output.link().voltage))
self.import_kicad(
@@ -427,7 +428,7 @@ def contents(self) -> None:
},
)
- self.assign(self.actual_factor, 1 / self.r.actual_resistance / self.c.actual_capacitance)
+ self.assign(self.actual_gain, 1 / self.r.actual_resistance / self.c.actual_capacitance)
class SummingAmplifier(OpampApplication):
diff --git a/edg/abstract_parts/PowerCircuits.py b/edg/abstract_parts/PowerCircuits.py
index b77ce7c8a..d72ea6850 100644
--- a/edg/abstract_parts/PowerCircuits.py
+++ b/edg/abstract_parts/PowerCircuits.py
@@ -237,12 +237,21 @@ def contents(self) -> None:
voltage=(0 * Volt(tol=0)).hull(self.pwr_in.link().voltage),
)
)
+
+ # because PMOS is source-referenced from vin, calculate the Vgs from GND by subtracting from Vin
+ # however, we can't calculate a fixed Vgs range for all Vin, since it would be overly restrictive,
+ # so instead we calculate ratios at the Vin corners, then take the intersection of the ratios
+ # this may generate intermediate negative ratios, but the intersection should clamp those
+ # for reasonable target_vgs
+ vgs_ratio_low = (self.pwr_in.link().voltage.lower() - self.target_vgs) / self.pwr_in.link().voltage.lower()
+ vgs_ratio_hi = (self.pwr_in.link().voltage.upper() - self.target_vgs) / self.pwr_in.link().voltage.upper()
+
# dV/dt over a capacitor is I / C => I = Cgd * dV/dt
# then calculate to get the target I: Vgs,th = I * Reff => Reff = Vgs,th / I = Vgs,th / (Cgd * dV/dt)
# we assume Vgs,th is exact, and only contributing sources come from elsewhere
self.div = self.Block(
ResistiveDivider(
- ratio=self.target_vgs.shrink_multiply(1 / self.pwr_in.link().voltage),
+ ratio=vgs_ratio_low.intersect(vgs_ratio_hi),
impedance=(1 / self.target_ramp).shrink_multiply(
self.drv.actual_gate_drive.lower() / (self.cap_gd.actual_capacitance)
),
diff --git a/examples/UsbSourceMeasure/SourceMeasureControl.kicad_sch b/examples/UsbSourceMeasure/SourceMeasureControl.kicad_sch
index 96b9cba45..b3a67537e 100644
--- a/examples/UsbSourceMeasure/SourceMeasureControl.kicad_sch
+++ b/examples/UsbSourceMeasure/SourceMeasureControl.kicad_sch
@@ -6838,7 +6838,7 @@
(hide yes)
)
)
- (property "Value2" "factor=1/4.7e-6*Ratio(tol=0.15),"
+ (property "Value2" "gain=100/4.7*kHertz(tol=0.15),"
(at 113.03 101.346 0)
(effects
(font
@@ -6846,7 +6846,7 @@
)
)
)
- (property "Value3" "capacitance=1*nFarad(tol=0.1))"
+ (property "Value3" "capacitance=10*nFarad(tol=0.1))"
(at 113.03 103.632 0)
(effects
(font
@@ -9786,7 +9786,7 @@
(hide yes)
)
)
- (property "Value2" "ratio=10*Ratio(tol=0.05))"
+ (property "Value2" "ratio=5*Ratio(tol=0.05))"
(at 237.49 128.016 0)
(effects
(font
diff --git a/examples/UsbSourceMeasure/UsbSourceMeasure.net b/examples/UsbSourceMeasure/UsbSourceMeasure.net
index 78a9fdff8..f9ae6d627 100644
--- a/examples/UsbSourceMeasure/UsbSourceMeasure.net
+++ b/examples/UsbSourceMeasure/UsbSourceMeasure.net
@@ -176,8 +176,8 @@
(property (name "edg_path") (value "ramp.div.top_res"))
(property (name "edg_short_path") (value "ramp.div.top_res"))
(property (name "edg_refdes") (value "R2"))
- (property (name "edg_part") (value "0603WAF2203T5E (UNI-ROYAL(Uniroyal Elec))"))
- (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 220kΩ 0603 Chip Resistor - Surface Mount ROHS"))
+ (property (name "edg_part") (value "0603WAF6803T5E (UNI-ROYAL(Uniroyal Elec))"))
+ (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 680kΩ 0603 Chip Resistor - Surface Mount ROHS"))
(sheetpath (names "/ramp/div/") (tstamps "/043901b1/02770144/"))
(tstamps "0c0c02fd"))
(comp (ref "R3")
@@ -188,8 +188,8 @@
(property (name "edg_path") (value "ramp.div.bottom_res"))
(property (name "edg_short_path") (value "ramp.div.bottom_res"))
(property (name "edg_refdes") (value "R3"))
- (property (name "edg_part") (value "0603WAF6803T5E (UNI-ROYAL(Uniroyal Elec))"))
- (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 680kΩ 0603 Chip Resistor - Surface Mount ROHS"))
+ (property (name "edg_part") (value "0603WAF2203T5E (UNI-ROYAL(Uniroyal Elec))"))
+ (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 220kΩ 0603 Chip Resistor - Surface Mount ROHS"))
(sheetpath (names "/ramp/div/") (tstamps "/043901b1/02770144/"))
(tstamps "175b043f"))
(comp (ref "Q2")
@@ -1628,8 +1628,8 @@
(property (name "edg_path") (value "control.int.c"))
(property (name "edg_short_path") (value "control.int.c"))
(property (name "edg_refdes") (value "C52"))
- (property (name "edg_part") (value "CL10B102KB8NNNC (Samsung Electro-Mechanics)"))
- (property (name "edg_value") (value "50V 1nF X7R ±10% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS"))
+ (property (name "edg_part") (value "0603B103K500NT (FH(Guangdong Fenghua Advanced Tech))"))
+ (property (name "edg_value") (value "50V 10nF X7R ±10% 0603 Multilayer Ceramic Capacitors MLCC - SMD/SMT ROHS"))
(sheetpath (names "/control/int/") (tstamps "/0bec0302/028e014c/"))
(tstamps "00640064"))
(comp (ref "R35")
@@ -2180,8 +2180,8 @@
(property (name "edg_path") (value "control.imeas.rg"))
(property (name "edg_short_path") (value "control.imeas.rg"))
(property (name "edg_refdes") (value "R54"))
- (property (name "edg_part") (value "0603WAF5601T5E (UNI-ROYAL(Uniroyal Elec))"))
- (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 5.6kΩ 0603 Chip Resistor - Surface Mount ROHS"))
+ (property (name "edg_part") (value "0603WAF1202T5E (UNI-ROYAL(Uniroyal Elec))"))
+ (property (name "edg_value") (value "±1% 1/10W Thick Film Resistors 75V ±100ppm/℃ -55℃~+155℃ 12kΩ 0603 Chip Resistor - Surface Mount ROHS"))
(sheetpath (names "/control/imeas/") (tstamps "/0bec0302/062a0210/"))
(tstamps "014d00da"))
(comp (ref "Q9")
diff --git a/examples/test_usb_source_measure.py b/examples/test_usb_source_measure.py
index ce1085136..77f86a3b8 100644
--- a/examples/test_usb_source_measure.py
+++ b/examples/test_usb_source_measure.py
@@ -547,7 +547,7 @@ def contents(self) -> None:
(self.ramp, self.cap_conv), _ = self.chain(
self.vusb,
imp.Block(
- RampLimiter(target_vgs=(3.7, 19) * Volt)
+ RampLimiter(target_vgs=(3.5, 17.5) * Volt)
), # avoid excess capacitance on VBus which may cause the PD source to reset
imp.Block(DecouplingCapacitor(47 * uFarad(tol=0.25))),
)