cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743: BDMA channel for SAI interface does not work.

Mapyam
Associate II

I would like to use SAI interface, but the initial setup seems to be failing. ErrorHandler was called because of FIFO is Empty after calling HAL_SAI_Transmit_DMA().

The SAI is set up as follows:

  hsai_BlockA4.Instance = SAI4_Block_A;
  hsai_BlockA4.Init.AudioMode = SAI_MODEMASTER_TX;
  hsai_BlockA4.Init.Synchro = SAI_ASYNCHRONOUS;
  hsai_BlockA4.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
  hsai_BlockA4.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
  hsai_BlockA4.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
  hsai_BlockA4.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_48K;
  hsai_BlockA4.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockA4.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockA4.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockA4.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockA4, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }
  hsai_BlockB4.Instance = SAI4_Block_B;
  hsai_BlockB4.Init.AudioMode = SAI_MODESLAVE_RX;
  hsai_BlockB4.Init.Synchro = SAI_SYNCHRONOUS;
  hsai_BlockB4.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
  hsai_BlockB4.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
  hsai_BlockB4.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockB4.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockB4.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockB4.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockB4, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }

The BDMA is set up as follows:

static void MX_BDMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_BDMA_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMAMUX2_OVR_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMAMUX2_OVR_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMAMUX2_OVR_IRQn);
  /* BDMA_Channel0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(BDMA_Channel0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
  /* BDMA_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(BDMA_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(BDMA_Channel1_IRQn);
 
}

Timeout occurs at line 47 of HAL_SAI_Transmit_DMA().

Is there a missing FIFO setting? Or is there something wrong?

HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
{
  uint32_t tickstart = HAL_GetTick();
 
  if ((pData == NULL) || (Size == 0U))
  {
    return  HAL_ERROR;
  }
 
  if (hsai->State == HAL_SAI_STATE_READY)
  {
    /* Process Locked */
    __HAL_LOCK(hsai);
 
    hsai->pBuffPtr = pData;
    hsai->XferSize = Size;
    hsai->XferCount = Size;
    hsai->ErrorCode = HAL_SAI_ERROR_NONE;
    hsai->State = HAL_SAI_STATE_BUSY_TX;
 
    /* Set the SAI Tx DMA Half transfer complete callback */
    hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
 
    /* Set the SAI TxDMA transfer complete callback */
    hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
 
    /* Set the DMA error callback */
    hsai->hdmatx->XferErrorCallback = SAI_DMAError;
 
    /* Set the DMA Tx abort callback */
    hsai->hdmatx->XferAbortCallback = NULL;
 
    /* Enable the Tx DMA Stream */
    if (HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
    {
      __HAL_UNLOCK(hsai);
      return  HAL_ERROR;
    }
 
    /* Enable the interrupts for error handling */
    __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
 
    /* Enable SAI Tx DMA Request */
    hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
 
    /* Wait until FIFO is not empty */
    while ((hsai->Instance->SR & SAI_xSR_FLVL) == SAI_FIFOSTATUS_EMPTY)
    {
      /* Check for the Timeout */
      if ((HAL_GetTick() - tickstart) > SAI_LONG_TIMEOUT)
      {
        /* Update error code */
        hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
 
        /* Process Unlocked */
        __HAL_UNLOCK(hsai);
 
        return HAL_TIMEOUT;
      }
    }

​If you have ideas, please let me know.

4 REPLIES 4

Try to get SAI working without DMA first, using polling.

JW​

Mapyam
Associate II

HAL_SAI_Transmit_IT() is working.

But HAL_SAI_Transmit_DMA() is not working.

I do not use cache and MPU control mode.

If SAI_FillFifo(hsai) is added before line 47, it will not time out.

However, HAL_SAI_RxCpltCallback() is not called.

Amel NASRI
ST Employee

Hi @�?��? 山本​ ,

Try to execute the example STM32CubeH7/Projects/STM32H743I-EVAL/Examples/SAI/SAI_AudioPlay first.

If you don't have an eval board available, try to compare your code with the one of the suggested example to check what are the differences that may impact the expected behavior.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.