Skip to content

I2C slave sets I2C_CR2_NACK after TX completes, but the peripheral address has already been received for a new transfer #17

@m4083888-blip

Description

@m4083888-blip

Hello,

I am experiencing NACKs on the client side when I2C requests (write/read, write/write) are sent repeatedly back to back.

HAL drivers version: v1.5.0-8-g539824f
MCU: STM32H523

The scenario in which the issue can be seen:
The I2C slave has completed transmitting, and the MCU has some work to do and cannot immediately process a new I2C request from a client that is issued immediately after the previous transfer is completed. However, the I2C peripheral has already matched the address of the new request and has set the I2C_FLAG_STOPF flag. When the MCU finally has time to process the I2C interrupt, it calls the function I2C_ITSlaveCplt from the interrupt handler:

  /* Check if STOPF is set */
  if ((I2C_CHECK_FLAG(tmpITFlags, I2C_FLAG_STOPF) != RESET) && \
      (I2C_CHECK_IT_SOURCE(ITSources, I2C_IT_STOPI) != RESET))
  {
    /* Call I2C Slave complete process */
    I2C_ITSlaveCplt(hi2c, tmpITFlags);
  }

The function sets the I2C_CR2_NACK flag, which inadvertently stops the active transfer.

The following workaround does not set the flag if I2C_FLAG_STOPF is set and the logical I2C state is HAL_I2C_STATE_BUSY_TX_LISTEN. The latter condition may not be necessary, though:

diff --git a/Src/stm32h5xx_hal_i2c.c b/Src/stm32h5xx_hal_i2c.c
index 5214c91..8546b1f 100644
--- a/Src/stm32h5xx_hal_i2c.c
+++ b/Src/stm32h5xx_hal_i2c.c
@@ -6582,8 +6582,11 @@ static void I2C_ITSlaveCplt(I2C_HandleTypeDef *hi2c, uint32_t ITFlags)
     /* Do nothing */
   }

-  /* Disable Address Acknowledge */
-  hi2c->Instance->CR2 |= I2C_CR2_NACK;
+  if (I2C_CHECK_FLAG(ITFlags, I2C_FLAG_STOPF) == RESET && tmpstate != HAL_I2C_STATE_BUSY_TX_LISTEN)
+  {
+    /* Disable Address Acknowledge */
+    hi2c->Instance->CR2 |= I2C_CR2_NACK;
+  }

   /* Clear Configuration Register 2 */
   I2C_RESET_CR2(hi2c);

Thank you!

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghalHAL-LL driver-related issue or pull-request.i2cInter-Integrated Circuit interfaceinternal bug trackerIssue confirmed and logged into the internal bug tracking system

Type

Projects

Status

Analyzed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions