cancel
Showing results for 
Search instead for 
Did you mean: 

Why LISR signals Half Complete and Total Complete ISR at the same time, while using HAL Double buffer mode for Audio

Schepka.Markus
Associate

Hello to all.

I'm trying to setup the STM32F746-Discovery board for audio transmission.

For the audio transmission it is important to use double buffer mode.

I'm using the HAL and the stm32746g_discovery_audio.c and wm8994.c files

The LISR register signals Half Complete and Total Complete ISR at the same time, but in LIFCR register are all flags '0'.

In the BSP_AUDIO_OUT_PLAY I'm calling HAL_DMAEx_MultiBufferStart_IT() instead of HAL_SAI_Transmit_DMA(), because HAL_SAI_Transmit_DMA() is for single buffer mode, as far as I understand the code.

uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint16_t* pBuffer2, uint32_t Size)
{
  /* Call the audio Codec Play function */
  if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)
  {
    return AUDIO_ERROR;
  }
  else
  {
    HAL_DMAEx_MultiBufferStart_IT(haudio_out_sai.hdmatx, (uint32_t)pBuffer, (uint32_t)&haudio_out_sai.Instance->DR, (uint32_t)pBuffer2, DMA_MAX(Size / AUDIODATA_SIZE));
    
        /* Enable the interrupts for error handling */
    //__HAL_SAI_ENABLE_IT(haudio_out_sai, SAI_InterruptFlag((SAI_HandleTypeDef *)&haudio_out_sai, SAI_MODE_DMA));
 
    /* Enable SAI Tx DMA Request */
    haudio_out_sai.Instance->CR1 |= SAI_xCR1_DMAEN;
    /* Update the Media layer and enable it for play */  
 //   HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer, DMA_MAX(Size / AUDIODATA_SIZE));
    
    return AUDIO_OK;
  }
}

Because the HAL_DMAEx_MultiBufferStart_IT() function do not enable the transmission, I add enabling in the above code.

When the HAL_DMAEx_MultiBufferStart_IT() is configured, as can be seen above, then the ISR function will be called, but Half Complete and Total Complete ISR flags are set.

Is the HAL_DMAEx_MultiBufferStart_IT() size parameter configured as "Size", then the half and total complete flags alternetes, as have to be.

But this is not the correct , because the Size needs to be half of its value.

The size parameter includes left and right channel.

Half of the data is for right channel the other half is for the left channel. This is the reason why the size parameter needs to be half of its size.

In the HAL_DMAEx_MultiBufferStart_IT() function I added the following line:

hdma->XferHalfCpltCallback = HAL_DMA_TxHalfCpltCallback;

because I need to set this parameter, otherwise the half interrupt enable flag will not be set.

if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
    {
      hdma->Instance->CR  |= DMA_IT_HT;
    }

I would be very happy about some help.

Best Regards

0 REPLIES 0