2012-07-16 09:06 AM
Hi all!!!
Please help me. A have problem with I2S interface in this MC. I need to work with audio codec cs4221 by means of I2S. I setup I2S2 interface in full-duplex mode (I2S2- Master reciev, I2S2ext - Slave TX). Data lenghth - 24 bit, chanel length - 32 bit. The problem it is that sometimes (every jne of three) i recieve frame with value 0xfffe or something like this. I do not understand, what is the problem? And I use tme I2S_MCK (256*22050=5644800Hz) for CS4221, Fs=22050Hz.And Another - why I2S_MCK presents on PC6 (pin 63 in LQFP100) only when I2S is Master-recieve, not Master-TX? About this says nothing in datasheet.my source code:void I2S_init (void){ /*Ã�à ñòðîéêà I2S ÷à ñòîòà äèñêðåòèçà öèè 22050Ãö f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN / PLLM) f(PLL I2S clock output) = f(VCO clock) / PLLI2SR */RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;//âêëþ÷èë GPIOC GPIOC->MODER|=GPIO_MODER_MODER6_1;//âûõîä AFGPIOC->OSPEEDR=0;GPIOC->OSPEEDR|=0x1000;GPIOC->AFR[0]|=0x05000000;//AF5-MCKI2SRCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN;//âêëþ÷èë GPIOBGPIOB->MODER|=GPIO_MODER_MODER12_1;//âûõîä AFGPIOB->MODER|=GPIO_MODER_MODER13_1;//âûõîä AFGPIOB->MODER|=GPIO_MODER_MODER14_1;//âûõîä AFGPIOB->MODER|=GPIO_MODER_MODER15_1;//âûõîä AFGPIOB->OSPEEDR=0;GPIOB->OSPEEDR|=0x55000000;GPIOB->AFR[1]|=0x56550000;//AF5-I2S/SPIRCC->PLLI2SCFGR=0;//îáÃóëÿþRCC->PLLI2SCFGR|=PLLI2SN(429);//RCC->PLLI2SCFGR|=PLLI2SR(4);//RCC->CR|=RCC_CR_PLLI2SON;//Âêëþ÷èë PLL I2S#ifndef SIMULATORwhile ((RCC->CR&RCC_CR_PLLI2SRDY)!=RCC_CR_PLLI2SRDY);//ïîêà çà ðà áîòà åò PLL#endifRCC->APB1ENR|=RCC_APB1ENR_SPI2EN;//âêëþ÷èë Spi2SPI2->I2SCFGR|=SPI_I2SCFGR_I2SMOD;//âêëþ÷èë I2SSPI2->I2SCFGR|=SPI_I2SCFGR_DATLEN_0;//24áèò äà ÃÃûåSPI2->I2SCFGR|=SPI_I2SCFGR_CHLEN;//32áèò äëèÃà äà ÃÃûõ SPI2->I2SPR=I2SDIV(9);//SPI2->I2SPR|=I2SODD(1);//SPI2->I2SCFGR|=I2SCFG(3);//Ã�åæèì Ìà ñòåð - ïðèìåÃèêSPI2->I2SPR|=I2SMCKOE(1);//âûõîä Ìà ñòåð êëîêà (I2S2ext->I2SCFGR)=0;I2S2ext->I2SCFGR|=SPI_I2SCFGR_I2SMOD;//âêëþ÷èë I2SI2S2ext->I2SCFGR|=SPI_I2SCFGR_DATLEN_0;//24áèò äà ÃÃûåI2S2ext->I2SCFGR|=SPI_I2SCFGR_CHLEN;//32áèò äëèÃà äà ÃÃûõ I2S2ext->I2SCFGR|=I2SCFG(0);//Ã�åæèì Ñëýéâ - òðà ÃñìèòòåðSPI2->CR2|=SPI_CR2_RXDMAEN;//DMASPI2->I2SCFGR|=SPI_I2SCFGR_I2SE;//âêëþ÷èë SPIdelay(5);I2S2ext->I2SCFGR|=SPI_I2SCFGR_I2SE;//âêëþ÷èë SPI}2012-07-17 03:16 AM
Have a look at the Errata, chapter 2.4.
It suggest to start (enable) the two peripherals in a reverse order than you did, i.e. the Slave (I2SExt) first, the Master second. JW2012-07-18 02:34 AM
In my case it is has not effect
2012-07-19 05:56 AM
I don't understand exactly what your problem is, just trying to point out things I found to be problematic.
Note that the data register is 16-bit long, so in 24-bit mode you have to read it two times per one sample. As I2S is MSB-first, the first reading returns bits 8..23, the second reading returns bits 0..7 but in the upper 8 bits of the read 16-bit halfword. So, if the codec transmits 0x123456, your first read is 0x1234 and the second is 0x5600. Note that codecs usually work in two's compelement, so if its input is close to zero, it will output numbers around 0xFFFFxx..0x0000xx. Note also, that in I2S mode, you don't use the MISO and MOSI pins of I2S2, but the I2S2_SD pin of I2S2, and the I2S2Ext_SD pin of I2S2Ext (which is in the AF6 group! whereas the I2S2 pins are in the AF5 group!). While debugging, you might find it useful first to loop back (connect), without having the codec connected. A logic analyser or oscilloscope may come handy too. I have tried I2S2 on '407 in both master transmit and master receive mode, and MCLK was properly output on PC6 in both modes. JW2012-07-20 01:53 PM
2012-07-24 08:40 AM
In an ideal world, if you ground the ADC input, a 24-bit codec would output 0x000000 onto the data line (to be ''seen'' by an oscilloscope or logic analyzer), and you would read it out of the I2S module of ST32F4xx as 0x0000 and 0x0000.
Now if the input or the reference fluctuates a little bit, the readout would go say one bit up or down, so the codec would output 0x000001 or 0xFFFFFF; you would then read it out as either 0x0000 and 0x0100; or as 0xFFFF and 0xFF00. JW