• Welcome to ASR. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

ES9821 ADC – heavy odd-order distortion far from datasheet THD+N. What am I missing?

siarez

Member
Forum Donor
Joined
Dec 3, 2025
Messages
15
Likes
60
Hey, This is my first post. Looking forward to be part this community, and share more about my projects :)
I'm currently working on a current drive DSP+AMP combo. It is using a ESS ES9821 ADC and I’m seeing much worse distortion and noise than the datasheet suggests.
I’d really appreciate a sanity check from anyone who’s used this part (or similar ESS ADCs) before I write it off or redesign around something else.

1. What the datasheet claims vs what I see​

Datasheet headline (ES9821):
  • DNR ≈ 120 dB (A-weighted)
  • THD+N ≈ –112 dB (A-weighted, 1 kHz, −1 dBFS, 48 kHz, etc.)
What I’m actually measuring (directly from I²S):
  • Test tone: 1 kHz, ~−1 dBFS, 48 kHz sample rate
  • FFT of the raw I²S stream (24-bit in 32-bit slots) shows:
    • Fundamental at ~0 dBFS (within ~1 dB of target)
    • Noise floor around –115…–120 dBFS per bin
    • Dominant HD3 & HD5 around −70…−80 dBFS
    • HD2 & HD4 much lower (roughly –95 to –110 dBFS)
Using a least-squares sine fit in the time domain and treating the residual as noise+distortion, I get:
  • THD+N ≈ 58–60 dB at –1 dBFS
  • This matches very closely what I see from a QA403 audio analyzer on the analog outputs of the same system
So THD+N is ~50 dB worse than the datasheet, and the spectrum is clearly THD-dominated, not noise-dominated.
Below is the FFT of the decoded I2S signal at different input levels.
1764748103400.png

2. Hardware overview​

  • ADC: ESS ES9821 (two different chips, five indetical boards)
  • Sampling: 48 kHz, I²S, 32-bit word, 24-bit meaningful data
  • Clocking:
    • External 24.576 MHz MCLK
    • ES9821 running as I²S master for most tests (also tried slave)
    • No PLL in this mode (PLL disabled, direct MCLK)
  • Front-end:
    • THS4521 fully differential driver per channel
    • VOCM ≈ 1.65 V
    • ADC inputs are shorted differentially for noise tests (still biased at 1.65V)
    • For THD tests: ~1.78 Vrms differential at the ADC pins ≈ −1 dBFS (per ESS example conditions)
I’ve measured the front-end alone (at the ES9821 input pins) with a QA403: noise floor and very low THD, so the op-amp stage is not the limiting factor.
Supplies and VREF have also been checked on a scope and QA analyzer – no obvious HF junk or tones anywhere near big enough to explain what I’m seeing.

3. Measurement method (no DAC in loop)​

Early on I looked at the DAC output, but I’ve since taken the DAC completely out of the picture.
Current method:
  1. Capture ES9821’s I²S DOUT + LRCLK on a Rigol DHO804 scope.
  2. Decode the captures in Python:
    • Use LRCLK transitions to segment each 32-bit half-frame.
    • Sample DOUT at an empirically determined phase (~0.8 of the bit period) to stay away from edges.
    • Rebuild 32-bit words, then extract 24-bit samples (24-bit left-justified in 32-bit, arithmetic >> 8).
    • Convert to floating point in full-scale units (FS ≡ ±1.0 peak).
  3. Analysis:
    • Time-domain sine fit at f₀ (≈996 Hz) → signal RMS and residual RMS → THD+N.
    • FFT with Hann window and proper scaling → dBFS/dBV spectra.
    • Automatic extraction of harmonic bins (HD2…HD10) around n·f₀.
The I²S-derived THD+N numbers match the QA403 to within a few dB, so I’m confident the problem really is in the ADC output stream, not the measurement pipeline.

4. Register / mode configuration and experiments​

