cancel
Showing results for 
Search instead for 
Did you mean: 

I2C Slave "HAL_I2C_SlaveRxCpltCallback" is not called when transmit completes

phoenixjia
Associate III

I am setting up I2C communication between a master board (STM32H753I-EVAL2) and a slave board (NUCLEO-H753ZI). At the master board side, I use "HAL_I2C_Master_Seq_Transmit_IT(&hi2c1, 96<<1, (uint8_t*)gTxBuffer, 4, I2C_FIRST_AND_LAST_FRAME)" to start the transmit, and set up "HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *I2cHandle)" to handle transmit complete interrupt. At the slave board side, I use "HAL_I2C_Slave_Seq_Transmit_IT(&hi2c2, (uint8_t*) gTxBuffer, 4, I2C_FIRST_AND_LAST_FRAME)" to set up the receive interrupt as soon as "HAL_I2C_AddrCallback" ISR handle is called. The problem is "HAL_I2C_SlaveRxCpltCallback" is not called. At the master board side, "HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *I2cHandle)" is called once the 4 bytes transmit completes. But the "HAL_I2C_SlaveRxCpltCallback" never gets called at the slave board. I step into the HAL code, found out that when "I2C_ITSlaveCplt" is called, I2C state is still HAL_I2C_STATE_BUSY_RX_LISTEN, the code "store last receive data", but it is only 1 byte, therefore hi2c->XferCount is not 0 and it goes to the error state.

The code snippet from HAL is posted below. I do not know why only 1 byte is received then goes to the error state. Does "I2C_ITSlaveCplt" get called when every byte is received or the entire date stream (4 bytes in my case) is received?

 

/* Store Last receive data if any */

if (I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_RXNE) != RESET)

{

/* Remove RXNE flag on temporary variable as read done */

tmpITFlags &= ~I2C_FLAG_RXNE;

 

/* Read data from RXDR */

*hi2c->pBuffPtr = (uint8_t)hi2c->Instance->RXDR;

 

/* Increment Buffer pointer */

hi2c->pBuffPtr++;

 

if ((hi2c->XferSize > 0U))

{

hi2c->XferSize--;

hi2c->XferCount--;

}

}

 

/* All data are not transferred, so set error code accordingly */

if (hi2c->XferCount != 0U)

{

/* Set ErrorCode corresponding to a Non-Acknowledge */

hi2c->ErrorCode |= HAL_I2C_ERROR_AF;

}

1 ACCEPTED SOLUTION

Accepted Solutions
phoenixjia
Associate III

The problem is solved by move "HAL_I2C_Master_Seq_Transmit_IT" to the initialization part of the code, not after the "HAL_I2C_AddrCallback".

View solution in original post

1 REPLY 1
phoenixjia
Associate III

The problem is solved by move "HAL_I2C_Master_Seq_Transmit_IT" to the initialization part of the code, not after the "HAL_I2C_AddrCallback".