cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407VGT6 and I2S

rx9cim
Associate II
Posted on July 16, 2012 at 18:06

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;//âûõîä AF

GPIOC->OSPEEDR=0;

GPIOC->OSPEEDR|=0x1000;

GPIOC->AFR[0]|=0x05000000;//AF5-MCKI2S

RCC->AHB1ENR|=RCC_AHB1ENR_GPIOBEN;//âêëþ÷èë GPIOB

GPIOB->MODER|=GPIO_MODER_MODER12_1;//âûõîä AF

GPIOB->MODER|=GPIO_MODER_MODER13_1;//âûõîä AF

GPIOB->MODER|=GPIO_MODER_MODER14_1;//âûõîä AF

GPIOB->MODER|=GPIO_MODER_MODER15_1;//âûõîä AF

GPIOB->OSPEEDR=0;

GPIOB->OSPEEDR|=0x55000000;

GPIOB->AFR[1]|=0x56550000;//AF5-I2S/SPI

RCC->PLLI2SCFGR=0;//îáíóëÿþ

RCC->PLLI2SCFGR|=PLLI2SN(429);//

RCC->PLLI2SCFGR|=PLLI2SR(4);//

RCC->CR|=RCC_CR_PLLI2SON;//Âêëþ÷èë PLL  I2S

#ifndef SIMULATOR

while ((RCC->CR&RCC_CR_PLLI2SRDY)!=RCC_CR_PLLI2SRDY);//ïîêà çàðàáîòàåò PLL

#endif

RCC->APB1ENR|=RCC_APB1ENR_SPI2EN;//âêëþ÷èë Spi2

SPI2->I2SCFGR|=SPI_I2SCFGR_I2SMOD;//âêëþ÷èë I2S

SPI2->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;//âêëþ÷èë I2S

I2S2ext->I2SCFGR|=SPI_I2SCFGR_DATLEN_0;//24áèò äàííûå

I2S2ext->I2SCFGR|=SPI_I2SCFGR_CHLEN;//32áèò äëèíà äàííûõ 

I2S2ext->I2SCFGR|=I2SCFG(0);//�åæèì Ñëýéâ - òðàíñìèòòåð

SPI2->CR2|=SPI_CR2_RXDMAEN;//DMA

SPI2->I2SCFGR|=SPI_I2SCFGR_I2SE;//âêëþ÷èë SPI

delay(5);

I2S2ext->I2SCFGR|=SPI_I2SCFGR_I2SE;//âêëþ÷èë SPI

}

5 REPLIES 5
Posted on July 17, 2012 at 12:16

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.

JW

rx9cim
Associate II
Posted on July 18, 2012 at 11:34

In my case it is has not effect

Posted on July 19, 2012 at 14:56

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.

JW
rx9cim
Associate II
Posted on July 20, 2012 at 22:53

Thanks for you, waclawek.jan!

I have stm32f407 in LQFP100 package, revision A. Indeed, in my stm32f407 MCLK generates only in Master recieve mode, independ from select formats and protocols.

You has written, that codecs usually work in two's compelement, so if its input is close to zero, it will output numbers around 0xFFFFxx..0x0000xx. Please correct me:

if input of ADC conect to GND (Uinput=0), codec send 0xFFFFxx(first 16 bit halfword) and 0x00xx(second byte) in Philips protocol?  That is right?

Posted on July 24, 2012 at 17:40

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