cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_IsDeviceReady problem and others

Marco1
Associate II
Posted on May 03, 2016 at 14:07

It's normal that you send the timeout to this function and inside call I2C_WaitOnFlagUntilTimeout with I2C_TIMEOUT_BUSY_FLAG, ( 10 seconds ) ?

If not ready, this function block all for about 10 seconds indipendently from timeout setted

HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)

{

  uint32_t tickstart = 0, tmp1 = 0, tmp2 = 0, tmp3 = 0, I2C_Trials = 1;

  if(hi2c->State == HAL_I2C_STATE_READY)

  {

    /* Wait until BUSY flag is reset */

    if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK)

Another problem is during HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c), after the line 

/* Peripheral clock enable */

__HAL_RCC_I2C2_CLK_ENABLE();

you can found setted (in random way) the bit BUSY of register I2C_SR2. 

Sorry for my english
3 REPLIES 3
slimen
Senior
Posted on May 06, 2016 at 17:41

Hi,

Could you precise which firmware package are you using ?

Locking for BUSY flag as described in the silicon errata in

http://www2.st.com/content/ccc/resource/technical/document/errata_sheet/7d/02/75/64/17/fc/4d/fd/CD00190234.pdf/files/CD00190234.pdf/jcr:content/translations/en.CD00190234.pdf

Regards
slimen
Senior
Posted on May 09, 2016 at 16:37

Hi,

1- I2C_TIMEOUT_BUSY_FLAG is predefinied to be 10s (#define I2C_TIMEOUT_BUSY_FLAG ((uint32_t)10000U)) and used to check BUSY flag.

However, the parameter ''Timeout'' is used in this check inside the function ''HAL_I2C_IsDeviceReady'': I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout).

 

2- Regarding the second issue (BUSY flag set after enabling I2C clock), try to configure GPIOs and enable alternate functions first, then enable I2C clock.

Regards
Marco1
Associate II
Posted on May 10, 2016 at 10:38

Thank you for answer,

i'm using STM32CubeMX 4.14.0

Why not put directly inside the initialization code a little fix to solve this problem ?

This is your parts of init code

GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;

GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

GPIO_InitStruct.Pull = GPIO_PULLUP;

HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );

/* Peripheral clock enable */

__HAL_RCC_I2C2_CLK_ENABLE(); // after this line, you can found BUSY flag set also if line of SDA and SCL are high

/* Peripheral interrupt init */

HAL_NVIC_SetPriority(I2C2_EV_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);

HAL_NVIC_SetPriority(I2C2_ER_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(I2C2_ER_IRQn);

I saw the errata and says to put high interrupt priority for I2C (priority 0) and lower to all others ... I need to reduce the priority also to system tick?

About 10 Seconds, you can see inside your function...try to call it with timeout of 100ms and I2C_FLAG_BUSY is set.

HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)

{

  uint32_t tickstart = 0, tmp1 = 0, tmp2 = 0, tmp3 = 0, I2C_Trials = 1;

  if(hi2c->State == HAL_I2C_STATE_READY)

  {

    /* Wait until BUSY flag is reset */

    if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) //10 second of timeout

    {

      return HAL_BUSY;  

    }

Bye Marco