cancel
Showing results for 
Search instead for 
Did you mean: 

I2C_WaitOnFlagUntilTimeout return HAL_ERROR

K.4
Associate

Hi,

I am using STM32F303RETb (NUCLEO-F303) to try I2C for another device. But always return HAL_ERROR into HAL_I2C_Slave_Receive(). By the way of I2C_WaitOnFlagUntilTimeout.

What are the possible problems with this error?

this part is setting code in the MX_I2C1_Init().

/* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00901D23;
  hi2c1.Init.OwnAddress1 = 0x40;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Analogue filter

this is main function.

/* USER CODE BEGIN 2 */
  uint8_t commandBuffer[4] = {0};
  uint8_t whoami[1] = {0x00};
  HAL_StatusTypeDef s;
  HAL_StatusTypeDef t;
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	    // I2C�?��?�期的�?�1�?イト�?��?��?�る
	  s = HAL_I2C_Slave_Receive(&hi2c1, (uint8_t *)commandBuffer, 1, 1000);
	    if (s == HAL_OK) {
	  t = HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t *)whoami, 1, 1000);
	      }

HERE is where the error in question occurs.

static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
                                                    uint32_t Timeout, uint32_t Tickstart)
{
  while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
  {
    /* Check for the Timeout */
    if (Timeout != HAL_MAX_DELAY)
    {
      if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
      {
        hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
        hi2c->State = HAL_I2C_STATE_READY;
        hi2c->Mode = HAL_I2C_MODE_NONE;
 
        /* Process Unlocked */
        __HAL_UNLOCK(hi2c);
        return HAL_ERROR;//HERE
      }
    }
  }
  return HAL_OK;
}

Is there anything I am missing in this code?

P.S.

Thank you for some answers.

Now that I know the cause, will report it.

In order to communicate with the device I was using, I made a mistake in setting I2C Speed Mode.

(I2C Speed Mode : Standard Mode → Fast Mode)

0693W00000aJjnZQAS.png 

I'm sorry for confusing you.

1 ACCEPTED SOLUTION

Accepted Solutions
Foued_KH
ST Employee

Hello @K.4​ ,

Please check results via an oscilloscope and Read/Write registers.

If nothings appears, please check the error flags set in the status register, so try to get the error (HAL_I2C_GetError)

Foued

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.

View solution in original post

10 REPLIES 10
Pavel A.
Evangelist III

So what is the ErrorCode value? If timeout: does the other side send anything? Use a scope to check.

Foued_KH
ST Employee

Hello @K.4​ ,

Please check results via an oscilloscope and Read/Write registers.

If nothings appears, please check the error flags set in the status register, so try to get the error (HAL_I2C_GetError)

Foued

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.

Hito
Associate II

i have also same problem

ErrorCode is 0x00000020  ---> TimeOut

and i chek with oscilloscope nothing will send at other side

if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
{
return HAL_ERROR;
}

 

Bob S
Principal

If "BUSY" is stuck "set" then the I2C port sees a logic low level on either SCL or SDA signals.  You say "chek with oscilloscope nothing will send at other side" - what does that mean?  Did you see both lines high (3.3V) and no transitions on either SCL or SDA?  Or was one of the lines low (near 0V)?  Or did you see the data from the other device but not anything from your STM32?

Hito
Associate II

 yes both SDA and SCL pin high 3.3v

 

Hito
Associate II

static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status,
uint32_t Timeout, uint32_t Tickstart)
{
while (__HAL_I2C_GET_FLAG(hi2c, Flag) == Status)
{
/* Check for the Timeout */
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
{
if ((__HAL_I2C_GET_FLAG(hi2c, Flag) == Status))
{
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
hi2c->State = HAL_I2C_STATE_READY;
hi2c->Mode = HAL_I2C_MODE_NONE;

/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
}
}
}
return HAL_OK;
}

 

stuck in this lines

Bob S
Principal

The answer is probably the same as it was for the original poster - read back the config registers and make sure they make sense.  Post them here if you have questions.

Need LOTS more information:

  • Which CPU?

  • Which PCB - ST NUCLEO, DISCO or your own custom board?

  • Are you operating as a slave or master?

  • Does this happen on your very first call the an I2C transmit or receive function?

  • Are you sure you have the proper pins configured for the I2C port (does your CubeMX config match the actual hardware)?

Show your code - not the HAL function, but your code that calls the HAL I2C functions.  And please paste your code using the "code" formatting button (click the "..." then the "</>" button).

Hito
Associate II

STM32 DevloperBord : STM32F030C6T6TR
CubeMX : version 6.7.0
keil : version 5

i2c config at standard mode I2C_Speed_Frequancy-100KHZ

static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00201D2C;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }

 

static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout,
                                                        uint32_t Tickstart)
{
  while (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET)
  {
    /* Check if an error is detected */
    if (I2C_IsErrorOccurred(hi2c, Timeout, Tickstart) != HAL_OK)
    {
      return HAL_ERROR;
    }

    /* Check for the Timeout */
    if (((HAL_GetTick() - Tickstart) > Timeout) || (Timeout == 0U))
    {
      if ((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET))
      {
        hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
        hi2c->State = HAL_I2C_STATE_READY;
        hi2c->Mode = HAL_I2C_MODE_NONE;

        /* Process Unlocked */
        __HAL_UNLOCK(hi2c);

        return HAL_ERROR;
      }
    }
  }
  return HAL_OK;
}

 

    if (I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
    {
      return HAL_ERROR;
    }

This function return HAL_ERROR every time and stuck in while loop
ErrorCode is --> 0x00000020 (TIMEOUT)
When i checked in oscilloscope, both SDA and SCL pins are at high state. I have checked multiple threads related to I2C error in HAL but haven't found solid root cause, can anyone help to address this issue?

I'm using RTC(MCP79410) as peripheral and comunicate with I2C

Bob S
Principal

> STM32 DevloperBord : STM32F030C6T6TR

That part number is the CPU's part number, not the board. Is this a NUCLEO board (I don't see one with the F030C6)?

You didn't answer all my questions:

Does this happen on your very first call the an I2C transmit or receive function? Or does the first transaction work and the 2nd (or 3rd, etc.) fails?

Are you sure you have the proper pins configured for the I2C port (are the SDA/SCL pins in CubeMX the pins you have wired to the MCP79410)?
[new question] Do you have pull-up resistors on the SDA and SCL lines? Not the STM32's internal pullups, but real resistors?
[new question] Is there anything else connected to the SDA and SCL pins on your dev board?

Show your code that calls the HAL I2C functions.

If this happens on the first attempt to communicate with the MCP79410, and presuming you have a digital scope, set the scope to trigger on falling SDA (or SCL, doesn't really matter) and set your timebase so you can capture the entire transaction (such as it is).