AnsweredAssumed Answered

STM32F407 I2S High speed trouble

Question asked by alex.001.T on Mar 9, 2013
Latest reply on Mar 15, 2013 by malund.erik
Hello peolpes,

maybe somebody can help me.
For a testing I use two I2S - one(I2S3) for transmitting, second (I2S2) - for receiving, phisicaly connected at the PCB.
At both I use Double Buffer DMA.
I fill the sending buffer with the constant, and looking for a receiving buffer to get the same values.
I use external clock at PC9 49MHz (by the way - what is the maximum alloud frequency?).
At all speeds up to 96K it works fvery goood, but at 192K it totaly not work!
Everytime I get a failed values in the receiving buffer, also frame error at I2S2 (receiver).
I'm doing everithing according to the datasheet and errata sheet, but I thin something wrong in initialisation (maybe I forget to clear some flags?)

// this is receiver r init:
 
void  I2S2_RCV_Init(void)
{
 I2S_InitTypeDef I2S2_InitStructure;
 
  //------------------------------------------------
   I2SGPIO_Init();
  //
  I2S_StructInit(&I2S2_InitStructure);
  I2S2_InitStructure.I2S_AudioFreq  =I2S_AudioFreq_Default;
  I2S2_InitStructure.I2S_CPOL       = I2S_CPOL_Low;
  I2S2_InitStructure.I2S_Mode       = I2S_Mode_SlaveRx;
  I2S2_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
  I2S2_InitStructure.I2S_Standard   = I2S_Standard_MSB;
   I2S2_InitStructure.I2S_DataFormat  = I2S_DataFormat_32b;
  
// wait for WS=1 the for WS=0, i.e. \_ front
  WaitForWCLK(1));
  WaitForWCLK(0));
 
  I2S_Init(SPI2, &I2S2_InitStructure);
 
  I2S2_DMA_Init();
  DMA_Cmd( Rx_DMAStream, ENABLE );
  I2S_Cmd(SPI2, ENABLE);
}
 
// WS waiting function:
static u8 WaitForWCLK(u8 edge)
{
   TOTmr1ms = WCLK_TIMEOUT;  // TOTmr1ms is decremented in SysTick interrupt
   if(edge>0){ // wait for WCLK=1
        while (0==(GPIOB->IDR & GPIO_Pin_12)){
            if(TOTmr1ms==0)
                return 0;
        }
        return 1;
   }else{    // wait for WCLK=0
        while (0!=(GPIOB->IDR & GPIO_Pin_12)){
            if(TOTmr1ms==0)
                return 0;
        }
        return 1;
 
   }
}

DMA Function:
static __INLINE void I2S2_DMA_Init( void )  // ******* D M A RECEIVER ****************
{
 DMA_InitTypeDef DMA_InitStruct;
 NVIC_InitTypeDef   NVIC_InitStructure;
   
    DMA_Cmd( Rx_DMAStream, DISABLE );
    while( DMA_GetCmdStatus( Rx_DMAStream ) == ENABLE );                // wait for the last DMA end
 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
   
    // From:
    DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR);      // I2S Data
    // To:
    DMA_InitStruct.DMA_Memory0BaseAddr  = (u32)&DMARCVBUF[0][0];    // memory start
    DMA_InitStruct.DMA_BufferSize       = DMARCVBUF_SIZE;               // length
 
    // With parameters:
    DMA_InitStruct.DMA_Channel          = DMA_Channel_0;
    DMA_InitStruct.DMA_DIR          = DMA_DIR_PeripheralToMemory;                   // direction
    DMA_InitStruct.DMA_PeripheralInc        = DMA_PeripheralInc_Disable;        //
    DMA_InitStruct.DMA_MemoryInc        = DMA_MemoryInc_Enable;        
    DMA_InitStruct.DMA_PeripheralDataSize   = DMA_PeripheralDataSize_HalfWord;  // 16 bit  per
    DMA_InitStruct.DMA_MemoryDataSize   = DMA_MemoryDataSize_HalfWord;      // 16 bit memory
    DMA_InitStruct.DMA_Mode             = DMA_Mode_Circular;                // circ
    DMA_InitStruct.DMA_Priority             = DMA_Priority_High;                // prority
    DMA_InitStruct.DMA_FIFOMode         = DMA_FIFOMode_Disable;
    DMA_InitStruct.DMA_MemoryBurst      = DMA_MemoryBurst_Single;
    DMA_InitStruct.DMA_PeripheralBurst  = DMA_PeripheralBurst_Single;
   
    DMA_Init( Rx_DMAStream, &DMA_InitStruct );                          // Init New
   
    DMA_ITConfig( DMA1_Stream3, DMA_IT_TC, ENABLE );
 
    DMA_DoubleBufferModeConfig(Rx_DMAStream, (uint32_t)RCVBuffer_2, DMA_Memory_0 );
    DMA_DoubleBufferModeCmd( Rx_DMAStream, ENABLE );
 
    SPI_I2S_DMACmd( SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
}

P.S. CPU - STM32F407VG

Outcomes