cancel
Showing results for 
Search instead for 
Did you mean: 

[BUG] - HAL_I2SEx_TxRxCpltCallback never fire in DMA circular mode

leonardo
Associate III

I was usig stm32f4 hal version 1.11 and in that version there was this code:

void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
{
  I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
  
  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
  {
    if(hi2s->Init.FullDuplexMode != I2S_FULLDUPLEXMODE_ENABLE)
    {    
       hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
    }
#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)
   /* FullDuplexMode feature enabled */   
    else
    {
      if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
      {
        /* Disable Tx DMA Request for the I2S Master*/  
        hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
      }
      else
      {
        /* Disable Tx DMA Request for the I2SEx Slave */  
        I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
      }
    }
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F401xx || STM32F411xx ||\
          STM32F469xx || STM32F479xx */
 
    hi2s->TxXferCount = 0U;
    if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
    {
      if(hi2s->RxXferCount == 0U)
      {
        hi2s->State = HAL_I2S_STATE_READY;
      }
    }
    else
    {
      hi2s->State = HAL_I2S_STATE_READY; 
    }
  }
  HAL_I2S_TxCpltCallback(hi2s);
}

as you can see HAL_I2S_TxCpltCallback(hi2s) is called at the end of the function, no matter if DMA was in circular mode or not. That is the expected behavior for that callback!!!!

In current stm32f4 hal library we have:

/**
  * @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);
      }
    }
  }
}

this time the call to HAL_I2SEx_TxRxCpltCallback(hi2s) function is inside the circular mode enabled check and therefore it never fire in circular mode.

13 REPLIES 13
S.Ma
Principal

Is there an application workaround? Probably the "transfer complete" is seen at untrue for cyclical mode? As the behaviour changed between versions, there maybe a changelist somewhere to let programmers of the functional modification if it is confirmed so?

leonardo
Associate III

This change does not make any sense! It does not matter if it is in a changelist, this is a BUG. If I use DMA in Circular mode and don't want to get an interrupt from transfer complete then I will not add HAL_I2SEx_TxRxCpltCallback(hi2s) into my code and problem solved, but if I do want to get an interrupt from transfer complete, then I need HAL library to call HAL_I2SEx_TxRxCpltCallback(hi2s) callback. It is so simple.

Can somebody tell me in what circunstance the call to HAL_I2SEx_TxRxCpltCallback is a problem in circular mode???????? I think that the guy that update this code never use a I2S device...

Please, solve it!!!!!!!

Imen.D
ST Employee

Hello,

We passed your request internally to add HAL_I2SEx_TxRxCpltCallback with DMA in circular mode.

Kind Regards,

Imen.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
leonardo
Associate III

Thank Imen.

meanwhile, could you provide a workaround?

Goof Ball
Associate III

Any update on this? Definitely appears to be a bug.

Geekboy1011
Associate II

This is still an active bug in V1.25.0 of the hal library for the stm32f4 as of writing. Really confusing and inconsistent with the non RxTx implementation of the hal library .

All in all confusing however. Can we please get this fixed?

Imen.D
ST Employee

Hello @Geekboy1011​ ,

After check internally with our Development team, the fix will be available in next patch release of STM32CubeF4.

Actually, I don’t have an exact date as we have released the last package on 20W34.

I will keep you updated on this topic.

Thanks

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Geekboy1011
Associate II

Thanks for the response! Glad to hear its getting fixed 🙂

I look forward to the updates and will keep an eye for the realease when it gets here!

You are welcome @Geekboy1011​ and thank you for your patience.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen