I am trying to recreate the Bode plot and phase margin calculations of ST Application Note 2823 "Current source for LED driving based on the L5973AD".
- The analysis there (p17) gives: FC as 36 kHz and ζM as 84°
- My calculations produce: FC as 36110.825275 and ζM as 82.552834°
My question: 1) have I done this correctly? 2) How do I evaluate if these values are "good"?
This is the circuit (p7), but understood as L5973AD (datasheet), with fsw of 500 kHz.

(image from application note given above)
Following the main formula (eq. 9) I'm building it up in SymPy and substituting values right at the end.
$$ G_{loop} = A_{ota} \cdot G_{pwm} \cdot G_{pwr} \cdot \alpha_{led} \tag{9} $$
We do each part: $$ A_{ota} = \frac{G_{m}}{C_{5} \cdot s + C_{EA} \cdot s + \frac{1}{R_{5} + \frac{1}{C_{4} \cdot s}} + \frac{1}{R_{o}}} \tag{15} $$
$$ G_{pwr} = \frac{1}{\left(\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}\right) \cdot \left(DCR + L \cdot s + \frac{1}{\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}}\right)} \tag{14} $$ $$ \alpha_{led} = \frac{R_{1} \cdot R_{sense}}{\left(R_{1} + R_{6}\right) \cdot \left(R_{led} + R_{sense}\right)} \tag{13} $$
Substituting in (9) we get $$ G_{loop} = \frac{G_{m} \cdot G_{pwm} \cdot R_{1} \cdot R_{sense}}{\left(R_{1} + R_{6}\right) \cdot \left(R_{led} + R_{sense}\right) \cdot \left(\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}\right) \cdot \left(DCR + L \cdot s + \frac{1}{\frac{1}{R_{led} + R_{sense}} + \frac{1}{ESR + \frac{1}{C_{out} \cdot s}}}\right) \cdot \left(C_{5} \cdot s + C_{EA} \cdot s + \frac{1}{R_{5} + \frac{1}{C_{4} \cdot s}} + \frac{1}{R_{o}}\right)} \tag{99} $$
Sympy simplify gives
$$ G_{loop} = \frac{G_{m} \cdot G_{pwm} \cdot R_{1} \cdot R_{o} \cdot R_{sense} \cdot \left(C_{4} \cdot R_{5} \cdot s + 1\right) \cdot \left(C_{out} \cdot ESR \cdot s + 1\right)}{\left(R_{1} + R_{6}\right) \cdot \left(\left(DCR + L \cdot s\right) \cdot \left(C_{out} \cdot ESR \cdot s + C_{out} \cdot s \cdot \left(R_{led} + R_{sense}\right) + 1\right) + \left(R_{led} + R_{sense}\right) \cdot \left(C_{out} \cdot ESR \cdot s + 1\right)\right) \cdot \left(C_{4} \cdot R_{5} \cdot s + C_{4} \cdot R_{o} \cdot s + R_{o} \cdot s \cdot \left(C_{5} + C_{EA}\right) \cdot \left(C_{4} \cdot R_{5} \cdot s + 1\right) + 1\right)} \tag{9} $$
Constant values
# only values are given in fig 7 Substitute C4 = 6.8e-08 Substitute C5 = 3.3e-11 Substitute R5 = 330.0 Substitute C_EA = 3e-12 (p16, in eq 17) Substitute C_out = 1e-07 (p 15 in eq 14) Substitute DCR = 0.155 (not given, typ value guessed) Substitute ESR = 0.1 (not given, typ value guessed) Substitute G_m = 0.0023 (p16, in eq 17) Substitute G_pwm = 26.3 (p13, eq 10) Substitute L = 0.0001 (p15 in eq 14) Substitute R1 = 20000.0 (p8 eq 5) Substitute R6 = 6800.0 (p8 eq 5) Substitute R_led = 1.3 (p13, eq 11) Substitute R_o = 800000.0 (p16, in eq 17) Substitute R_sense = 1.5 (p8 eq 4) Now we have the single remaining s: $$ G_{loop} = \frac{54170.1492537313 \cdot \left(1.0 \cdot 10^{-8} \cdot s + 1\right) \cdot \left(2.244 \cdot 10^{-5} \cdot s + 1\right)}{\left(2.8 \cdot 10^{-8} \cdot s + \left(2.9 \cdot 10^{-7} \cdot s + 1\right) \cdot \left(0.0001 \cdot s + 0.155\right) + 2.8\right) \cdot \left(2.88 \cdot 10^{-5} \cdot s \cdot \left(2.244 \cdot 10^{-5} \cdot s + 1\right) + 0.05442244 \cdot s + 1\right)} $$
We extract the polynomial coefficients of s:
num, den = G_loop.as_numer_denom() numf = list(map(float, num.as_poly(s).coeffs())) denf = list(map(float, den.as_poly(s).coeffs())) And using Python's Control library doc
G = ct.tf(numf, denf) gm, pm, _, _ = ct.margin(G) G is this, polynomials of s:
1.216e-08 s^2 + 1.216 s + 5.417e+04 --------------------------------------------------------------- 1.874e-20 s^4 + 1.644e-12 s^3 + 5.451e-06 s^2 + 0.161 s + 2.955 Gain and phase margin:
gain margin 3143.446534 phase margin 82.552834 Further functions give a frequency margin of 36110.825275 and a (visually) matching Bode plot.

Bode plot actually made with sympy.physics.control.lti.TransferFunction and .bode_plot