cancel
Showing results for 
Search instead for 
Did you mean: 

I2S Slave Receive Mode and DMA receives wrong samples after a random amount of time.

Mehrdad FP
Associate
Posted on December 04, 2017 at 12:03

Hi All,

I am using an SPDIF receiver, It has been connected to the STM32F401 I2S. The diagram is as bellow,

SPDIF Receiver (I2S Master)  -> STM32F401 (I2S slave Receiver DMA) -> STM32F401 (DAC DMA) -> STM32F401 analog output

For a while system works perfect and I can see the analog output follows the signals which SPDIF receiver gets. But after a random amount of time which is vary from 3 minutes to 40 minutes suddenly the STM32F401's I2S DMA starts receiving wrong values. 

static void MX_I2S2_Init(void)

{

hi2s2.Instance = SPI2;

hi2s2.Init.Mode = I2S_MODE_SLAVE_RX;

hi2s2.Init.Standard = I2S_STANDARD_MSB;

hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;

hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;

hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;

hi2s2.Init.CPOL = I2S_CPOL_LOW;

hi2s2.Init.ClockSource = I2S_CLOCK_PLL;

hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;

if (HAL_I2S_Init(&hi2s2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s)

{

GPIO_InitTypeDef GPIO_InitStruct;

if(hi2s->Instance==SPI2)

{

/* USER CODE BEGIN SPI2_MspInit 0 */

/* USER CODE END SPI2_MspInit 0 */

/* Peripheral clock enable */

__HAL_RCC_SPI2_CLK_ENABLE();

/**I2S2 GPIO Configuration

PC3 ------> I2S2_SD

PB10 ------> I2S2_CK

PB12 ------> I2S2_WS

*/

GPIO_InitStruct.Pin = GPIO_PIN_3;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* I2S2 DMA Init */

/* SPI2_RX Init */

hdma_spi2_rx.Instance = DMA1_Stream3;

hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

hdma_spi2_rx.Init.Mode = DMA_CIRCULAR;

hdma_spi2_rx.Init.Priority = DMA_PRIORITY_HIGH;

hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

__HAL_LINKDMA(hi2s,hdmarx,hdma_spi2_rx);

/* USER CODE BEGIN SPI2_MspInit 1 */

/* USER CODE END SPI2_MspInit 1 */

}

}

in the main() after making sure the I2S_WS is low I start the I2S DMA in the circular mode like below where

i2s_rx_buff is quite huge uint16_t type buffer 

.

HAL_I2S_Receive_DMA(&hi2s2, (uint16_t *)i2s_rx_buff, 3840);

The I2S receive buffer fills by half-word values as bellow, and clearly the odd index has to zero because the 16 bit out of 32 bit has been chosen. As an example the following 4 half-words has been put here where they are correct values. 

0x0000-0xC4A1-0x0000-0xC493

After that unexpected events, the values shifts gradually one by one to the odd words. like bellow,

0x20FC-0x0003-0x25C0-0x0003

This bug is completely random and sometimes doesn't show even after 40-50 minutes, but sometimes it shows after a few minutes after restarting the STM32.

Some hints,

1. When I reboots the stm32 again the samples values get back to normal without bug.

2. The problem is really random and I can't see anything regular in it.

3. It seems there is something missing in i2S shift-register setting or somewhere around there.

please kindly let me know if you know what is the problem and/or you have any hint to solve it.

Thanks ~

0 REPLIES 0