cancel
Showing results for 
Search instead for 
Did you mean: 

HAL I2C driver HAL_I2C_IsDeviceReady() returns HAL_TIMEOUT

Magnus Eriksson
Associate
Posted on September 12, 2017 at 15:51

Hi

I have some problems with the I2C HAL driver. When I'm calling 

HAL_I2C_IsDeviceReady(), the function is returning HAL_TIMEOUT in my init function.

According to instructions on how to use I2C driver

@file stm32f1xx_hal_i2c.c

* @author MCD Application Team

* @version V1.1.1

* @date 12-May-2017

* @brief I2C HAL module driver.

(#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API:

(##) Enable the I2Cx interface clock

(##) I2C pins configuration

(+++) Enable the clock for the I2C GPIOs

(+++) Configure I2C pins as alternate function open-drain

(##) NVIC configuration if you need to use interrupt process

(+++) Configure the I2Cx interrupt priority

(+++) Enable the NVIC I2C IRQ Channel

(#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1,

Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure.

(#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware

(GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API.

(#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady()

I think I have done Above instructions.

My code:

i2cinit(){

__HAL_RCC_I2C2_CLK_ENABLE();

hi2c.Instance = I2C2;

hi2c.Init.ClockSpeed = 100000; //100kHz CLK

hi2c.Init.DutyCycle = I2C_DUTYCYCLE_2;

hi2c.Init.OwnAddress1 = 0;

hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

hi2c.Init.OwnAddress2 = 0;

hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

if (HAL_I2C_Init(&hi2c) != HAL_OK){

_Error_Handler(__FILE__, __LINE__);

}

DevAddress = 0x55; 

HAL_StatusTypeDef init;

init = HAL_I2C_IsDeviceReady(&hi2c, DevAddress, 2, 15);

if(init != HAL_OK){

asm('bkpt 0');

}

...

..

.

}

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c)

{

uint32_t freqrange = 0U;

uint32_t pclk1 = 0U;

/* Check the I2C handle allocation */

if(hi2c == NULL)

{

return HAL_ERROR;

}

/* Check the parameters */

assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance));

assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed));

assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle));

assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1));

assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode));

assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode));

assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2));

assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode));

assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode));

if(hi2c->State == HAL_I2C_STATE_RESET)

{

/* Allocate lock resource and initialize it */

hi2c->Lock = HAL_UNLOCKED;

/* Init the low level hardware : GPIO, CLOCK, NVIC */

HAL_I2C_MspInit(hi2c);

}

...

..

.

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)

{

GPIO_InitTypeDef GPIO_InitStruct;

if(hi2c->Instance==I2C2)

{

/* USER CODE BEGIN I2C2_MspInit 0 */

/* USER CODE END I2C2_MspInit 0 */

/**I2C2 GPIO Configuration

PB10 ------> I2C2_SCL

PB11 ------> I2C2_SDA

*/

GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;

GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* Peripheral clock enable */

__HAL_RCC_I2C2_CLK_ENABLE();

/* I2C2 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);

/* USER CODE BEGIN I2C2_MspInit 1 */

/* USER CODE END I2C2_MspInit 1 */

}

}

...

..

.

}

I have set All other interrupt to lower priorityes. Have also tested with with different prioritys but it seams that this will not work. 

Can anyone point me in the right direction on how to solve this problem?

//Magnus

1 REPLY 1
Magnus Eriksson
Associate
Posted on September 14, 2017 at 07:53

I have found out that the code returns HAL_TIMEOUT from the function 

HAL_I2C_IsDeviceReady() line 3333 in stm32f1xx_hal_i2c.c

/* Generate Start */

hi2c->Instance->CR1 |= I2C_CR1_START;

/* Wait until SB flag is set */

tickstart = HAL_GetTick(); //Added by user.

if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)

{

return HAL_TIMEOUT;

}