From d6ae4a03428060206dc1eb0b15cb4bf67075c719 Mon Sep 17 00:00:00 2001 From: Kevin Zhou Date: Sat, 14 Sep 2024 15:55:19 +0800 Subject: [PATCH] xtensa/esp32s3: Adjust I2C clock timing --- arch/xtensa/src/esp32s3/esp32s3_i2c.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/src/esp32s3/esp32s3_i2c.c b/arch/xtensa/src/esp32s3/esp32s3_i2c.c index 5b29f321b1..25526ab21c 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_i2c.c +++ b/arch/xtensa/src/esp32s3/esp32s3_i2c.c @@ -662,12 +662,15 @@ static void i2c_init_clock(struct esp32s3_i2c_priv_s *priv, /* According to the Technical Reference Manual, the following timings must * be subtracted by 1. - * Moreover, the frequency calculation also shows that we must subtract 3 - * to the total SCL. + * However, according to the practical measurement and some hardware + * behaviour, if wait_high_period and scl_high minus one. The SCL frequency + * would be a little higher than expected. Therefore, the solution here is + * not to minus scl_high as well as scl_wait_high, and the frequency will + * be absolutely accurate to all frequency to some extent. */ scl_low = half_cycle; - putreg32(scl_low - 1 - 2, I2C_SCL_LOW_PERIOD_REG(priv->id)); + putreg32(scl_low - 1, I2C_SCL_LOW_PERIOD_REG(priv->id)); /* By default, scl_wait_high must be less than scl_high. * A time compensation is needed for when the bus frequency is higher @@ -678,8 +681,8 @@ static void i2c_init_clock(struct esp32s3_i2c_priv_s *priv, (half_cycle / 5 * 4 + 4); scl_wait_high = half_cycle - scl_high; - reg_value = VALUE_TO_FIELD(scl_high - 1 - 1, I2C_SCL_HIGH_PERIOD); - reg_value |= VALUE_TO_FIELD(scl_wait_high - 1 - 1, + reg_value = VALUE_TO_FIELD(scl_high, I2C_SCL_HIGH_PERIOD); + reg_value |= VALUE_TO_FIELD(scl_wait_high, I2C_SCL_WAIT_HIGH_PERIOD); putreg32(reg_value, I2C_SCL_HIGH_PERIOD_REG(priv->id));