sgtl5000 Delay from ADC to DAC

Status
Not open for further replies.

Neal

Well-known member
I wrote a simple program to try and understand a 250 usec delay I am seeing between the sgtl5000 input to its output. The intent of this test is to take a single sample from the codec ADC into the teensy and then send it back out to the codec DAC. No Audio buffers or Audio library methods are being used for this test.

I am using a simple SAI1 interrupt (no DMA) to handle the data transfers. I configured the i2s clocks and registers almost exactly as is done in the Audio library program except for a small change I made to the I2S1_TCSR register to account for not using DMA. I am also running with an fs = 96000 Hz, which is about a 10.4 usec interrupt rate.

Here is an Arduino sketch of the test program:

#include <Audio.h>
#include "utility\imxrt_hw.h"

void setup() {
AudioControlSGTL5000 sgtl5000_1;
Codec_config_i2s();
attachInterruptVector(IRQ_SAI1, CodecDAC_isr);
NVIC_ENABLE_IRQ(IRQ_SAI1);
I2S1_TCSR |= 1<<8; // start TX interrupts
sgtl5000_1.enable();
}

void loop() {
}

void CodecDAC_isr(void)
{
I2S1_TDR0 = I2S1_RDR0;
__DSB();
}

void Codec_config_i2s(void)
{
CCM_CCGR5 |= CCM_CCGR5_SAI1(CCM_CCGR_ON);

int fs = 96000.0f;
int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
int n2 = 1 + (24000000 * 27) / (fs * 256 * n1);

double C = ((double)fs * 256 * n1 * n2) / 24000000;
int c0 = C;
int c2 = 10000;
int c1 = C * c2 - (c0 * c2);
set_audioClock(c0, c1, c2, false);

CCM_CSCMR1 = (CCM_CSCMR1 & ~(CCM_CSCMR1_SAI1_CLK_SEL_MASK)) | CCM_CSCMR1_SAI1_CLK_SEL(2);
CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK)) | CCM_CS1CDR_SAI1_CLK_PRED(n1 - 1)
| CCM_CS1CDR_SAI1_CLK_PODF(n2 - 1);

IOMUXC_GPR_GPR1 = (IOMUXC_GPR_GPR1 // master clock is an output and something else?
& ~(IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL_MASK)) |
(IOMUXC_GPR_GPR1_SAI1_MCLK_DIR | IOMUXC_GPR_GPR1_SAI1_MCLK1_SEL(0));

int rsync = 0;
int tsync = 1;

I2S1_TMR = 0;
I2S1_TCR1 = I2S_TCR1_RFW(1);
I2S1_TCR2 = I2S_TCR2_SYNC(tsync) | I2S_TCR2_BCP
| (I2S_TCR2_BCD | I2S_TCR2_DIV((1)) | I2S_TCR2_MSEL(1));
I2S1_TCR3 = I2S_TCR3_TCE;
I2S1_TCR4 = I2S_TCR4_FRSZ((2 - 1)) | I2S_TCR4_SYWD((32 - 1)) | I2S_TCR4_MF | I2S_TCR4_FSD | I2S_TCR4_FSE | I2S_TCR4_FSP;
I2S1_TCR5 = I2S_TCR5_WNW((32 - 1)) | I2S_TCR5_W0W((32 - 1)) | I2S_TCR5_FBT((32 - 1));

I2S1_RMR = 0;
I2S1_RCR1 = I2S_RCR1_RFW(1);
I2S1_RCR2 = I2S_RCR2_SYNC(rsync) | I2S_RCR2_BCP
| (I2S_RCR2_BCD | I2S_RCR2_DIV((1)) | I2S_RCR2_MSEL(1));
I2S1_RCR3 = I2S_RCR3_RCE;
I2S1_RCR4 = I2S_RCR4_FRSZ((2 - 1)) | I2S_RCR4_SYWD((32 - 1)) | I2S_RCR4_MF | I2S_RCR4_FSE | I2S_RCR4_FSP | I2S_RCR4_FSD;
I2S1_RCR5 = I2S_RCR5_WNW((32 - 1)) | I2S_RCR5_W0W((32 - 1)) | I2S_RCR5_FBT((32 - 1));

