Electronic – ST Microelectronics I2C Interrupt HAL Library question

hal-libraryi2cstm32

I am trying to get I2C (with interrupts) on an F411RE to work. I dived into the HAL library code and found this tid bit…

static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c)
{
  /* Declaration of temporary variables to prevent undefined behavior of  volatile usage */
  uint32_t CurrentState = hi2c->State;

  if(hi2c->XferCount != 0U)
  {
    /* Write data to DR */
    hi2c->Instance->DR = (*hi2c->pBuffPtr++);
    hi2c->XferCount--;

    if((hi2c->XferCount == 0U) && (CurrentState ==          HAL_I2C_STATE_BUSY_TX_LISTEN))
    {
      /* Last Byte is received, disable Interrupt */
      __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF);

      /* Set state at HAL_I2C_STATE_LISTEN */
      hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX;
      hi2c->State = HAL_I2C_STATE_LISTEN;

      /* Call the Tx complete callback to inform upper layer of the end of receive process */
      HAL_I2C_SlaveTxCpltCallback(hi2c);
    }
  }
  return HAL_OK;

I am little confused. I was expecting to see while loop go through the transfer count. Instead, it is if statements. So, my question is, am I understanding this correctly? The way that HAL treats a slave transmits on interrupt is that it relies on an interrupt to be generated for each byte of the transfer instead of one interrupt for transferring all the bytes at once?

Best Answer

Yes I think you understood that correctly.

And if you think about it, that's the whole point of interrupts. You don't need interrupts when you simply loop over the array and wait for each byte.

The interrupts allow your program to do stuff while the I²C transaction is ongoing.

The other thing with only one interrupt would be using DMA to feed the data to the I²C peripheral.


From the implementation work I've done on an own HAL for the F401, I'd recommend you to use the interrupt capability only for the bulk transmission or reception. I encountered strange interrupts with no source (no bits set in the registers) while trying to implement a purely interrupt driven approach for the I²C.