cancel
Showing results for 
Search instead for 
Did you mean: 

I2S DMA Complete transfer IRQ on circular mode

leonardo
Associate III

Hi, I'm using an audiocodec with a STM32F4011 through I2S interface. I configure I2S to transmit/receive in DMA mode and circular buffer. I need to get an ISR on HalfComplete and Complete transfer.

HAL_I2SEx_TxRxHalfCpltCallback is fired on half complete transfer, but HAL_I2SEx_TxRxCpltCallback is not.

Is there a way to get an IRQ on transfer complete?

Thank

9 REPLIES 9

I don't see any reason why half-complete would work and transfer-complete wouldn't, except that the latter is not enabled (or some basic programming error).

Observe whether the related DMA_SxCR.TCIE/HTIE bits are set.

I don't Cube.

JW

leonardo
Associate III

In full duplex, DMA enable CubeMX generate two ISR:

void DMA1_Stream3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */
 
  /* USER CODE END DMA1_Stream3_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_i2s2_ext_rx);
  /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */
 
  /* USER CODE END DMA1_Stream3_IRQn 1 */
}
 
/**
  * @brief This function handles DMA1 stream4 global interrupt.
  */
void DMA1_Stream4_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
 
  /* USER CODE END DMA1_Stream4_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_spi2_tx);
  /* USER CODE BEGIN DMA1_Stream4_IRQn 1 */
 
  /* USER CODE END DMA1_Stream4_IRQn 1 */
}

hdma_i2s2_ext_rx->CR contain:

110000000000010110100011111

bit 3 and 4 are for TCIE and HTIE. Both have a 1

hdma_spi2_tx->CR contain:

10110101011111

again both bit's are in 1

both ISR are fired when I run my code.

Then I have two callbacks:

HAL_I2SEx_TxRxHalfCpltCallback

and

HAL_I2SEx_TxRxCpltCallback

The first one is fired but the second one not.

I'm working on circular mode.

There was some change on HAL code, becuse it works on previous versions... The calbbacks name change and Transfer complete does not work anymore

leonardo
Associate III

Ok, I run step by step the HAL code and get here:

/**
  * @brief DMA I2S transmit receive process complete callback
  * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA module.
  * @retval None
  */
static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
{
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
 
  /* if DMA is not configured in DMA_CIRCULAR mode */
  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
  {
    if (hi2s->hdmarx == hdma)
    {
      /* Disable Rx DMA Request */
      if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\
          ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
      {
        CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN);
      }
      else
      {
        CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN);
      }
 
      hi2s->RxXferCount = 0U;
 
      if (hi2s->TxXferCount == 0U)
      {
        hi2s->State = HAL_I2S_STATE_READY;
 
        HAL_I2SEx_TxRxCpltCallback(hi2s);
      }
    }
 
    if (hi2s->hdmatx == hdma)
    {
      /* Disable Tx DMA Request */
      if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\
          ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
      {
        CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN);
      }
      else
      {
        CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN);
      }
 
      hi2s->TxXferCount = 0U;
 
      if (hi2s->RxXferCount == 0U)
      {
        hi2s->State = HAL_I2S_STATE_READY;
 
        HAL_I2SEx_TxRxCpltCallback(hi2s);
      }
    }
  }
}

And the first IF checks that DMA config is NOT in circular mode. So, IN circular mode, HAL_I2SEx_TxRxCpltCallback is never called.

In a previous version:

/**
  ******************************************************************************
  * @file    stm32f4xx_hal_i2s_ex.c
  * @author  MCD Application Team
  * @version V1.4.2
  * @date    10-November-2015
  * @brief   I2S HAL module driver.
  *          This file provides firmware functions to manage the following 
  *          functionalities of I2S extension peripheral:
  *           + Extension features Functions
  *         
  @verbatim

The ISR goes to:

void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
{
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
 
  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
  {
    /* Disable Rx DMA Request */
    hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
    defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
    defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F469xx) ||\
    defined(STM32F479xx)
    if(hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE)
    {
      /* Disable Tx DMA Request for the slave*/  
      I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
    }
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F401xx || STM32F411xx ||\
          STM32F469xx || STM32F479xx */
    hi2s->RxXferCount = 0;
    if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
    {
      if(hi2s->TxXferCount == 0)
      {
        hi2s->State = HAL_I2S_STATE_READY;
      }
    }
    else
    {
      hi2s->State = HAL_I2S_STATE_READY; 
    }
  }
  HAL_I2S_RxCpltCallback(hi2s); 
}

and as you can see HAL_I2S_RxCpltCallback is called outside of Circular mode check.

Is this a bug?

This is exactly why I don't use Cube.

JW

leonardo
Associate III

Could I expect some "oficial" help here or am I on my own with this problem?

Thank!

BTW, do you use some other library?

No. In my opinion, handling hardware is simple enough, so that any "library" such as SPL/Cube only gets unnecessarily into way.

This view appears to be considered extreme here.

JW

in the begining I used to use CMSIS register definitions and write values directly to them using user manual. But there is not much suport in HAL and there is musch less support on the using direct register access...