CORE_PIN23_CONFIG = 3; // MCLK
CORE_PIN21_CONFIG = 3; // RX_BCLK
CORE_PIN20_CONFIG = 3; // RX_SYNC
CORE_PIN7_CONFIG = 3; // TX_DATA0
CORE_PIN8_CONFIG = 3; // 1:RX_DATA0
IOMUXC_SAI1_RX_DATA0_SELECT_INPUT = 2;
I2S1_RCSR |= I2S_RCSR_RE | I2S_RCSR_BCE;
I2S1_TCSR = I2S_TCSR_TE | I2S_TCSR_BCE /* | I2S_TCSR_FRDE <-- not using DMA */;
}

The problem is that the signal I put into codec line input is delayed by 250 usec at the codec line out. With no data buffering, and a 10.4 usec interrupt rate I would expect to see no more than a few tens of microseconds, not 250 usec. Below is a picture of the scope output. The top trace is the sgtl5000 ADC line input and the next trace down is the DAC line out.

Codec Delay.jpg

I haven't found much information on the guts of the sgtl5000 like amplifier details, or internal buffering or an ADC/DAC pipeline, so the delay is a mystery to me.

If someone has information to explain the delay, I would greatly appreciate it.

Thanks
 
If someone has information to explain the delay, I would greatly appreciate it.

How about speculation and guesswork?

NXP gives almost no information about the inner workings of the chip, but it's a pretty sure guess that the ADC is based on a sigma-delta modulator and digital low pass filter. On high-end ADC chips, often the datasheet will tell you the modulator's response (what "order" the noise shaping is) and the number of bits it uses and details like its oversampling ratio. Sometimes very high-end ADCs even let you select different filter functions. On low power parts like SGTL5000, usually no info is given. Very likely the modulator is a single bit output with 2nd or 3rd order response. Filters are usually simple IIR types, probably CIC.

The delay is probably coming from that filter.
 
I think its pretty likely that FIR filters are used in ADCs and DACs for oversampling (multirate conversion) as these allow
the efficient polyphase topology.

And yes, audio I2S ADCs and DACs are all sigma-delta AFAICT, as its cheaper and there's no need for DC accuracy.

A delay of 11 sample times is nothing unusual in a sigma-delta architecture. If delay matters you need to use something like
a SAR ADC and non-sigma-delta DAC chips. In the past I've used the 18 bit SAR ADS8885 for home-brew FFT analyzer.

[ BTW sigma-delta chips need to be continuously clocked with a stable clock, I2S is a perfect fit for this. ]
 
Yes I agree the architecture is probably sigma delta. Also, at a 10.4 usec conversion rate, the delay is about 25 sample times. FIRs can eat that up, but IIR CIC filters that are usually used after a sigma delta conversion shouldn't have that much delay. I guess we will never know without more detailed information from NXP.

In looking more closely at the sgtl5000 data sheet I also noted that it has the option of IO of up to 32 bits. The SNR specs are probably predicated on using 32bits. But the Audio Library control_sgtl.cpp selects the 16 bit mode. I plan to continue my testing to see the impact of using all 32 bits available in the sgtl5000.
 
Given the 0.12dB flatness spec, its got to have either decent downconversion filter in the first place such as half-band, or a pass-band flattening
filter after the CICs?
 
Given the 0.12dB flatness spec, its got to have either decent downconversion filter in the first place such as half-band, or a pass-band flattening
filter after the CICs?

Having done a bit of reading about decimation filters recently, I can definitely say no ADC uses just CIC for decimation due
to pass-band droop (!). So there will be some extra filtering (probably a halfband filter combined with the pass-band correction characteristic).
 
