-
Notifications
You must be signed in to change notification settings - Fork 11
Description
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
Type
Projects
Status