Sitemap
David Ramsay

David Ramsay

Watch Yourself with STM32 HAL I2S Library

2 min readFeb 27, 2018

The STM32 stock libraries are slightly notorious for being incorrect. I want to reiterate that from my personal experience, and offer some support to those that might be fighting with I2S and other audio related functionality.

I traced down a bug that cost me several days of my life in the I2S HAL library that is *not* documented even with several pages of Google search, so I decided to put it here in case it’s useful to anyone. This is part of the STM32F7XX family libraries.

In STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_i2s.c, at line 1151 we have the I2S_WaitFlagStateUntilTimeout function. The description of this function (and it’s use in the HAL_I2S_Receive) indicate it should spin until the flag equals the expected passed State, or until timeout. See if you can spot the error:

static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State, uint32_t Timeout)
{
uint32_t tickstart = 0;

/* Get tick */
tickstart = HAL_GetTick();

/* Wait until flag is reset */
if(State == RESET)
{
while(__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET)
{
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
{
/* Set the I2S State ready */
hi2s->State= HAL_I2S_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2s);
return HAL_TIMEOUT;
}
}
}
}
else
{
while(__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET)
{
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
{
/* Set the I2S State ready */
hi2s->State= HAL_I2S_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hi2s);
return HAL_TIMEOUT;
}
}
}
}
return HAL_OK;
}

If you’re paying attention, you’ll see that in the first section of the main if statement (State==RESET), we’re waiting for the flag to turn from SET to RESET. Unfortunately, the while loop that follows will count down and eventually timeout if the state actually does happen to be RESET. If it’s SET instead (when it should be waiting and counting), it instead jumps to the bottom of the function and returns HAL_OK. The same is true of the second section as well.

Get David Ramsay’s stories in your inbox

Join Medium for free to get updates from this writer.

This has the unfortunate property of immediately returning HAL_OK if the flag is *not* in the state you’re looking for it to be, and counting down and eventually timing out if it *is* in the proper state.

Despite the hours I spent tracking this down, it’s an easy fix — simply switch the while loops from == to != and vice versa.

Be wary of these libraries! ST has a lot of work to do to make these useable. You should definitely take them all with a grain of salt.

I also sent this off to ST, on their forums here.

--

--