I did more tests over the past few days and the results are consistent with the above assumptions of there being a FIR filter somewhere in the processing chain. I tested the delays over for various frequency sine waves and the time delays were very constant (about 250 usec). Having constant group delays (linear phase delay) is a characteristic of a FIR filter that is designed to be distortion-less.

Still all guesswork, but fun to speculate!
 
You mean zero-phase, since standard metrics of distortion typically ignore phase.

The standard audio ADC architecture seems to be high-order sigma-delta modulator, high-rate CIC decimation stage(s),
then FIR droop-correction filter and FIR half-band final decimation stage(s), the latter running much lower clock speeds than
the modulator and first decimation filters.
 
No, I mean linear phase delay. For example, if you have a signal that is made up of say a 1 Hz tone and a 2 Hz tone and you are going to feed them into a linear phase FIR filter. Both signal components will be delayed the same amount of time (constant group delay), but the phase delay of each component is different. For example, with a .25 sec time delay, the phase delay for the 1 Hz component is 90 degrees. But the phase delay of the 2 Hz component is only 180 degrees.
 
I just meant FIR filters often are designed as zero-phase (the maths is easier) - any actual realization has to be causal of course.
(Not that being FIR implies linear phase at all, its just normal to use FIR when zero phase / linear phase is desired).
 
Funny, I thought that the main benefit of FIR was linear phase. If one wanted a minimum phase filter, yeah, you can also do that as an FIR, but you could use an IIR and it'd be more computationally efficient. So, if I can tolerate anything but linear phase, I abandon FIR and go IIR.

The comment that the maths are easier for FIR with minimum phase caught me off guard. Since I always design my FIR via FFT, the math is no easier or harder to do linear phase vs minimum phase. No diff in effort at all.

I love hearing these different perspectives!

Chip
 
Here you can find the document that describes from where the delays come from:
https://www.ti.com/lit/wp/slyy095a/slyy095a.pdf?ts=1613141458124

Though I note this sentence in that doc:
(Some ADCs have an additional filter stage to flatten the passband, but for simplicity those filters are not discussed here.)
Their example has 1.5 sample delays attributable to sinc filtering only at 8kSPS, we see more like 11 sample delays
from the SGTL5000 which must mostly be from the slowest clocked last filter in the chain, typically a half-band filter.
The chip claims a 0.11dB pass-band ripple figure, which indicates the final filter is optimized for low power, not
passband precision.

That doc also seems to neglect the normal architecture in audio ADCs of CIC cascade into half-band cascade, doesn't even
mention half-band filters. Higher quality audio ADCs tend to have higher-spec filters, and thus more delay.
 
As a point of reference, the 250 usec delay I measured in my testing is about 24 sample delays because my test was at Fs = 96000 Hz. It is an 11 sample delay at Fs = 44100.

The TI document is well written, as we are accustomed to from TI, but I agree the delays in this article are inconsistent with the sgtl5000 delays. If you look at the summary Table 2 at the end of the article, the delay it predicts for an Fs = 64000 Hz is still less than 2 sample delays.
 
The total delay is 250 usec when input and output are viewed on an oscilloscope. Since the sampling frequency is 96000 Hz, that is about 24 sample times. This is basically a black box test, so I have no idea how much of the delay is from the ADC versus the DAC.
 
Oh, yes you're right there, I'd not read the detailed setup code, in fact 24 samples seems more likely than 12 -
I guess I should check the latency with the Audio lib default rate too.
 
I finally found a bit of time to dig into this a little further. I wanted to find out how much of the 250 usec could be attributed to just the DAC. So I measured the time it took from an i2s write to the time the DAC output occurred. I alternately output a -32768 (0x8000) to +32767 (0x7FFF). I just replaced the CodecDAC_isr in the code I previously posted with this code:

void CodecDAC_isr(void)
{
if(counter++ == 32768){ DACdata = 0x8000; digitalWriteFast(5, HIGH); }
if(counter == 0){ DACdata = 0x7FFF; digitalWriteFast(5, LOW); }

I2S1_TDR0 = (int32_t)(DACdata) << 16;
I2S1_TDR0 = 0x0000;

__DSB();
}


