Skip to main content
Explorer II
December 21, 2022
Question

HAL_I2C_Mem_Read_DMA and HAL_I2C_GetState never gets HAL_I2C_STATE_READY

  • December 21, 2022
  • 0 replies
  • 1347 views

Hi,

I use the NUCLEO-F091RC, STM32CubeIDE with the MCU Package 1.11.3 and FreeRtos.

The I2C1 is used with an Eeprom. So I would like to use the function HAL_I2C_Mem_Read_DMA as it is shown for example STM32Cube_FW_F0_V1.11.3\Projects\STM32091C_EVAL\Examples\I2C\I2C_EEPROM\Src\main.c:

/*##-3- Start reading process ##############################################*/
 if (HAL_I2C_Mem_Read_DMA(&I2cHandle, (uint16_t)EEPROM_ADDRESS, 0, I2C_MEMADD_SIZE_16BIT, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
 {
 /* Reading process Error */
 Error_Handler();
 }
 
 /* Wait for the end of the transfer */
 while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
 {
 }

But if I run the code it hangs in the HAL_I2C_GetState loop. The SDA/SCL lines look fine with the oscilloscope. And at the end the software does jump into the I2C_DMAMasterReceiveCplt function (file stm32f0xx_hal_i2c.c).

I would expect that in function I2C_DMAMasterReceiveCplt somewhere set hi2c->State = HAL_I2C_STATE_READY would be coded?

Where should be hi2c->State = HAL_I2C_STATE_READY happen?

My fix would be this:

static void I2C_DMAMasterReceiveCplt(DMA_HandleTypeDef *hdma)
{
 /* Derogation MISRAC2012-Rule-11.5 */
 I2C_HandleTypeDef *hi2c = (I2C_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
 
 /* Disable DMA Request */
 hi2c->Instance->CR1 &= ~I2C_CR1_RXDMAEN;
 
 /* If last transfer, enable STOP interrupt */
 if (hi2c->XferCount == 0U)
 {
	hi2c->State = HAL_I2C_STATE_READY; // <<<<<<< this is my fix <<<<
 /* Enable STOP interrupt */
 I2C_Enable_IRQ(hi2c, I2C_XFER_CPLT_IT);
 }
 /* else prepare a new DMA transfer and enable TCReload interrupt */
 else
 {
 /* Update Buffer pointer */
 hi2c->pBuffPtr += hi2c->XferSize;
 
 /* Set the XferSize to transfer */
 if (hi2c->XferCount > MAX_NBYTE_SIZE)
 {
 hi2c->XferSize = MAX_NBYTE_SIZE;
 }
 else
 {
 hi2c->XferSize = hi2c->XferCount;
 }
 
 /* Enable the DMA channel */
 if (HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->RXDR, (uint32_t)hi2c->pBuffPtr,
 hi2c->XferSize) != HAL_OK)
 {
 /* Call the corresponding callback to inform upper layer of End of Transfer */
 I2C_ITError(hi2c, HAL_I2C_ERROR_DMA);
 }
 else
 {
 /* Enable TC interrupts */
 I2C_Enable_IRQ(hi2c, I2C_XFER_RELOAD_IT);
 }
 }
}

    This topic has been closed for replies.