This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
we have the following system which works with synchronous clocks. One AIC3204 is the i2s master of the whole system and generates the clocks for all i2s slaves. Servicing of c5535 i2s is done by dma. The c5535 just loop through the audio data at the moment. The audio transfers work, but sometimes the audio is scrambled after power on. When we reinit the codec and the dsp i2s and dma, scrambling dissappears. What could be the reason for this scrambling?!
The init procedure of AIC3204 is as follows. The only difference in initialization of master or slave is the register 27 in page 0 (marked in red).
CSL_Status AIC3254_Init(Bool master)
{
CSL_Status result = CSL_SOK;
result = AIC3254_Write(0, 0); // write 0 to page register to select page 0
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(1, 1); // reset codec
if (result != CSL_SOK)
{
return result;
}
/* Select the PLL input and CODEC_CLKIN */
/* PLL input is assumed as 12MHz */
result = AIC3254_Write(4, 0x03);
if (result != CSL_SOK)
{
return result;
}
/*
PLL_CLK = (PLL_CLKIN * R * J.D)/P
DAC_FS = PLL_CLK/(NDAC * MDAC * DOSR)
ADC_FS = PLL_CLK/(NADC * MADC * AOSR)
DAC_CLK = PLL_CLK/NDAC
BCLK = DAC_CLK/BDIV_CLKIN
DAC_FS, BCLK:
16 kHz: P=1, R=1, J=7, D=1754 (0x6da)
NDAC=6, MDAC=7, DOSR=128
BCLK = 28
PLL_CLK = (12e6 * 1 * 7.1754)/1 = 86104800
DAC_FS = PLL_CLK/(6 * 7 * 128) = 16016.52
BCLK = PLL_CLK/NDAC/BCLK = 28701600/2/28 = 512528.57
ADC_FS:
16 kHz: P=1, R=1, J=7, D=1754 (0x6da)
NADC=6, MADC=7, AOSR=128
ADC_FS = PLL_CLK/(2 * 7 * 128) = 16016.52
*/
// Power up the PLL and set P = 1 & R = 1
result = AIC3254_Write(5, 0x91); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set J value to 7
result = AIC3254_Write(6, 0x07); // 16khz
if (result != CSL_SOK)
{
return result;
}
//
// CODEC_CLKIN = 12MHz *(R * J.D)/P
//
// Set D value(MSB) = 0x06
result = AIC3254_Write(7, 0x6); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set D value(LSB) = 0xda
result = AIC3254_Write(8, 0xda); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set NDAC to 6 - this along with BCLK N configures BCLK
result = AIC3254_Write(11, 0x86); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set MDAC to 7
result = AIC3254_Write(12, 0x87); // 16khz
if (result != CSL_SOK)
{
return result;
}
//
// DAC_FS = (12MHz *(R * J.D)/P)/(NDAC * MDAC * DOSR)
//
/* Set DAC OSR MSB value to 0 */
result = AIC3254_Write(13, 0x0);
if (result != CSL_SOK)
{
return result;
}
// Set DAC OSR LSB value to 128
// This generates the DAC_FS = 16KHz
result = AIC3254_Write(14, 128); // 16khz
if (result != CSL_SOK)
{
return result;
}
//
// BCLK = (12MHz *(R * J.D)/P)/(NDAC * BCLK N)
//
// Set BCLK N value to 28
// This along with NDAC generates the BCLK = 512 kHz
// BCLK = (12MHz *(R * J.D)/P)/(NDAC * BCLK N)
result = AIC3254_Write(30, 0x9C); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set ADC_FS to 16 kHZ
// Set NADC to 6
result = AIC3254_Write(18, 0x86); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set MADC to 7
result = AIC3254_Write(19, 0x87); // 16khz
if (result != CSL_SOK)
{
return result;
}
// Set ADC OSR LSB value to 128
// This generates the ADC_FS = 16KHz
// ADC_FS = (12MHz *(R * J.D)/P)/(NADC * MADC * AOSR)
result = AIC3254_Write(20, 128); // 16khz
if (result != CSL_SOK)
{
return result;
}
if (master == TRUE)
{
result = AIC3254_Write(27,0xd); // BCLK and WCLK is set as op to AIC3254(Master)
if (result != CSL_SOK)
{
return result;
}
}
result = AIC3254_Write(0, 1); // select page 1
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(51, 0x48); // power up Mic Bias using LDO-IN
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(1, 0x8); // Disable crude AVDD generation from DVDD
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(2, 1); // Enable Analog Blocks and internal LDO
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(20, 0); // Depop reg R=6K,t=8RC(2.256ms),ramp time=0ms
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(14, 0x8); // LDAC AFIR routed to LOL
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(15, 0x8); // RDAC AFIR routed to LOR
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(52, 0xC0); // Route IN1L to LEFT_P with 40K input impedance
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(54, 0xC0); // Route Common Mode to LEFT_M with impedance of 40K
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(55, 0xC0); // Route IN1R to RIGHT_P with 40K input impedance
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(57, 0xC0); // Route Common Mode to RIGHT_M with impedance of 40K
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(59, 0x00); // Unmute Left MICPGA, Gain = 0 dB
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(60, 0x00); // Unmute Right MICPGA, Gain = 0 dB
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(0, 0); // write 0 to page register to select page 0
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(86, 0x90); // Enable LEFT AGC, target level -8dBFs
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(94, 0x90); // Enable RIGHT AGC, target level -8dBFs
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(64, 0x2); // DAC left vol=right vol
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(63, 0xd4); // DAC power up left, right data paths and set channel
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(64, 0xc); // DAC mute
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(0, 1); // select page 1
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(18, 0); // unmute LOL, 0dB gain
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(19, 0); // unmute LOR, 0dB gain
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(9, 0x0C); // power up LOL, LOR
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(0, 0x0); // select page 0
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(64, 0x2); // unmute DAC with right vol=left vol
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(65, 0); // set DAC gain to 0dB
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(66, 0); // set DAC gain to 0dB
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(81, 0xc0); // Powerup left and right ADC
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(82, 0x00); // Unmute left and right ADC
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(83, 0); // Set left ADC Gain to 0dB
if (result != CSL_SOK)
{
return result;
}
result = AIC3254_Write(84, 0); // Set right ADC Gain to 0dB
if (result != CSL_SOK)
{
return result;
}
return result;
}
Initialization of C5535 i2s is as follows:
CSL_Status I2sInit(void)
{
CSL_Status status;
I2S_Config hwConfig;
hI2sLoc->configured = false;
/* Set the value for the configure structure */
hwConfig.dataFormat = I2S_DATAFORMAT_LJUST;
hwConfig.dataType = I2S_STEREO_ENABLE;
hwConfig.loopBackMode = I2S_LOOPBACK_DISABLE;
hwConfig.fsPol = I2S_FSPOL_LOW; // I2S_FSPOL_HIGH
hwConfig.clkPol = I2S_RISING_EDGE; // I2S_FALLING_EDGE
hwConfig.datadelay = I2S_DATADELAY_ONEBIT;
hwConfig.datapack = I2S_DATAPACK_ENABLE;
hwConfig.signext = I2S_SIGNEXT_DISABLE;
hwConfig.wordLen = I2S_WORDLEN_16;
hwConfig.i2sMode = I2S_SLAVE;
hwConfig.clkDiv = I2S_CLKDIV2; // don't care for slave mode
hwConfig.fsDiv = I2S_FSDIV32; // don't care for slave mode
hwConfig.FError = I2S_FSERROR_DISABLE;
hwConfig.OuError = I2S_OUERROR_DISABLE;
/* Configure hardware registers */
status = I2S_setup(hI2sLoc, &hwConfig);
if (status != CSL_SOK)
{
printf("Setup I2S Loc Module failed\n");
return (status);
}
hI2sRem->configured = false;
/* Set the value for the configure structure */
hwConfig.dataFormat = I2S_DATAFORMAT_LJUST;
hwConfig.dataType = I2S_STEREO_ENABLE;
hwConfig.loopBackMode = I2S_LOOPBACK_DISABLE;
hwConfig.fsPol = I2S_FSPOL_LOW; // I2S_FSPOL_HIGH
hwConfig.clkPol = I2S_RISING_EDGE; // I2S_FALLING_EDGE
hwConfig.datadelay = I2S_DATADELAY_ONEBIT;
hwConfig.datapack = I2S_DATAPACK_ENABLE;
hwConfig.signext = I2S_SIGNEXT_DISABLE;
hwConfig.wordLen = I2S_WORDLEN_16;
hwConfig.i2sMode = I2S_SLAVE;
hwConfig.clkDiv = I2S_CLKDIV2; // don't care for slave mode
hwConfig.fsDiv = I2S_FSDIV32; // don't care for slave mode
hwConfig.FError = I2S_FSERROR_DISABLE;
hwConfig.OuError = I2S_OUERROR_DISABLE;
/* Configure hardware registers */
status = I2S_setup(hI2sRem, &hwConfig);
if (status != CSL_SOK)
{
printf("Setup I2S Rem failed\n");
return (status);
}
return CSL_SOK;
}
I2s WCLK and BCLK look as follows:
The peaks at the BCLK occur due to not connected ground on oscilloscope.
I2s WCLK and Data:
I2s BCLK and Data:
We don't know if the initialization of the aic3204 and c5535 i2s is correct and match each other. We took them out of example code from ti (Beam form application and C55x USB Audio Class Framework). It would be fine if you could take a look at the init procedures and the screenshots. Perhaps you can see the reason for the scrambled sound?! As already mentioned, scrambling only appears sporadic after init of codec and c5535 i2s. When we do a reinit, it dissappears.
Is the data delay of one bit correct? In my understanding this means that the data is valid after the second rising edge on BCLK after WCLK change.But then only 15 rising BCLK edges remain?!?! What about the c5535 Frame Clock Timing Requirement in Slave Mode mentioned in chapter 2.4 in http://www.ti.com/lit/ug/sprufp4a/sprufp4a.pdf?? It is mentioned that the WCLK can be delayed by a RC combination. But why is the RC placed at the DOUT pin and not at the WCLK pin in Figure 6??
Thanks in advance and have a nice day
Marc
Hello Marc,
Q: Are these scope shots captured while the scrambled audio is happening?
Q: Did you compare the signals during scrambled data verses when the data is not scrambled sounding? Can you attach both here?
Q: Can you describe the scrambled sound a bit?
Q: Are you running from CCS or from the bootloader (stand-alone)?
Q: Can you halt the execution with a JTAG emulator while the scrambled audio is happening and dump the all of the I2S registers? If you are running from a bootloaded image, connect to the target without using any GEL file init so it preserves the state of the execution.
I would check first if hwConfig.i2sMode = I2S_SLAVE. Scrambled audio can occur when there are two masters driving the I2S CLK and FS signals.
Perhaps you can do some debugging with I2S_DATAPACK disabled also...
=-=-
Marc48067 said:
What about the c5535 Frame Clock Timing Requirement in Slave Mode mentioned in chapter 2.4 in www.ti.com/.../sprufp4a.pdf It is mentioned that the WCLK can be delayed by a RC combination. But why is the RC placed at the DOUT pin and not at the WCLK pin in Figure 6??
Marc48067 said:
Is the data delay of one bit correct?
Hi Mark,
thanks a lot for the usefull information. I inserted a wait time of 5ms after codec reset and made a change in the order of dma init. It seems as if the distorted sound, which occurred sometimes after power up, is gone now.
At the moment we manually generate a sinus table in the dsp and send it to the codec dac via i2s. When we generate positive and negative sinus values, the output at the line out doesn't loot like a sinus. Does the dac not understand two's complement negative numbers? When the sinus table just contains positive values, we can see the sinus at the line out. But the sinus only looks good as long as the digital values are in the range 0...32767 (15Bit). When we use greater values, the sinus is completely distorted. Does the dac only process 15Bit positive numbers?
15 Bit sinus table:
for(i = 0; i < 16; i++)
{
sinus[i] = (sin((i*2*3.14)/16)*0x3FFF)+0x3FFF;
}
table:
16383
22649
27962
31515
32765
31525
27981
22673
16409
10140
4821
1260
0
1230
4766
10068
Line out signal at aic3204:
16 Bit sinus table:
for(i = 0; i < 16; i++)
{
sinus[i] = (sin((i*2*3.14)/16)*0x3FFF)+0x3FFF+20;
}
table:
16403
22669
27982
31535
32785
31545
28001
22693
16429
10160
4841
1280
20
1250
4786
10088
Line out signal at aic3204:
Thanks a lot
Marc
Hi Mark,
one additional question. We want to feed the i2s data coming from the aic3204 adc into aer/aec echo cancellation library functions. And the processed data is sent to the dac. Now I am not sure if the data format of the codec matches those of the library functions.
The library functions use this format for the samples:
/*! Portable linear sample.
*
* Portable linear sample has at least 16 bits of precision.
*
* <b>Suggested usage:</b> linear signal samples are always in [-32768, 32767]
* range. They may be obtained from the PCM compressed samples using
* appropriate expansion lookup table. Internally, linSample is based on
* the Fract type. Signal processing algorithms assume that the analog sine
* wave of +3dBm power is scaled into a digital sine wave that has a full
* scale amplitude of 32768. On a fixed point platform linear samples are
* in Q0 format.
*
* <b>NOTE:</b> On floating point platforms linear samples would also have the
* range [-32768.0, 32767.0].
*/
typedef tint linSample;
Our codec uses 16Bit data. Is this data signed or unsigned? Do we have to set the sign extend bit in dsp i2s initialization or use a look up table? As mentioned above, the dac had some problems with our self generated sinus when it contains negative numbers?!
Thanks in advance
Marc
Hi,
I did some more tests and found out that the sinus table wasn't correctly copied into the dma out buffer. Data was corrupt when negative and positive values were put into the U32 dma out buffer. This is now fixed and the dac works with positive and negative sinus values. So I think the codec works with 16 Bit signed values which can directly be processed by the algorithms. Am I right here?
Thanks a lot
Marc
Hi Marc
Were you able to resolve the issues you were encountering here?
Regards
Mukul
Hi Mukul,
thanks for your post. Yes, as already mentioned we were able to solve the problem (see answers above).
Thanks for your support
Marc