xtensa/esp32s3: Adjust I2C clock timing

This commit is contained in:
Kevin Zhou 2024-09-14 15:55:19 +08:00 committed by Xiang Xiao
parent 1af4cdf500
commit d6ae4a0342

View File

@ -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));