From b6c06cf13f8152f0faa93e6c7f5f8e24a575ac4e Mon Sep 17 00:00:00 2001 From: Aurora-QIU0 <2170685247@qq.com> Date: Thu, 17 Sep 2026 12:20:26 +0800 Subject: [PATCH] risc-v/espressif: Fix I2C polling wait timeout comparison. clock_t is an unsigned type unless CONFIG_SYSTEM_TIME64 is selected, as documented in sys/types.h. The difference in while (current - timeout < 0 && priv->error == 0) therefore underflows to a large positive value instead of being negative, the comparison is always false, and the loop body never runs. status keeps its initial value of zero and the function returns OK without having waited for the transfer at all. Because the polling path reports completion immediately, every transfer looks successful: no timeout is ever raised and register reads return whatever the RX FIFO happens to contain. The function is compiled in under CONFIG_I2C_POLLED, which boards use when the I2C interrupt is not wired up. Cast the difference to int32_t to get the intended signed comparison. The result also stays correct across the counter wrap, as long as the timeout is shorter than the counter range, which SEC2TICK(10) satisfies. Since this file is modified by this commit, the pre-existing nxstyle violations reported by the check job are fixed as well, as asked in CONTRIBUTING.md section 2.1 (adapt all modified files even if you did not introduce the problem yourself): * esp_i2c.c:1267 - statement over-indented inside its enclosing block (8 spaces where the block body is at 6) * esp_i2c.c:1303 - missing blank line after declarations * esp_i2c.c:1592 - missing blank line after declarations * esp_i2c.c:1710-1725 - 'case'/'default' labels inside switch(port) sat at the same indent as the brace opening the switch body; they belong one level further in, with the case logic one more level in from the label Assisted-by: WorkBuddy:DeepSeek-V4.1-Flash Signed-off-by: Aurora-QIU0 <2170685247@qq.com> --- arch/risc-v/src/common/espressif/esp_i2c.c | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/arch/risc-v/src/common/espressif/esp_i2c.c b/arch/risc-v/src/common/espressif/esp_i2c.c index 3dc652c99164b..cc8a9fc4cc6de 100644 --- a/arch/risc-v/src/common/espressif/esp_i2c.c +++ b/arch/risc-v/src/common/espressif/esp_i2c.c @@ -1064,7 +1064,7 @@ static int esp_i2c_polling_waitdone(struct esp_i2c_priv_s *priv) * and an error didn't occur within the timeout */ - while (current - timeout < 0 && priv->error == 0) + while ((int32_t)(current - timeout) < 0 && priv->error == 0) { /* Check if any interrupt triggered, clear them * process the operation. @@ -1264,7 +1264,7 @@ static int esp_i2c_transfer(struct i2c_master_s *dev, } #endif - i2cinfo("Message %" PRIu8 " transfer complete.\n", priv->msgid); + i2cinfo("Message %" PRIu8 " transfer complete.\n", priv->msgid); } /* Dump the trace result */ @@ -1300,6 +1300,7 @@ static void esp_i2c_clear_bus(struct esp_i2c_priv_s *priv) clock_t start = clock_systime_ticks(); clock_t timeout = start + MSEC2TICK(I2C_CLR_BUS_TIMEOUT_MS); + while (i2c_ll_master_is_bus_clear_done(priv->ctx->dev)) { if (clock_systime_ticks() >= timeout) @@ -1589,6 +1590,7 @@ static inline void esp_i2c_process(struct esp_i2c_priv_s *priv, struct i2c_msg_s *msg = &priv->msgv[priv->msgid]; #ifdef CONFIG_I2C_TRACE uint32_t status = 0; + status = GET_STATUS(priv->ctx->dev); #endif /* Check for any errors */ @@ -1707,22 +1709,22 @@ struct i2c_master_s *esp_i2cbus_initialize(int port) switch (port) { #ifdef CONFIG_ESPRESSIF_I2C0_MASTER_MODE - case ESPRESSIF_I2C0: - priv = &esp_i2c0_priv; - break; + case ESPRESSIF_I2C0: + priv = &esp_i2c0_priv; + break; #endif #ifdef CONFIG_ESPRESSIF_I2C1_MASTER_MODE - case ESPRESSIF_I2C1: - priv = &esp_i2c1_priv; - break; + case ESPRESSIF_I2C1: + priv = &esp_i2c1_priv; + break; #endif #ifdef CONFIG_ESPRESSIF_LP_I2C0 - case ESPRESSIF_LP_I2C0: - priv = &esp_lp_i2c0_priv; - break; + case ESPRESSIF_LP_I2C0: + priv = &esp_lp_i2c0_priv; + break; #endif - default: - return NULL; + default: + return NULL; } nxmutex_lock(&priv->lock);