I2C SCL frequency 10% less than it should be at 400kHz

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby Jakobsen » Tue Mar 07, 2017 12:02 pm

Hi
My hot fix for the i2c_scl clock below

I tried also to change I2C[i2c_num]->sda_sample.time = half_cycle - but did not get to a stable setup.
From time to time the driver gets to unrecoverable stated with random data on data/clk line :-(

Code: Select all

I2C[i2c_num]->fifo_conf.nonfifo_en = 0;
    }
    //set frequency      7.3.2017/JKJ hotfix  - 8 scl_low/high_period to get correct timing   
    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   
    //set timing for start signal
    I2C[i2c_num]->scl_start_hold.time = half_cycle;
    I
Image
Image

/j
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby MartyMacGyver » Tue Mar 07, 2017 8:44 pm

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.

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby MartyMacGyver » Tue Mar 07, 2017 9:18 pm

I tried your correction along with Espressif's, as you did above. I even reverted to the 1:1 duty cycle to test it. The 100kHz SCL was just about 99kHz, and the 400kHz SCL was around 397kHz.

However, that was with two I2C devices I was testing with (OLED with 4.7Kohm pull-ups + a digital barometric sensor with 10Kohm pull-ups). I took the OLED out and re-ran the test... 100kHz SCL -> 97 kHz actual, 400kHz SCL -> 375kHz actual.

Then I took out the sensor and added 1.5Kohm resistors as pull-ups. 400kHz SCL -> 408kHz now, and so on.

For comparison, I tried similar load tests on the Particle Photon (ignoring the branding, it's an STM32 and it's not doing anything special besides following the I2C standard when it comes to register settings - no special corrections). 400kHz SCL ~= 400Khz actual for a wide range of loads, and no need for the dramatic pulldowns necessary to get the ESP32 to even approach the SCL it's set to. Basically I get none of the weird side-effects there (particularly with the OLED) and it "just works".

I really want to see the ESP32 "just work" too - I didn't come into this to compare devices, because I didn't expect I2C of all things to have problems, and certainly not ones as weird as this. There are significant advantages with the dual core design, etc. that led me to the ESP32 - but right now it's very unreliable when it comes to I2C.

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby Jakobsen » Tue Mar 07, 2017 10:32 pm

Hi
I also found that my hot fix works for both 100kbps and 400kbps. I measure frequency on the 8 first scl clock only. period of 9 th clock (ACK) is still long and random.

From a system perspective i would never relay on any derived frequency from a i2c interface - Do you have any reason for doing so?

For me it is the stability issues that is bigger concern - i had a closer look at the i2c driver and found that there are relative much interrupt going on and my guess is that I am hit by task switch, interrupt, linked command list collision.

I would love to see a more simple driver that uses the hardware more direct instead of the driver that adds a layer that is not usefull in must simple setup.

One thing I have not tried is to use the other bus...

All a matter of time and priority /j
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby MartyMacGyver » Tue Mar 07, 2017 11:59 pm

This comes back to how exactly you are testing this - what pins are you using? Which bus? Which *board*? What code?

Yes, I'm checking normal clocks within the data stream, not the potentially stretched clock periods. The frequencies are off. Try adding some load, an extra I2C device or at least some more pull-ups and see what the clock does.

As noted earlier, the hotfix of padding the period values works somewhat, but the clock still varies as load increases. While I don't "rely" on it, I expect it not to vary significantly just because I add a device (and I expect it to be close to the expected value too, not >10% off for defined values). This thing is all over the map.

As for the HAL, it's about as close to the hardware as you can get, and the steps above and below it are at most doing register mapping and function mapping.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby WiFive » Thu Mar 09, 2017 12:56 am

I was briefly looking at this and it seems there is compensation for rise/fall times built in so that if you have a weak pullup and a long rise time the high period timer is not going to start until the signal goes above 1.8v. Since the negative edge is sharp, the low time is accurate. So this is sort of a relative clock, not absolute. Not sure of the implications, just observing.

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby ESP_igrr » Thu Mar 09, 2017 7:24 am

When the pads are used in open-drain mode, the frequency will not be the same as defined by 1/(low_period + high_period), but will be lower (as you have found). The higher frequency is used, the higher will the difference be.
ESP-IDF I2C driver doesn't take this into account, but it can be extended to correct the periods by certain amount based on bus loading, pullup resistance, and clock frequency.
We could possibly even estimate this automatically, by discharging the capacitance of the SCL line using a GPIO and then measuring charging rate (using an ADC or a GPIO).

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby MartyMacGyver » Thu Mar 09, 2017 11:10 am

That strikes me as peculiar... the STM32 operates I2C in open drain mode and doesn't have anything as near as much trouble keeping near the frequency (and the clock settings are straightforward - no fiddle factors). Is there any pull-up value that will produce an actual 400kHz when SCL is configured exactly for that speed in the registers? Best I've seen is the high 380K's, with sub-1Kohm pull-ups (which is way too much pull-up IMHO).

Yes, one can always add correction factors that scale in some way, but that likely affects all the other settings as well... and in the end, it doesn't solve the sensitivity of the lines to capacitance variances just by having a hand near it (a sensitivity I've not seen elsewhere).

ESP_igrr
Posts: 2072
Joined: Tue Dec 01, 2015 8:37 am

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby ESP_igrr » Thu Mar 09, 2017 12:09 pm

MartyMacGyver wrote:Is there any pull-up value that will produce an actual 400kHz when SCL is configured exactly for that speed in the registers?
No, there isn't. The high half-period duration counter only starts ticking when the line actually crosses from low to high logic level (well, it's slightly more complicated, but nevertheless...). It's the transition time from low to high which isn't taken into account when calculating half-period values based on the desired frequency.

MartyMacGyver
Posts: 56
Joined: Sun Dec 18, 2016 9:17 pm

Re: I2C SCL frequency 10% less than it should be at 400kHz

Postby MartyMacGyver » Wed Mar 22, 2017 7:09 am

I was away for a short time. I see your point about rise times and such, but despite that I2C on the ESP32 is proving to be tricky and not very reliable. I've been watching my STM32 drive an I2C OLED display flawlessly for an hour now at 400KHz... the ESP32 is lucky to do it for a minute before glitching, and while re-shaping the waveform helped a bit it seemed, it's not the solution I hoped for. This glitchy behavior is unacceptable and I'd like to know how to fix this problem or whether it's some known bug in the chip itself.

Who is online

Users browsing this forum: No registered users and 12 guests