AnsweredAssumed Answered

STM32F7 I2S DMA data shift (flushing issue)

Question asked by klem on Nov 22, 2017
Latest reply on Nov 23, 2017 by waclawek.jan


I'm trying to use the STM32F723 I2S3 peripheral in reception (with a circular DMA).

But I'm having an issue : when I2S is started for the first time everything works fine. But if I stop/restart it, the received samples are shifted of 16bits.


It looks like when I disable the I2S, its 16bits RX buffer is not completely flushed and shift my samples next time I restart it.

Unfortunately I was not able to find a solution to flush that RX buffer, I tried to flush it manually by reading SPI3_RXCRCR buffer while SPI3_SR.FRLVL is not equal to zero. But it doesn't work.

I tried to deinit and reinit I2S but it doesn't fix the problem.

The only workaround I found is to hard reset the I2S3/SPI3 peripheral with a : __HAL_RCC_SPI3_FORCE_RESET();


The I2S3 is configured in slave to receive a 24bits stereo signals and store it in a 32bits array in memory.

The DMA is configured in circular mode and data alignement is HALF_WORD on peripheral side and WORD on memory side.


To start and stop I2S I use the HAL functions :



Here are my I2S and DMA config :

    hi2s3.Instance = SPI3;
    hi2s3.Init.Mode = I2S_MODE_SLAVE_RX;
    hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;
    hi2s3.Init.DataFormat = I2S_DATAFORMAT_24B;
    hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
    hi2s3.Init.AudioFreq = 192000;
    hi2s3.Init.CPOL = I2S_CPOL_LOW;
    hi2s3.Init.ClockSource = I2S_CLOCK_PLL;

    hdma_spi3_rx.Instance = DMA1_Stream0;
    hdma_spi3_rx.Init.Channel = DMA_CHANNEL_0;
    hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_spi3_rx.Init.Mode = DMA_CIRCULAR;
    hdma_spi3_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;


Doyou have any idea where the problem could come from ?

Thank you.