Electronic – Straight from the datasheet: Is this really a sensible filter circuit

adcaudiodacoperational-amplifiersimulation

Cirrus Logic CS42426-CQZ is an audio CODEC that I want to use in a custom USB sound card. You can download the datasheet from there.

On page 61, the datasheet has a recommended circuit for each A/D and D/A channel, but I fail to see the purpose of such complexity. Sure, they're converting between differential and single-ended, but there are simpler ways to do that too.

I copied their schematic into some open-source simulation software (http://qucs.sourceforge.net/) and the frequency response doesn't even match the stated purpose. But least the audible response is somewhat flat:

ADC In:
In
(Okay, so they're relying on the CMRR of the ADC itself as part of the anti-aliasing filter. Don't like that idea.)

DAC Out:
Out

I assume that they're actually serious about using those circuits in a real-world application, but something doesn't seem right about it. Like I said, the audible response is fairly flat, so it'll probably sound okay without cell phones or other RF, but I think I can do better with the old classics from OpAmps 101. You guys agree?

Is there really a good reason to have an audio ADC rise from nominal-gain at 20kHz to a peak at 300kHz? Or for the DAC to do the same from 20Hz to around 0.5Hz?


For completeness, here are the simulation files. Copy them into plain text files, change the extension to .sch if your system cares, and open them in Qucs:

ADC In:

<Qucs Schematic 0.0.18>
<Properties>
  <View=785,329,2079,1333,0.883466,0,0>
  <Grid=10,10,1>
  <DataSet=DiffAmpIn.dat>
  <DataDisplay=DiffAmpIn.dpl>
  <OpenDisplay=1>
  <Script=DiffAmpIn.m>
  <RunScript=0>
  <showFrame=0>
  <FrameText0=Title>
  <FrameText1=Drawn By:>
  <FrameText2=Date:>
  <FrameText3=Revision:>
</Properties>
<Symbol>
</Symbol>
<Components>
  <GND * 1 1120 480 0 0 0 0>
  <VProbe In 1 1110 460 28 -31 0 0>
  <GND * 1 940 640 0 0 0 0>
  <C C4 5 1010 520 -26 17 0 0 "100 uF" 1 "" 0 "neutral" 0>
  <GND * 1 1080 640 0 0 0 0>
  <R R18 5 1080 590 16 -10 0 3 "10 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <.DC DC1 5 930 700 0 41 0 0 "26.85" 0 "0.001" 0 "1 pA" 0 "1 uV" 0 "no" 0 "150" 0 "no" 0 "none" 0 "CroutLU" 0>
  <C C6 5 1230 420 -26 17 0 0 "470 pF" 1 "" 0 "neutral" 0>
  <R R23 5 1310 380 -9 10 0 2 "634 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R22 5 1350 500 -9 10 0 2 "91 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <OpAmp OP3 5 1230 500 -26 -42 1 0 "1e6" 0 "15 V" 0>
  <R R27 5 1300 570 16 -10 0 3 "634 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <C C8 5 1600 610 17 -26 0 1 "2700 pF" 1 "" 0 "neutral" 0>
  <Vac V1 5 940 590 18 -26 0 1 "1 V" 1 "1 kHz" 1 "0" 0 "0" 0>
  <C C7 5 1390 660 -26 17 0 0 "470 pF" 1 "" 0 "neutral" 0>
  <R R24 5 1470 620 -9 10 0 2 "634 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R25 5 1510 740 -9 10 0 2 "91 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <OpAmp OP4 5 1390 740 -26 -42 1 0 "1e6" 0 "15 V" 0>
  <GND * 1 1260 780 0 0 0 0>
  <R R26 5 1310 760 -9 10 0 2 "332 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <.AC AC1 5 930 750 0 41 0 0 "log" 1 "0.1 Hz" 1 "100 MHz" 1 "901" 1 "no" 0>
  <VProbe Diff 1 1820 610 -16 28 0 3>
  <GND * 1 1760 740 0 0 0 0>
  <VProbe Neg 1 1750 720 28 -31 0 0>
  <GND * 1 1760 500 0 0 0 0>
  <VProbe Pos 1 1750 480 28 -31 0 0>
</Components>
<Wires>
  <1080 480 1100 480 "" 0 0 0 "">
  <1080 480 1080 520 "" 0 0 0 "">
  <1040 520 1080 520 "" 0 0 0 "">
  <940 520 980 520 "" 0 0 0 "">
  <940 520 940 560 "" 0 0 0 "">
  <940 620 940 640 "" 0 0 0 "">
  <1080 620 1080 640 "" 0 0 0 "">
  <1080 520 1080 560 "" 0 0 0 "">
  <1080 520 1200 520 "" 0 0 0 "">
  <1300 420 1300 500 "" 0 0 0 "">
  <1260 420 1300 420 "" 0 0 0 "">
  <1180 420 1200 420 "" 0 0 0 "">
  <1300 500 1320 500 "" 0 0 0 "">
  <1380 500 1400 500 "" 0 0 0 "">
  <1180 380 1180 420 "" 0 0 0 "">
  <1180 380 1280 380 "" 0 0 0 "">
  <1400 380 1400 500 "" 0 0 0 "">
  <1340 380 1400 380 "" 0 0 0 "">
  <1270 500 1300 500 "" 0 0 0 "">
  <1180 420 1180 480 "" 0 0 0 "">
  <1180 480 1200 480 "" 0 0 0 "">
  <1300 500 1300 540 "" 0 0 0 "">
  <1400 500 1600 500 "" 0 0 0 "">
  <1600 500 1600 580 "" 0 0 0 "">
  <1600 640 1600 740 "" 0 0 0 "">
  <1300 600 1300 720 "" 0 0 0 "">
  <1460 660 1460 740 "" 0 0 0 "">
  <1420 660 1460 660 "" 0 0 0 "">
  <1340 660 1360 660 "" 0 0 0 "">
  <1460 740 1480 740 "" 0 0 0 "">
  <1340 620 1340 660 "" 0 0 0 "">
  <1340 620 1440 620 "" 0 0 0 "">
  <1500 620 1560 620 "" 0 0 0 "">
  <1540 740 1560 740 "" 0 0 0 "">
  <1560 740 1600 740 "" 0 0 0 "">
  <1560 620 1560 740 "" 0 0 0 "">
  <1430 740 1460 740 "" 0 0 0 "">
  <1340 660 1340 720 "" 0 0 0 "">
  <1340 720 1360 720 "" 0 0 0 "">
  <1260 760 1260 780 "" 0 0 0 "">
  <1260 760 1280 760 "" 0 0 0 "">
  <1340 760 1360 760 "" 0 0 0 "">
  <1300 720 1340 720 "" 0 0 0 "">
  <1600 740 1710 740 "" 0 0 0 "">
  <1710 740 1740 740 "" 0 0 0 "">
  <1710 620 1710 740 "" 0 0 0 "">
  <1710 620 1800 620 "" 0 0 0 "">
  <1600 500 1710 500 "" 0 0 0 "">
  <1710 500 1740 500 "" 0 0 0 "">
  <1710 500 1710 600 "" 0 0 0 "">
  <1710 600 1800 600 "" 0 0 0 "">
</Wires>
<Diagrams>
  <Rect 880 1239 498 359 3 #c0c0c0 1 10 1 0.1 1 1e+08 1 -0.540919 1 6 1 -1 0.5 1 315 0 225 "" "" "">
    <"In.v" #0000ff 0 3 0 0 0>
    <"Diff.v" #ff0000 0 3 0 0 0>
  </Rect>
  <Rect 1480 1239 498 359 3 #c0c0c0 1 10 1 0.1 1 1e+08 1 -1 0.5 1 1 -0.100118 1 4.34333 315 0 225 "" "" "">
    <"Pos.v" #0000ff 0 3 0 0 0>
    <"Neg.v" #ff0000 0 3 0 0 0>
  </Rect>
</Diagrams>
<Paintings>
</Paintings>

DAC Out:

<Qucs Schematic 0.0.18>
<Properties>
  <View=-56,169,1878,1394,0.909091,0,88>
  <Grid=10,10,1>
  <DataSet=DiffAmpOut.dat>
  <DataDisplay=DiffAmpOut.dpl>
  <OpenDisplay=1>
  <Script=DiffAmpOut.m>
  <RunScript=0>
  <showFrame=0>
  <FrameText0=Title>
  <FrameText1=Drawn By:>
  <FrameText2=Date:>
  <FrameText3=Revision:>
</Properties>
<Symbol>
</Symbol>
<Components>
  <GND * 1 40 660 0 0 0 0>
  <IProbe Neg 1 370 500 -26 16 0 0>
  <IProbe Pos 1 370 620 -26 16 0 0>
  <R R16 5 250 620 -9 10 0 2 "0 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R17 5 250 500 -9 10 0 2 "0 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <GND * 1 460 560 0 0 0 0>
  <R R19 5 550 680 -9 10 0 2 "1.65 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <C C2 5 550 620 -26 17 0 0 "5800 pF" 1 "" 0 "neutral" 0>
  <R R21 5 730 680 -9 10 0 2 "1.87 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R23 5 730 620 -9 10 0 2 "887 Ohm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R18 5 550 440 -9 10 0 2 "5.49 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <C C1 5 550 500 -26 17 0 0 "1800 pF" 1 "" 0 "neutral" 0>
  <R R20 5 730 440 -9 10 0 2 "6.19 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R22 5 730 500 -9 10 0 2 "2.94 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <C C5 5 890 680 -26 17 0 0 "22 uF" 1 "" 0 "neutral" 0>
  <OpAmp OP1 5 870 560 -26 -42 1 0 "1e6" 0 "15 V" 0>
  <C C3 5 890 620 -26 17 0 0 "1200 pF" 1 "" 0 "neutral" 0>
  <C C4 5 890 500 -26 17 0 0 "390 pF" 1 "" 0 "neutral" 0>
  <GND * 1 960 700 0 0 0 0>
  <GND * 1 1320 560 0 0 0 0>
  <VProbe Out 1 1310 540 28 -31 0 0>
  <C C6 5 1090 560 -26 17 0 0 "22 uF" 1 "" 0 "neutral" 0>
  <R R24 5 1170 560 -9 10 0 2 "1 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <R R25 5 1260 630 19 -8 0 3 "47.5 kOhm" 1 "26.85" 0 "0.0" 0 "0.0" 0 "26.85" 0 "US" 0>
  <GND * 1 1260 680 0 0 0 0>
  <GND * 1 1040 520 0 0 0 0>
  <VProbe Amp 1 1030 500 28 -31 0 0>
  <.DC DC1 5 30 730 0 39 0 0 "26.85" 0 "0.001" 0 "1 pA" 0 "1 uV" 0 "no" 0 "150" 0 "no" 0 "none" 0 "CroutLU" 0>
  <.AC AC1 5 30 780 0 39 0 0 "log" 1 "0.1 Hz" 1 "10 MHz" 1 "801" 1 "no" 0>
  <Vac V1 5 40 610 18 -26 0 1 "0 V" 1 "1 kHz" 1 "0" 0 "0" 0>
  <Vac V3 5 190 620 -26 18 0 0 "1 V" 1 "1 kHz" 1 "0" 0 "0" 0>
  <Vac V2 5 190 500 -26 -50 0 2 "1 V" 1 "1 kHz" 1 "0" 0 "0" 0>
</Components>
<Wires>
  <280 620 340 620 "" 0 0 0 "">
  <40 640 40 660 "" 0 0 0 "">
  <40 560 40 580 "" 0 0 0 "">
  <40 560 140 560 "" 0 0 0 "">
  <140 500 160 500 "" 0 0 0 "">
  <140 620 160 620 "" 0 0 0 "">
  <140 500 140 560 "" 0 0 0 "">
  <140 560 140 620 "" 0 0 0 "">
  <280 500 340 500 "" 0 0 0 "">
  <400 500 420 500 "" 0 0 0 "">
  <400 620 420 620 "" 0 0 0 "">
  <420 440 420 500 "" 0 0 0 "">
  <420 440 520 440 "" 0 0 0 "">
  <420 620 420 680 "" 0 0 0 "">
  <420 680 520 680 "" 0 0 0 "">
  <460 560 500 560 "" 0 0 0 "">
  <500 560 500 620 "" 0 0 0 "">
  <500 620 520 620 "" 0 0 0 "">
  <580 620 660 620 "" 0 0 0 "">
  <580 680 660 680 "" 0 0 0 "">
  <660 680 700 680 "" 0 0 0 "">
  <660 620 660 680 "" 0 0 0 "">
  <660 620 700 620 "" 0 0 0 "">
  <500 500 500 560 "" 0 0 0 "">
  <500 500 520 500 "" 0 0 0 "">
  <580 500 660 500 "" 0 0 0 "">
  <580 440 660 440 "" 0 0 0 "">
  <660 440 700 440 "" 0 0 0 "">
  <660 440 660 500 "" 0 0 0 "">
  <660 500 700 500 "" 0 0 0 "">
  <760 680 860 680 "" 0 0 0 "">
  <920 680 960 680 "" 0 0 0 "">
  <760 440 960 440 "" 0 0 0 "">
  <760 500 840 500 "" 0 0 0 "">
  <760 620 840 620 "" 0 0 0 "">
  <840 580 840 620 "" 0 0 0 "">
  <840 500 840 540 "" 0 0 0 "">
  <840 620 860 620 "" 0 0 0 "">
  <840 500 860 500 "" 0 0 0 "">
  <910 560 960 560 "" 0 0 0 "">
  <960 500 960 560 "" 0 0 0 "">
  <920 500 960 500 "" 0 0 0 "">
  <960 440 960 500 "" 0 0 0 "">
  <920 620 960 620 "" 0 0 0 "">
  <960 620 960 680 "" 0 0 0 "">
  <960 680 960 700 "" 0 0 0 "">
  <1120 560 1140 560 "" 0 0 0 "">
  <1200 560 1260 560 "" 0 0 0 "">
  <1260 560 1300 560 "" 0 0 0 "">
  <1260 560 1260 600 "" 0 0 0 "">
  <1260 660 1260 680 "" 0 0 0 "">
  <1000 520 1020 520 "" 0 0 0 "">
  <960 560 1000 560 "" 0 0 0 "">
  <1000 560 1060 560 "" 0 0 0 "">
  <1000 520 1000 560 "" 0 0 0 "">
</Wires>
<Diagrams>
  <Rect 300 1119 498 359 3 #c0c0c0 1 10 1 0.1 1 3e+06 1 -0.422698 1 4.66459 1 -1 0.5 1 315 0 225 "" "" "">
    <"Pos.i" #0000ff 0 3 0 0 0>
    <"Neg.i" #ff0000 0 3 0 0 0>
  </Rect>
  <Rect 880 1119 498 359 3 #c0c0c0 1 10 1 0.1 1 3e+06 1 -0.00012118 0.0002 0.00133304 1 -1 0.5 1 315 0 225 "" "" "">
    <"Amp.v" #0000ff 0 3 0 0 0>
    <"Out.v" #ff0000 0 3 0 0 0>
  </Rect>
</Diagrams>
<Paintings>
</Paintings>

Best Answer

I like this question. It's such a good example of how datasheet schematics are great for showing concepts, but not to just be used as is.

Looking at the description of the filter, it seems the main concepts are: flat response in the audio pass band, low source impedance to the ADC inputs, operation centered around a VQ of 2.7V, and attenuation of 20dB is adequate for anti-aliasing.

The 2700pF cap implies that the ADC is switched capacitor input, without any buffer. At 6MHz that's about 10 Ohms of filter output impedance. While it would be easy to use something like a lossy integrator to get the attenuation and centering around VQ, output impedance would be higher.

The amplifier arrangement, sometimes called "in the loop load compensation" is to cope with the capacitive loading on the OpAmps. Compensation like this has an adjustable Q so that the transition into roll-off can be much sharper than a simple RC. There is often some amount of tuning required to get the desired flatness. In this case though it looks like there is an error in the schematic that caused peaking with the part values.

Here's a schematic with reference designators:

enter image description here

You can see where I think the schematic goes wrong, with the connection of R4. But, before going into that, let's go over how the circuit should work.

With capacitive loading, an OpAmp will loose phase margin. A good OpAmp will typically have about 60 degrees of phase margin. But even a load of 100pF can cause phase margin to decline to 40 or 45 degrees, resulting in a peaky response. Addition of R2, C2, and R3 allows the amplifier to maintain phase margin with load. C2 rolls bandwidth back, increasing phase margin. R3 helps minimize phase margin loss with the addition of C4. R2 provides low frequency feedback to correct any passband error caused by R3.

Circuit response can be tuned by adjusting the value of C2. Making C2 larger will lower the Q of the filter. At low frequencies the loop of R2 dominates, but the C2 loop dominates at higher frequencies where C2 impedance is lower than R2+R3. Then the drop across R3 is uncompensated and the signal is attenuated by R3 C4 and eventual amplifier rolloff.

Consider just the non-inverting section with ideal amplifier. Transfer function, leaving out the zero of C1 R1 would be:

\$\frac{\text{Vo}}{\text{Vin}}\$ = \$\frac{\text{C2} s (\text{R2}+\text{R3})+1}{\text{C2} \text{C4} \text{R2} \text{R3} s^2+s (\text{C2} \text{R2}+\text{C2} \text{R3})+1}\$

The denominator looks suspiciously like the classical quadratic form containing Q and \$\omega _o\$, so derive those.

Q = \$\frac{\text{R2} \text{R3} \sqrt{\text{C4} \left(\frac{1}{\text{R2}}+\frac{1}{\text{R3}}\right)}}{\sqrt{\text{C2}} (\text{R2}+\text{R3})^{3/2}}\$

\$\omega _o\$ = \$\frac{\sqrt{\frac{1}{\text{R2}}+\frac{1}{\text{R3}}}}{\sqrt{\text{C2} \text{C4} (\text{R2}+\text{R3})}}\$

Since ideal amplifier was used to make things manageable, Q goes to infinity as C2 goes to zero. This won't be a problem since we only care about frequencies below amplifier bandwidth. With a real amplifier Q would fall off with amplifier gain. Pluging in values for R2, R3, and C4 we can plot Q as a function of C2.

enter image description here

Q decreases as value of C2 increases. If the amplifier is too peaky, just increase C2 too flatten out the response.

Now, looking at the curve, it looks like C2 of 470pF would have a Q of ~0.8. That would be pretty flat response. What happened?

In the datasheet the schematic show R4 connected to U1 output. This does 2 bad things. First, after going to some trouble to compensate out the low frequency effects of R3 and R6, connecting R4 to U1 out adds R3 drop back in. If you look at the output impedance of the filter you will see that is true. Second, it causes peaking to occur with C2 and C3 of 470pF (peak of Q is around 300pF, more or less than that Q decreases). If R4 is connected to the node with R2 R3 and C4, Q acts as expected. Also, filter output impedance will stay very low through audio passband, until rolloff and then follow C4 impedance.