cancel
Showing results for 
Search instead for 
Did you mean: 

Executing HAL_I2C_Master_Transmit_IT function holds SCL low.

SomeGuyFromNH
Associate II

Hi,

I found in my search there is a similar question that went unanswered. This may be a newb question, but I'm stuck on it.

What I have found is that when executing HAL_I2C_Master_Transmit(), the data transfer happens as expected. (I happen to have green LEDs hanging on GPIO). When I execute HAL_I2C_Master_Transmit_IT(), only the 7-bit address is sent, and the Master (this program) continues to hold the SCL line low.

If someone could explain what I am doing wrong with the HAL_I2C_Master_Transmit_IT() program, that would be much appreciated!

	  //Turn on the two green LEDs on the LTC4306's GPIO
	  data[0] = 0x01;
	  data[1] = 0b00001111;
	  status = HAL_I2C_Master_Transmit(&hi2c1, ltc4306_Address, data, 2, 1 );
 
	  //Turn off the two green LEDs on the LTC4306's GPIO
	  data[0] = 0x01;
	  data[1] = 0b00111111;
	  status = HAL_I2C_Master_Transmit(&hi2c1, ltc4306_Address, data, 2, 1 );
 
	  //Turn on the two green LEDs on the LTC4306's GPIO
	  data[0] = 0x01;
	  data[1] = 0b00001111;
	  status = HAL_I2C_Master_Transmit_IT(&hi2c1, ltc4306_Address, data, 2 ); //This returns HAL_OK... but the master (this program) is holding SCL low after having transmitted the 7-bit address.
	  HAL_I2C_MasterTxCpltCallback(&hi2c1); // SCL still being held low after execution of this line. Doesn't seem to help. 

13 REPLIES 13
GFedo.1
Associate

I had similar problem. If you had something like that:

uint8_t fn{

uint8_t data[2];

data[0] = 0x01;

data[1] = 0b00001111;

status = HAL_I2C_Master_Transmit(&hi2c1, ltc4306_Address, data, 2, 1 );

data[0] = 0x01;

data[1] = 0b00111111;

status = HAL_I2C_Master_Transmit(&hi2c1, ltc4306_Address, data, 2, 1 );

data[0] = 0x01;

data[1] = 0b00001111;

status = HAL_I2C_Master_Transmit_IT(&hi2c1, ltc4306_Address, data, 2 );

return 0;

}

In the moment, when you execute return line, you pop fn function pointer from stack. i2c takes data from different place in memory and NACK on SDA occurs -> transmitting is stopped.

txnghia
Associate II

You probably missed the I2C1 interrupt handler function. I had a similar problem when executing this function HAL_I2C_Master_Transmit_IT(). After I added the interrupt handler function, the problem was fixed.

I added I2C1 interrupt handler in to the "stm32fxxx_it.c" file as below:

/* External variables --------------------------------------------------------*/

extern I2C_HandleTypeDef hi2c1;

void I2C1_IRQHandler(void)

{

 if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {

  HAL_I2C_ER_IRQHandler(&hi2c1);

 } else {

  HAL_I2C_EV_IRQHandler(&hi2c1);

 }

}

And don't forget to add I2C1 interrupt enable to this function HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)

  HAL_NVIC_SetPriority(I2C1_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(I2C1_IRQn);

Hope it helps.

txnghia
Associate II

You probably missed the I2C1 interrupt handler function. I had a similar problem. After I added the interrupt handler function, the problem is fixed.

I added the interrupt handler to "stm32f0xx_it.c" file as below. (I use STM32F072RBT6 chip)

void I2C1_IRQHandler(void)

{

 if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {

  HAL_I2C_ER_IRQHandler(&hi2c1);

 } else {

  HAL_I2C_EV_IRQHandler(&hi2c1);

 }

}

And also added I2C1 interrupt initialization to HAL_I2C_MspInit() function as below

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 if(hi2c->Instance==I2C1)

 {

  __HAL_RCC_GPIOB_CLK_ENABLE();

  /**I2C1 GPIO Configuration

  PB8   ------> I2C1_SCL

  PB9   ------> I2C1_SDA

  */

  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;

  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;

  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* Peripheral clock enable */

  __HAL_RCC_I2C1_CLK_ENABLE();

  /* I2C1 interrupt Init */

  HAL_NVIC_SetPriority(I2C1_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(I2C1_IRQn);

 }

HYih.1
Associate

I am using STM32H745I-DISCO board. STM32CubeMX v6.5.0. generates interrupt handlers:

void I2Cx_EV_IRQHandler(void)

void I2Cx_ER_IRQHandler(void)

and MspInit function:

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)