THD Hump?
Time to decode the setup for the ESS DAC. I don't know if it's correct to post this in this forum thread, or if it's better to start a new thread, please give me a hint. Anyway, I've been interested in what @amirm has called "the ESS hump", where the measurements have a rise in THD when doing IMD measurements. By checking how the DAC is set up, we can start to see why some implementations don't have that problem. I know that both @amirm, me and others have had a suspicion of the built-in THD compensation available on the ESS DAC's. So let's go down the rabbit hole and see if that's the case.
So I've hooked up my Khadas DAC to my logic analyzer and dumped the communication between the XMOS USB chip and the ES9038Q2M chip. I'm going to over-explain everything so even if you don't have the knowledge of electronics or how it works; you will still be able to follow along.
I2C (pronounced eye-squared-cee)
First, let's start with how the XMOS chip communicates with the DAC to set it up on startup. It uses a hardware protocol called I2C, which was developed by Philips back in the '70s for communication between IC chips. The protocol is very simple; it only needs two signal lines, one is a clock signal called SCL and one called SDA for data. You have a Master IC that talks to Slaves on the two lines. There can be several Masters and Slaves on the same lines because all the chips have an ID-number so that the Masters can address the specific chip with a corresponding ID number.
Communication
The Master initialise either a read or write to a specific register. The IC's have two specific addresses, one for writing and one for reading. In our case, the ES9038Q2M has 0x90 as write and 0x92 for reading. The numbers are in hexadecimal. What we are interested in at first is what registers are written to, and with what value.
Boot sequence
I have uploaded the boot sequence in a file you can download and follow along. All you have to do is to download the Saleae logic analyzer software. You can use it without any logic analyzer connected and load my file without a problem.
Sanity check
Let's first see if I managed to capture values that is correct. First, we need to get hold of the datasheet for the ES9038Q2M DAC. Having to do that is usually done by signing a non-disclosure agreement, which is stupid in my humble opinion, but they've decided to do that. Fortunately for us, there is a multitude of places to download it anyway.
In the datasheet, there are several registers for setting up the DAC. They go from 0 to 102. The first 52 to are read/write, 53-54 are reserved, and 55 to 102 are read-only for checking status.
So let's check if our data looks sane.
So register 0 sets up the oscillator drive, clock divider and soft reset and is by default 0. Checking the captured data, that is precisely what we get.
Register 1 is for input selection. It's easier to set the display of the captured data to binary because the register has several bits that determine different functions. Input select are designated with [1:0] which in normal speak means bit 0 and 1. The default setting is 00, which we have, so let's continue to check the bits.
Auto select: bits 2 and 3 specifies what kind of input signal the DAC is to expect.
2'b11: automatically select between DSD, SPDIF or serial data (default)
So this seems to be set to the standard values as well. Looking good.
Next is serial_mode. That should be set to 00, which it is. After that, bits [7:6] selects the word length of the audio data, and it should be set to 11. So it is. So we can now be quite confident that we have valid data captured.
THD compensation
So now we can check if the Khadas DAC uses the THD compensation by checking the value of register 13: THD Bypass.
Here bit [6] determines if the THD compensation is activated. However, here's a trap. There's a glaring error in the datasheet. Looking at the information about the default values, it shows that bit 6 should be 1 by default, but if you look further down, it says that 0 enables the THD compensation. I would guess that the first entry, that you need a 1 in bit [6] enables the THD compensation. That means that the Khadas DAC does not have THD compensation enabled because it sends 0x00 to that register.
If we check register 23-24, which is a 16-bit signed coefficient for correcting second harmonic distortion, that value is set to 0.
The same goes for register 25-26, which is not set at all.
So where do we go from here? Well, time to replace the logic analyzer that only reads values and use a Bus Pirate that can inject values to registers instead. However, first I need to get my QuantAsylum QA-401 setup to read the THD correctly and then enable the THD compensation. The next step would be to try to feed coefficient values and try to knock down the already low harmonics. However, that has to be done at a later stage. Maybe we could give the correction coefficient values to Khadas as a Christmas present?
Time to decode the setup for the ESS DAC. I don't know if it's correct to post this in this forum thread, or if it's better to start a new thread, please give me a hint. Anyway, I've been interested in what @amirm has called "the ESS hump", where the measurements have a rise in THD when doing IMD measurements. By checking how the DAC is set up, we can start to see why some implementations don't have that problem. I know that both @amirm, me and others have had a suspicion of the built-in THD compensation available on the ESS DAC's. So let's go down the rabbit hole and see if that's the case.
So I've hooked up my Khadas DAC to my logic analyzer and dumped the communication between the XMOS USB chip and the ES9038Q2M chip. I'm going to over-explain everything so even if you don't have the knowledge of electronics or how it works; you will still be able to follow along.
I2C (pronounced eye-squared-cee)
First, let's start with how the XMOS chip communicates with the DAC to set it up on startup. It uses a hardware protocol called I2C, which was developed by Philips back in the '70s for communication between IC chips. The protocol is very simple; it only needs two signal lines, one is a clock signal called SCL and one called SDA for data. You have a Master IC that talks to Slaves on the two lines. There can be several Masters and Slaves on the same lines because all the chips have an ID-number so that the Masters can address the specific chip with a corresponding ID number.
Communication
The Master initialise either a read or write to a specific register. The IC's have two specific addresses, one for writing and one for reading. In our case, the ES9038Q2M has 0x90 as write and 0x92 for reading. The numbers are in hexadecimal. What we are interested in at first is what registers are written to, and with what value.
Boot sequence
I have uploaded the boot sequence in a file you can download and follow along. All you have to do is to download the Saleae logic analyzer software. You can use it without any logic analyzer connected and load my file without a problem.
Sanity check
Let's first see if I managed to capture values that is correct. First, we need to get hold of the datasheet for the ES9038Q2M DAC. Having to do that is usually done by signing a non-disclosure agreement, which is stupid in my humble opinion, but they've decided to do that. Fortunately for us, there is a multitude of places to download it anyway.
In the datasheet, there are several registers for setting up the DAC. They go from 0 to 102. The first 52 to are read/write, 53-54 are reserved, and 55 to 102 are read-only for checking status.
So let's check if our data looks sane.
So register 0 sets up the oscillator drive, clock divider and soft reset and is by default 0. Checking the captured data, that is precisely what we get.
Register 1 is for input selection. It's easier to set the display of the captured data to binary because the register has several bits that determine different functions. Input select are designated with [1:0] which in normal speak means bit 0 and 1. The default setting is 00, which we have, so let's continue to check the bits.
Auto select: bits 2 and 3 specifies what kind of input signal the DAC is to expect.
2'b11: automatically select between DSD, SPDIF or serial data (default)
So this seems to be set to the standard values as well. Looking good.
Next is serial_mode. That should be set to 00, which it is. After that, bits [7:6] selects the word length of the audio data, and it should be set to 11. So it is. So we can now be quite confident that we have valid data captured.
THD compensation
So now we can check if the Khadas DAC uses the THD compensation by checking the value of register 13: THD Bypass.
Here bit [6] determines if the THD compensation is activated. However, here's a trap. There's a glaring error in the datasheet. Looking at the information about the default values, it shows that bit 6 should be 1 by default, but if you look further down, it says that 0 enables the THD compensation. I would guess that the first entry, that you need a 1 in bit [6] enables the THD compensation. That means that the Khadas DAC does not have THD compensation enabled because it sends 0x00 to that register.
If we check register 23-24, which is a 16-bit signed coefficient for correcting second harmonic distortion, that value is set to 0.
The same goes for register 25-26, which is not set at all.
So where do we go from here? Well, time to replace the logic analyzer that only reads values and use a Bus Pirate that can inject values to registers instead. However, first I need to get my QuantAsylum QA-401 setup to read the THD correctly and then enable the THD compensation. The next step would be to try to feed coefficient values and try to knock down the already low harmonics. However, that has to be done at a later stage. Maybe we could give the correction coefficient values to Khadas as a Christmas present?