Here is a picture I got on my scope:

RigolDS3.png

The D5 step indicates when the step occurs. Trace #4 shows when the DAC output step occurs. The delay is approximately 120 usec! I didn't expect that. I thought most of the 250 usec overall delay was going to be in ADC as discussed in the above posts.

The rest of the scope output shows the actual i2s signals, LR clock, bit clock and the actual ADC and DAC serial data. The display is compressed but you can see the DAC serial data change from the 0x7FFF to 0x8000 at the D5 step. Just to beat this dead horse a bit further, I zoomed in to take a closer look at the detailed i2s serial stream. Here is the zoomed in scope output:

RigolDS4.png

My scope i2s decoder clearly shows the L (left) codec DAC write occurring about 120 usec before the DAC output is visible.

So what does this all say. All I can say at this point is that the delays in the sgtl5000 are fairly large, in this case 250 usec. BTW, these delays vary linearly with the sample rate. I am working with an Fs of 96 kHz. Fs of 48 kHz delays would be in the 500 usec range. It looks to be split half to the ADC and half to the DAC end of things.

I would love to see a detailed logic diagram of the guts of this codec, but I know that isn't possible. Hope this was of interest to others!
 
In the audio codecs from TI, the DAC's reconstruction filter is usually a similar length to the ADC's decimation filter. So, the latency is similar through the DAC and through the ADC.

These filters are a certain number of samples in length. That's why the duration of the lag scales with sample rate.

If you're seeing 250usec lag from the DAC when running at 96kHz, it clearly must use a 24 sample long reconstruction filter. That is similar to the TI chips that I'm more familiar with.

The TI docs will say somewhere how long the decimation and reconstruction filters are. It's a bummer that the doc for the SGTL5000 does not.

Chip
 
I popped a 'scope on the data in and data out as well as the analog line in and out and measured, for SGTL5000 at 44100SPS a
delay of about 280µs for ADC and 240µs for the DAC, using square wave input, measured to the mid-transition of the analog
signal. The MSBs of the I2S data pins are fairly obvious with square waves it turns out, didn't need any teensy code to do
this (you can see this in the above shots too if you look carefully).

That's basically the same sample count, around 12 to 14, for each of ADC and DAC, whether at 96kSPS or 44.1kSPS
 
Can you point me to a TI audio codec similar to the sgtl5000 that has more information on the decimation and reconstruction filters?
 
The datasheet of the CirrusLogic CS4272 specifies group delay for the both the ADC and DAC circuitry.
This 24bit/192kHz codec is used in the Focusrite Scarlett 2i2 3Gen USB audio interface.

Paul
 
Can you point me to a TI audio codec similar to the sgtl5000 that has more information on the decimation and reconstruction filters?

The TI codec I'm most familiar with is the AIC3206. TI divides the technical details between the datasheet and the "Application Reference Guide". The details about the decimation filter (ADC) and interpolation filter (DAC) are in the App Ref Guide...

https://www.ti.com/lit/pdf/slaa463

For the ADC, there are a few diff filters that you can choose from. The typical one is decimation filter A. Table 2-16 says that it has a filter group delay of 17/fs (where fs is the sample rate). So, this filter is clearly 17 samples long.

For the DAC, there are also several choices. The typical one is interpolation filter A. Table 2-24 says that it has a group delay of 21/fs. So, it is clearly 21 samples long.

Because the AIC3206 allows you to choose other versions of the decimation and interpolation filters (unfortunately the STGL5000 has no such flexibility?) it is possible on the AIC3206 to choose filters that have less delay. For example, if you swap both the ADC and DAC to filter option "C", the delay drops to 11 samples for the ADV and 13 samples for the DAC. The trade-off is that you might not like the freq response that results.

Regardless, it is nice that TI makes this info available. Yes, it's buried pretty deep in the docs, but at least it is there.

Chip
 
Status
Not open for further replies.
Back
Top