cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 I2S DMA RX problem but not TX

hjh
Associate III

Hi

I am stuck with STM32H743IIT I2S DMA RX ..

The code is working perfect when uncommet HAL_I2S_Transmit_DMA (Line 29) but when uncomment line 31 HAL_I2S_Receive_DMA it feedback HAL_OK but do never go into the callbacks ..What can be the issue ?

Best regards

Hjalmar

#define I2S_BUFFER_SIZE 48
 
__attribute__(( section(".MY_RAM_D2") )) volatile uint8_t I2S_TXbuf[I2S_BUFFER_SIZE ];
__attribute__(( section(".MY_RAM_D2") )) volatile uint8_t I2S_RXbuf[I2S_BUFFER_SIZE ];
 
 
 float phaseStep = 550.0f/192000.0f;
 float phaseStepSum = 0;
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2S2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
 
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_I2S2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_StatusTypeDef feedBack = HAL_OK;
 
 // feedBack = HAL_I2S_Transmit_DMA(&hi2s2,I2S_TXbuf, sizeof(I2S_TXbuf)>>1);
 
  feedBack = HAL_I2S_Receive_DMA(&hi2s2,I2S_RXbuf, sizeof(I2S_RXbuf)>>1);
 
  //feedBack = HAL_I2SEx_TransmitReceive_DMA(&hi2s2, I2S_TXbuf, I2S_RXbuf, I2S_BUFFER_SIZE >> 1);
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    HAL_Delay(100);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
 
 
/* USER CODE BEGIN 4 */
 
void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s2)
{
 
}
 
void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s2)
{
 
}
 
void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s2)
{
	for(int i = 0; i < I2S_BUFFER_SIZE >> 1 ; i++)
	{
		 printf(" RXbuf : %\r\n", I2S_RXbuf[i]);
	}
}
 
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s2)
{
	for(int i = I2S_BUFFER_SIZE ; i < I2S_BUFFER_SIZE ; i++)
	{
		 printf(" RXbuf : %\r\n", I2S_RXbuf[i]);
	}
}
 
void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s2)
{
	fillI2SBuffer_24(0);
}
 
void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s2)
{
	fillI2SBuffer_24(I2S_BUFFER_SIZE>>1);
}
 
void fillI2SBuffer_24(int indexBegin)
{
	int32_t y0 = 0;
	int32_t y1 = 0;
 
	float     tmp_y;
	for(int i = 0; i < I2S_BUFFER_SIZE >> 1; i=i+6 )
	{
		phaseStepSum = phaseStepSum + phaseStep;
		if(phaseStepSum > 1.0f){phaseStepSum = 0;}
		tmp_y = (float) sin(6.2832f * phaseStepSum)* 1.0f;
		y0 = (int32_t)(tmp_y * 8388607.0f);
 
		I2S_TXbuf[i+2+indexBegin]=  y0 & 0xFF ;
		I2S_TXbuf[i+1+indexBegin]= (y0 >> 8) & 0xFF;
		I2S_TXbuf[i+indexBegin]= (y0 >> 16) & 0xFF;
/*
		I2S_TXbuf[i+5+indexBegin]=  y0 & 0xFF ;
		I2S_TXbuf[i+4+indexBegin]= (y0 >> 8) & 0xFF;
		I2S_TXbuf[i+3+indexBegin]= (y0 >> 16) & 0xFF;
*/
		I2S_TXbuf[i+5+indexBegin]=  0x00 ;
		I2S_TXbuf[i+4+indexBegin]=  0x00;
		I2S_TXbuf[i+3+indexBegin]=  0x00;
 
	}
}
 
 

5 REPLIES 5
Kamil Duljas
Senior III
/* Set the I2S Rx DMA Half transfer complete callback */
  hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
 
  /* Set the I2S Rx DMA transfer complete callback */
  hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
 
  /* Set the DMA error callback */
  hi2s->hdmarx->XferErrorCallback = I2S_DMAError;

It's part of ​HAL_I2S_Receive_DMA.

Look at the callback function name​s, you don't use this function.

Analyze this function:

https://github.com/STMicroelectronics/STM32CubeH7/blob/4fdaa91bd55f9b4fc5c03fbc929b93566acea76e/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2s.c#L1506​

Dudo
hjh
Associate III

HI

Thanks for reply

i already check that and as you can see i use the right callback name ...

it is on stm32h7 so there have to been another issue i am not aware off ...

Please help

static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
{
  /* Derogation MISRAC2012-Rule-11.5 */
  I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
 
  /* Call user Rx half complete callback */
#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1UL)
  hi2s->RxHalfCpltCallback(hi2s);
#else
  HAL_I2S_RxHalfCpltCallback(hi2s);
#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
}

LCE
Principal

First of all: the callbacks are called from DMA interrupts, so it's not good to put printf in there, unless you are using super slow I2S and super fast UART. Even then it's "bad practice".

Please show us the DMA init and related source, there might be some problems, often related to data alignment (byte, half-word, word).

hjh
Associate III

hi

Thanks for your reply

the reason to printf in a callback is only to test ...

The program is for testing the i2s so i can continue DSP project.

the hole project is attached and here you can see DMA init and I2S init ..

Hope so much for help ;o)

Best regards

Hjalmar

void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  if(hi2s->Instance==SPI2)
  {
  /* USER CODE BEGIN SPI2_MspInit 0 */
 
  /* USER CODE END SPI2_MspInit 0 */
 
  /** Initializes the peripherals clock
  */
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
    PeriphClkInitStruct.PLL2.PLL2M = 2;
    PeriphClkInitStruct.PLL2.PLL2N = 100;
    PeriphClkInitStruct.PLL2.PLL2P = 8;
    PeriphClkInitStruct.PLL2.PLL2Q = 2;
    PeriphClkInitStruct.PLL2.PLL2R = 2;
    PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
    PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
    PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
    PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }
 
    /* Peripheral clock enable */
    __HAL_RCC_SPI2_CLK_ENABLE();
 
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOI_CLK_ENABLE();
    /**I2S2 GPIO Configuration
    PC2_C     ------> I2S2_SDI
    PB12     ------> I2S2_WS
    PB13     ------> I2S2_CK
    PC6     ------> I2S2_MCK
    PI3     ------> I2S2_SDO
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_6;
    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_12|GPIO_PIN_13;
    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);
 
    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(GPIOI, &GPIO_InitStruct);
 
    /* I2S2 DMA Init */
    /* SPI2_RX Init */
    hdma_spi2_rx.Instance = DMA1_Stream0;
    hdma_spi2_rx.Init.Request = DMA_REQUEST_SPI2_RX;
    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_BYTE;
    hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    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();
    }
 
    __HAL_LINKDMA(hi2s,hdmarx,hdma_spi2_rx);
 
    /* SPI2_TX Init */
    hdma_spi2_tx.Instance = DMA1_Stream1;
    hdma_spi2_tx.Init.Request = DMA_REQUEST_SPI2_TX;
    hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;
    hdma_spi2_tx.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
    {
      Error_Handler();
    }
 
    __HAL_LINKDMA(hi2s,hdmatx,hdma_spi2_tx);
 
  /* USER CODE BEGIN SPI2_MspInit 1 */
 
  /* USER CODE END SPI2_MspInit 1 */
  }
 
}

hjh
Associate III

Hi

Can somebody give me a hint ?

I will like so much just to get a hint where to look

Thanks

hjalmar