cancel
Showing results for 
Search instead for 
Did you mean: 

I2C getting stuck in HAL_I2C_IsDeviceReady

PPopo.1
Senior

I had this problem on my project, so I created a new one and added only I2C to pins Pb7 and Pb6. I set I2C from disable to I2C and I set them to "pull-up" . That's about it. And the code gets stuck in the HAL_I2C_IsDeviceReady function.

I have also set the sysclk to 80Mhz.

Any ideas what could be the issue?

The code I have and the inside of the HAL_I2C_IsDeviceReady where it enters the never ending loop:

 while ((tmp1 == RESET) && (tmp2 == RESET))
      {
        if (Timeout != HAL_MAX_DELAY)
        {
          if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
          {
            /* Update I2C state */
            hi2c->State = HAL_I2C_STATE_READY;
 
            /* Update I2C error code */
            hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
 
            /* Process Unlocked */
            __HAL_UNLOCK(hi2c);
 
            return HAL_ERROR;
          }
        }
 
        tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
        tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
      }

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t buf[256];
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
  HAL_StatusTypeDef ret;
 //#ifdef _TEST_
   for(uint8_t i=1; i<256; i++)
        {
 	   ret = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 10, 100); //10x proba komunicirat in caka max 100 ms
 	   if (ret != HAL_OK) /* No ACK Received At That Address */
 	   {
 		   //HAL_UART_Transmit(&huart1, Space, sizeof(Space), 10000);
 	   }
 	   else if(ret == HAL_OK)
 	   {
 		   //sprintf(buf, "0x%X", i);
 		   //HAL_UART_Transmit(&huart1, buf, sizeof(buf), 10000);
 	   }
 	   buf[i] = (uint8_t)ret;
        }
 //#endif
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

5 REPLIES 5
Foued_KH
ST Employee

Hello @PPopo.1​ ,

 1) Set SCL and SDA with GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HIGH or VERY_HIGH setting is not good.

2) Try to roll the counter up to 255.

    for(i = 0 ; i < 255; i++)

I think the dev address has to be shifted 1 bit to the left.

3) Check that you have actual (2.7K for example) pull_up resistors on the I2C lines,

GPIO_InitStruct.Pull = GPIO_PULLUP, is often not enough.

for(uint8_t i=0; i<255; i++)
        {
 	   ret = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i<<1), 3, 10);
 	   if (ret != HAL_OK) /* No ACK Received At That Address */
 	   {
 		   //HAL_UART_Transmit(&huart1, Space, sizeof(Space), 10000);
 	   }
 	   else if(ret == HAL_OK)
 	   {
 		   //sprintf(buf, "0x%X", i);
 		   //HAL_UART_Transmit(&huart1, buf, sizeof(buf), 10000);
 	   }
 
        }

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.

PPopo.1
Senior

the problem is that it's really hard to debug because live expressions are not showing for some reason

PPopo.1
Senior

I changed the GPIO_InitStruct.Speed to low and instead of counter up to 255 I entered the Address which is 0x77 and also shifted it. I would like to say that this has worked for me before and now it just doesn't anymore and have no idea why. Pb6 and pb7 are both set to pull up in the .ioc file

Pavel A.
Evangelist III

Your HAL timer likely is not ticking.

WQ
Associate III

Internal pull-ups are too weak for I2C if there are no external pull-up resistors. -wq