AnsweredAssumed Answered

I2C Busy error

Question asked by frank.matthias on Oct 28, 2016

Hi everyone.

I use the STM32F29 and have a similiar problem with the I2C as the following User:
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F103XX%20I2C%20Busy%20Flag%20after%20unsuccessful%20transfer&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=458


The i2C works but sometimes when i use "HAL_I2C_Mem_Read"  there is a timeout error.
After this timeout often the I2C no longer works because of a busy error.

When i measure SDA und the SCL I see that SDA is low and SCL is always high without a clock.

Why this error hapens and what can i do?

In the link above the solution is to make a stop signal with following code when the I2C is busy:

SET_BIT(hi2c1.Instance->CR1, I2C_CR1_STOP); 
I2C_WaitOnFlagUntilTimeout(&hi2c1, I2C_FLAG_BUSY, SET, 1000);

When i call that code the busy error persists.
When i measure SDA und SCL at the Busy error and after that code there are different states.

Sometimes SCL and SDA are still low. But sometimes after I have made a hardware reset and try to repeat it, SDA is low and SCL is high or they are both high.


zaehler =0;
  do
  {
    while (HAL_I2C_GetState(&hi2c1) !=
HAL_I2C_STATE_READY);
     test = HAL_I2C_Mem_Read(&hi2c1, panel_touch_adresse, adresse_anpassen(mxt_object_message_count_t44.start_address), I2C_MEMADD_SIZE_16BIT, (uint8_t *)buffer, mxt_object_message_count_t44.size_minus_one +1, 100);

     if(test == HAL_ERROR)
     {
       HAL_GPIO_WritePin(GPIOG, GPIO_PIN_7, RESET);
       HAL_Delay(1000);
     }
     if(test == HAL_BUSY)
     {
       HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_10);
       HAL_Delay(1000);


       SET_BIT(hi2c1.Instance->CR1, I2C_CR1_STOP);
       I2C_WaitOnFlagUntilTimeout(&hi2c1, I2C_FLAG_BUSY, SET, 1000,HAL_GetTick());
     }
     if(test == HAL_TIMEOUT)
     {
       HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_12);
       HAL_Delay(1000);
     }


     zaehler++;
     if (zaehler >=2) test = HAL_OK;


  }while(test !=
HAL_OK);

Outcomes