I was curious to see what app code you ran as part of your test.
The Arduino ESP32 HAL has none of the corrections the IDF HAL has but is otherwise similar. The fact that you have to add that much more correction to both SCL low and high periods is similar to what I experience - but while that makes the numbers work out better it's not really a fix.
Here's the original code, plus your correction:
Code: Select all
int half_cycle = ( I2C_APB_CLK_FREQ / i2c_conf->master.clk_speed ) / 2;
I2C[i2c_num]->scl_low_period.period = half_cycle -1 -8; // 7.3.2017 JKJ Hotfix
I2C[i2c_num]->scl_high_period.period = ( I2C_APB_CLK_FREQ / i2c_conf->master.clk_speed ) - half_cycle - 1 -8; // 7.3.2017 JKJ Hotfix
If we reduce this code algebraically and move the padding to variables, we see both scl_low_period.period and scl_high_period.period are actually exactly the same:
Code: Select all
int espressif_pad_value = -1; // As seen ONLY in the IDF's HAL
int extra_pad_value = -8; // 7.3.2017 JKJ Hotfix
int half_cycle = ( I2C_APB_CLK_FREQ / i2c_conf->master.clk_speed ) / 2;
I2C[i2c_num]->scl_low_period.period = half_cycle + espressif_pad_value + extra_pad_value;
I2C[i2c_num]->scl_high_period.period = half_cycle + espressif_pad_value + extra_pad_value;
I suspect the -1 padding in the IDF HAL was an attempt to correct the 100kHz SCL - it's insufficient for the 400kHz SCL (I'm really surprised it helped for both of your tests). The Arduino side had no corrections - just the "half-cycle" value.
In short, I wouldn't recommend either pad value, as they are correcting for a condition that isn't characterized (and the correction doesn't scale across the different operating frequencies). There's something else going on here, and it'd be good to get some solid feedback from Espressif on this.
However, the fact that the -1 corrections sprinkled in above and the arbitrary 1:1 duty cycle used across the board both apparently came out of Espressif makes me wonder if there is *any* correct answer to be had yet. I don't think this problem has actually been characterized and I am worried it's a chip-level flaw that renders I2C degraded or just plain broken.