I started from ESS’s example register settings for 48 kHz and then tried a bunch of variations. Key points:
  • Clocking & system config (simplified):
    • 48 kHz, 24.576 MHz MCLK
    • 32-bit I²S
    • ES9821 as I²S master in one set of tests, as slave in another
    • No PLL engaged in this mode; direct MCLK
  • ESS-provided scripts:
    • Used their “SW_MCLK_MasterMode 24 MHz”–style scripts:
      • Enabling master mode
      • THD compensation (C2/C3 registers for both channels)
      • AUTO_FS_DETECT, 64× mode, etc.
    • Also tried their slave-mode config with PLL from BCLK in a separate experiment.
    • Result: only small changes (a few dB) in HF response / noise. THD and harmonic structure essentially unchanged.
  • ADC_CLK_DIV2 (Reg 0x02[7])
    • ADC_CLK_DIV2 = 1 improves noise by ~8 dB vs 0, but:
      • It somewhat improves harmonics,
      • THD is still dominated by HD3/HD5 around –70…–80 dBFS at –1 dBFS input.
      • ADC_CLK_DIV2 = 1 is out of spec according to the datasheet
  • FIR bypass
    • Bypassed FIR4x and FIR2x in the ADC path (ADC_BYPASS bits).
    • This shifts the noise floor and HF response by a few dB, but does not fix distortion/noise at audio frequencies (100 Hz–2 kHz).
  • THD compensation
    • Programmed THD-comp registers C2/C3 (Regs 55–62) with the values provided by ESS.
    • No measurable improvement in HD3/HD5 levels. I guess this is because those registers are not meant to fix this level of distortion.
  • I²S format & word length
    • Tried I²S vs left-justified, 16/24/32-bit word lengths.
    • No change in THD behaviour.
  • Master vs slave
    • Both ES9821-as-master and ES9821-as-slave to an external I²S master behave similarly in terms of THD/HD3/HD5/noise.
  • Chip sourcing
    • One batch assembled by JLCPCB (original suspect: “bad lot”).
    • One ES9821 sourced later from Mouser. Swapped onto a board.
    • Behaviour is essentially identical on both chips.

5. Distortion behaviour vs level and frequency​

Using a series of I²S captures and Python analysis:

5.1 1 kHz: Harmonics vs input level​

Input levels (approx, at ADC in): –1, –6, –12, –18, –24 dBFS.
Measured fundamentals and harmonics in dBFS:
  • Fundamental roughly follows input (linear within ~1 dB).
  • Example (1 kHz, ~–1 dBFS input):
    • Fund ≈ –1.7 dBFS
    • HD2 ≈ –106 dBFS (≈ –104 dBc)
    • HD3 ≈ –73 dBFS (≈ –71 dBc)
    • HD4 ≈ –94 dBFS
    • HD5 ≈ –74 dBFS (≈ –72 dBc)
As the input level is reduced from −1 → −18 dBFS:
  • HD3/HD5 in absolute dBFS change only a few dB.
  • In dBc, they actually get worse at lower levels (distortion floor is roughly fixed while the signal shrinks).
This is not what you’d expect from a simple small cubic term (which should scale 3× with level); instead it looks like a fixed nonlinearity floor in the ADC.

5.2 Harmonics vs frequency (100 Hz → 4 kHz)​

At a fixed level (around −1 to −6 dBFS), sweeping tone frequency from 100 Hz up to 4 kHz:
  • HD3/HD5 amplitudes in dBFS are essentially flat with frequency.
  • No strong trend of “distortion gets worse at higher f”.

6. Summary of where I am stuck​

  • Noise-only SNR (ignoring harmonics) is in the ballpark of 70–80 dB at –1 dBFS - not great!
  • But THD is dominated by HD3 and HD5 around –70…–80 dBFS, nearly level- and frequency-independent across the audio band.
  • THD+N ≈ 58–60 dB at –1 dBFS @ 1 kHz, confirmed both:
    • Digitally (from the I²S stream),
    • And analog-side via a QA403.
Given:
  • Two differently sourced ES9821 chips,
  • five boards,
  • Clean front-end,
  • And a lot of register/clocking experiments,
I’m struggling to reconcile this with the –112 dB THD+N claimed in the datasheet which I'm sure it's not a lie.

7. Other observations​

  • Poking, probing, and tapping the pins of the chip has no impact on noise and distortion level.
  • Sweeping the input bias voltage also did nothing to noise and distortion. (It only made it worse at extreme values)
  • All five prototype boards behave the same.

Finally​

Has anyone here:
  1. Run into a similar “odd-order floor” (HD3/HD5) that is:
    • ~–70…–80 dBc at –1 dBFS,
    • Fairly flat vs level and frequency,
    • With a high noise floor
  2. Is there any undocumented mode / calibration / clock tree combination / OSR setting that’s critical to achieving the published THD but not obvious from the datasheet?
  3. Any “gotchas” with:
    • SELECT_ADC_NUM, ADC_CLK_DIV2, FIR bypass settings,
    • or ESS’s THD compensation registers,
      that might silently drop the part into a lower-performance mode?
At this point I’m trying to decide whether:
  • I’m missing one crucial configuration/calibration step, or
  • I've made a grave mistake in my schematic/layout
Happy to share register dumps, small I²S captures, and the Python analysis scripts if that helps anyone reproduce or sanity-check the numbers.

Sorry for the long post. I did a lot of investigative work! And thanks in advance for any insights or “I’ve seen this before” stories.
 
Makes complete sense in hindsight. A clean, low-impedance VREF tends to be extremely important for high performance in both ADCs and DACs.
Yea, I do have a cap on VREF. I was missing the cap on VREF_BUFF. I assumed VREF_BUFF is just VREF that is buffered internally to serve as reference for external circuits. But when I probed it there is a 200mVrms noise on it, which tells me internal circuits are also drawing significant current from it.
 
Back
Top Bottom