I have a project using the EZDSP5535, which uses I2S interrupt mode to read audio data from the codec ADC (eventually process it) and output it to the codec DAC.
I believe I have configured the codec for 48k ADC and DAC, and the I2S for instance 2, as master.
The BCLK on pin 2 of the codec shows 1.53 MHz as expected, until the program runs, at which time the clock appears corrupted with both some higher and lower frequencies, as if there was some bus contention. This produces a corrupted and noisy audio output with no audio input.
Is someone else using interrupt driven audio I/O? I thought this would be the easiest way to get this going, and efficient enough) but it is frustrating me.
Here is the codec setup:
void CodecInit()
{
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 1, 0x01 ); // Reset codec
EZDSP5535_waitusec(1000); // Wait 1ms after reset
//power
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 1, 0x08 ); // Disable crude AVDD generation from DVDD
AIC3204_rset( 2, 0x01 ); // Enable Analog Blocks, use LDO power
AIC3204_rset( 123,0x05 ); // Force reference to power up in 40ms
EZDSP5535_waitusec(50000); // Wait at least 40ms
// PLL and Clocks config
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 4, 0x03 ); // PLL setting: PLLCLK <- MCLK, CODEC_CLKIN <-PLL CLK
AIC3204_rset( 6, 0x07 ); // PLL setting: J=7
AIC3204_rset( 7, 0x06 ); // PLL setting: HI_BYTE(D=1680)
AIC3204_rset( 8, 0x90 ); // PLL setting: LO_BYTE(D=1680)
AIC3204_rset( 30, 0x88 ); // For 32 bit clocks per frame in Master mode ONLY
// BCLK=DAC_CLK/N =(12288000/8) = 1.536MHz = 32*fs
AIC3204_rset( 5, 0x91 ); // PLL setting: Power up PLL, P=1 and R=1
EZDSP5535_waitusec(10000); // Wait for PLL to come up
AIC3204_rset( 27, 0x0C ); // BCLK and WCLK are set as o/p; AIC3204(Master)
AIC3204_rset( 28, 0x00 ); // Data ofset = 0
AIC3204_rset( 13, 0x00 ); // Hi_Byte(DOSR) for DOSR = 128 decimal or 0x0080 DAC oversamppling
AIC3204_rset( 14, 0x80 ); // Lo_Byte(DOSR) for DOSR = 128 decimal or 0x0080
AIC3204_rset( 20, 0x80 ); // AOSR for AOSR = 128 decimal or 0x0080 for decimation filters 1 to 6
AIC3204_rset( 11, 0x87 ); // Power up NDAC and set NDAC value to 2
AIC3204_rset( 12, 0x82 ); // Power up MDAC and set MDAC value to 7
AIC3204_rset( 18, 0x87 ); // Power up NADC and set NADC value to 7
AIC3204_rset( 19, 0x82 ); // Power up MADC and set MADC value to 2
AIC3204_rset( 29, 0x02 ); // SET BCLK from ADC Clk
AIC3204_rset( 31, 0x02 ); //
/* AIC3204_rset( 32, 0x00 ); //
AIC3204_rset( 33, 0x00 ); //
AIC3204_rset( 28, 0x00 ); //
*/
/* DAC ROUTING and Power Up */
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 12, 0x08 ); // LDAC AFIR routed to HPL
AIC3204_rset( 13, 0x08 ); // RDAC AFIR routed to HPR
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 64, 0x02 ); // Left vol=right vol
AIC3204_rset( 65, 0x00 ); // Left DAC gain to 0dB VOL; Right tracks Left
AIC3204_rset( 63, 0xd4 ); // Power up left,right data paths and set channel
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 16, 0x00 ); // Unmute HPL , 0dB gain
AIC3204_rset( 17, 0x00 ); // Unmute HPR , 0dB gain
AIC3204_rset( 9 , 0x30 ); // Power up HPL,HPR
EZDSP5535_waitusec(100 ); // Wait
/* ADC ROUTING and Power Up */
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset(51,0x48); //mic bias
AIC3204_rset( 52, 0x30 ); // STEREO 1 Jack
// IN2_L to LADC_P through 40 kohm
// AIC3204_rset( 55, 0x30 ); // IN2_R to RADC_P through 40 kohmm
AIC3204_rset( 54, 0xC0 ); // CM_1 (common mode) to LADC_M through 40 kohm
// AIC3204_rset( 57, 0xc0 ); // CM_1 (common mode) to RADC_M through 40 kohm
AIC3204_rset( 59, 0x00 ); // MIC_PGA_L unmute
AIC3204_rset( 60, 0x00 ); // MIC_PGA_R unmute
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 81, 0xc0 ); // Powerup Left and Right ADC
AIC3204_rset( 82, 0x00 ); // Unmute Left and Right ADC
AIC3204_rset( 0, 0x00 ); // Select page 0
EZDSP5535_waitusec(100 ); // Wait
}
and here is the I2S setup:
void i2sInit(void )
{
I2S_Config hwConfig;
CSL_IRQ_Config rxconfig;
CSL_IRQ_Config txconfig;
/* Set the value for the configure structure */
hwConfig.dataType = I2S_STEREO_ENABLE;
hwConfig.loopBackMode = I2S_LOOPBACK_DISABLE;
hwConfig.fsPol = I2S_FSPOL_HIGH;
hwConfig.clkPol = 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_MASTER;
hwConfig.FError = I2S_FSERROR_ENABLE;
hwConfig.OuError = I2S_OUERROR_ENABLE;
hwConfig.clkDiv = I2S_CLKDIV4;
hwConfig.fsDiv = I2S_FSDIV32;
hwConfig.dataFormat = I2S_DATAFORMAT_LJUST;
/* Configure hardware registers */
i2sHandle = I2S_open(I2S_INSTANCE2, I2S_INTERRUPT, I2S_CHAN_STEREO);
I2S_setup(i2sHandle, &hwConfig);
/* Clear any pending interrupts */
IRQ_clearAll();
/* Disable all the peripheral interrupts */
IRQ_disableAll();
IRQ_setVecs((Uint32)(&VECSTART));
rxconfig.funcAddr = &i2s_rxIsr;
txconfig.funcAddr = &i2s_txIsr;
IRQ_plug(RCV2_EVENT, rxconfig.funcAddr);
IRQ_plug(XMT2_EVENT, txconfig.funcAddr);
I2S_transEnable(i2sHandle, TRUE);
}
and the read and write ISRS:
interrupt void i2s_rxIsr()
{
IRQ_globalDisable();
I2S_read(i2sHandle, ReadData, 4);
/* if(isrcntr==7000)
{
SaveData[0]=ReadData[0];
SaveData[1]=ReadData[1];
SaveData[2]=ReadData[2];
SaveData[3]=ReadData[3];
}*/
isrcntr++;
IRQ_globalEnable();
}
interrupt void i2s_txIsr()
{
IRQ_globalDisable();
I2S_write(i2sHandle, ReadData, 4);
txisrcntr++;
IRQ_globalEnable();
}
Is there anything obvious (not so obvious to a new user) which is missing or wrong?
Thanks.