cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_Mem_Read_DMA and HAL_I2C_GetState never gets HAL_I2C_STATE_READY

Mat1
Associate III

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);
    }
  }
}

0 REPLIES 0