cancel
Showing results for 
Search instead for 
Did you mean: 

F4 I2S CubeMX problem in HAL_I2S_DMAStop

eugene239955_st
Associate II
Posted on January 04, 2016 at 18:12

I would like to point the attention of ST to the problem they have in the CubeMX generated code.

In HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s) function the procedure described in 26.6.4 I2S master mode of RM0390 is NOT followed!

It is clearly stated that ''To switch off the I2S, by clearing I2SE, it is mandatory to wait for TXE = 1 and BSY = 0.''

It is not done so and in 24 and 32 bit mode the next start usually gets shifted by 16 bit because of incompleted sequence during stop!

Following should be added before the __HAL_I2S_DISABLE(hi2s):

while(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != 1 || __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_BSY) != 0);

Also the timeout should be added and some protection of course in production version.

This bug has costed me about a day to track down.

2 REPLIES 2
eugene239955_st
Associate II
Posted on January 04, 2016 at 18:19

Update. The fully define function:

__weak HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)

{

    /* Process Locked */

    __HAL_LOCK(hi2s);

    /* Disable the I2S Tx/Rx DMA requests */

    hi2s->Instance->CR2 &= ~SPI_CR2_TXDMAEN;

    hi2s->Instance->CR2 &= ~SPI_CR2_RXDMAEN;

    /* Abort the I2S DMA Stream tx */

    if(hi2s->hdmatx != NULL)

    {

        HAL_DMA_Abort(hi2s->hdmatx);

    }

    /* Abort the I2S DMA Stream rx */

    if(hi2s->hdmarx != NULL)

    {

        HAL_DMA_Abort(hi2s->hdmarx);

    }

    // To switch off the I2S, by clearing I2SE, it is mandatory to wait for TXE = 1 and BSY = 0.

    uint32_t tickstart = 0;

    tickstart = HAL_GetTick();

    while(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != 1 || __HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_BSY) != 0)

    {

    if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_I2S_ABORT)

{

/* Update error code */

    hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;

/* Process Unlocked */

__HAL_UNLOCK(hi2s);

/* Change the I2S state */

hi2s->State = HAL_I2S_STATE_TIMEOUT;

return HAL_TIMEOUT;

}

    }

    /* Disable I2S peripheral */

    __HAL_I2S_DISABLE(hi2s);

    hi2s->State = HAL_I2S_STATE_READY;

    /* Process Unlocked */

    __HAL_UNLOCK(hi2s);

    return HAL_OK;

}

In .h:

#define HAL_TIMEOUT_I2S_ABORT    ((uint32_t)1000)  /* 1s */

#define HAL_I2S_ERROR_TIMEOUT       ((uint32_t)0x00000040)    /*!< I2S transfer error          */

Amel NASRI
ST Employee
Posted on January 06, 2016 at 13:22

Hishamaev.eugene,

You can follow the status of the reported issue in

https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Java/F4%20I2S%20CubeMX%20problem%20in%20HAL_I2S_DMAStop

.

-Mayla-

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.