AnsweredAssumed Answered

HAL DMA I2S Bug

Question asked by stanley.phillip on Aug 26, 2016
Latest reply on Apr 4, 2017 by Nesrine M
There is a bug in HAL in full duplex I2S. The internal callback in the library disables all further DMA requests even if circular buffering is enabled. This is incorrect as it requires that an application call
HAL_I2SEx_TransmitReceive_DMA() again, but then streams become desynchronized, at least on my implementation where microcontroller  is the slave and output to codec is on I2S_SD line and input from codec is on I2S_SD_ext line.

I am using a STM32F301C8Tx. My project is an STM32CubeMX project where latest firmware is V1.6.0. Bug  is in stm32f3xx_hal_i2s_ext.c. In internal callback, I2S_TxRxDMACplt(). The offending code is this for rx requests:

if(((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
{
  I2SxEXT(hi2s->Instance)->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
}
else
{
  hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
}

I just deleted this bit of code since my application will only be using circular buffering, and it works just fine. Similar bit of code for tx requests and can just be deleted. Also, you can replace duplex external callback with same callbacks for half duplex functions. Makes more sense.

Also, without half complete callbacks, the HAL is useless for my application. The half complete requests however are still being invoked, but no callback is being assigned. So just create internal half complete callback, assign in HAL_I2SEx_TransmitReceive_DMA(), and in internal half complete callback, invoke appropriate external callbacks.

Full duplex I2S should work using HAL if you do these things.

Outcomes