Skip to main content
Visitor II
May 16, 2023
Question

STM32H7 I2S DMA RX problem but not TX

  • May 16, 2023
  • 5 replies
  • 2050 views

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;
 
	}
}
 
 

    This topic has been closed for replies.

    5 replies

    Graduate
    May 16, 2023
    /* 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​

    hjhAuthor
    Visitor II
    May 17, 2023

    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 */
    }

    Graduate II
    May 17, 2023

    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).

    hjhAuthor
    Visitor II
    May 17, 2023

    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 */
     }
     
    }

    hjhAuthor
    Visitor II
    May 19, 2023

    Hi

    Can somebody give me a hint ?

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

    Thanks

    hjalmar