Open astrogene1000 opened 5 months ago
i2c bus without pull up resistors is using out of specs. Don't expect anything working when doing this. On a bus the last device should have this resistors.
Sorry but the line state should not affect timeout's as to when the framework returns control to the calling program. The time span is always almost exactly 1000ms, not something random.
Actually it does make a difference as I2C also supports something like clock stretching. This is when a device can keep a pin (I think it is SCL, but could also be SDA) low to indicate it isn't ready yet.
IMHO this was an awful design decision, but we're stuck with it and thus also with sensors so poorly designed they actually need this clock stretching to work. (I3C no longer has this 'feature' :) )
Anyway, having the pins 'floating' or continuously 'pulled down' is undefined behavior and will cause timeouts as you're seeing.
If you want to see when this waiting actually occurs, you can set some other GPIO pins high/low in your code and add them to your logic analyzer. Since the write function and endTransmission both return some kind of result, it is essential that the data has been sent or at least attempted to be sent.
Totally appreciate what you are saying but will add the 1000ms seen is totally arbitrary and controlled someplace inside the framework. The ask here would be to expose allowing to set this timeout also.
You may need to check the code, but if my memory serves me right, then this timeout was coupled to the clock stretch timeout and I think there is some function to set the clock stretch. (at least there was some debate about it a while ago, when issues with clock stretching needs were raised for ESP32)
Whether this is strictly correct to consider "clock stretching" the same as timeout is up for debate, but I think these are now linked in ESP32 code.
The clock stretching timeout is set here https://github.com/tasmota/arduino-esp32/blob/main/cores/esp32/esp32-hal-i2c.c#L133
By the way, it seems like the I2C pins are by default also pulled up internally. See: https://github.com/tasmota/arduino-esp32/blob/fc1114d28e2957062459de2e99def2c04e1eec71/cores/esp32/esp32-hal-i2c.c#L115-L116 So if yours are not "high" then I guess you might be using pins that will be pulled down externally?
@TD-er, correct, the pullup's are on the far end.
@Jason2866 so following it through, //Clock Stretching Timeout: 20b:esp32, 5b:esp32-c3, 24b:esp32-s2 i2c_set_timeout((i2c_port_t)i2c_num, I2C_LL_MAX_TIMEOUT);
So basically set it to the largest value that fit's in 24 bits for an ESP32-s2 From: components/hal/esp32s2/include/hal/i2c_ll.h
With components/soc/esp32s2/include/soc/i2c_reg.h
Got it!
Thank you!
Gene
Board
ESP32-S2 based
Device Description
Multiple I2C devices
Hardware Configuration
GPIO 11 & 12 connected to I2C
Version
latest master (checkout manually)
IDE Name
1.8.19 with Arduino 3.0.0-Alpha3
Operating System
W10
Flash frequency
As per S2 spec
PSRAM enabled
yes
Upload speed
115200
Description
Hello all,
Wondering what is causing a delay on I2C when there is no pullup on SDA or SCL.
Now why no pull-up: 1) Connected to multiple I2C devices, each has a pullup, if cable is pulled the higher level program querying the ESP times out because the ESP is stuck in I2C write so cannot process the higher level program query.
I am using Wire library which provides wire.cpp which calls i2cWrite in esp32-hal-i2c.c which calls ret = i2c_master_cmd_begin((i2c_port_t)i2c_num, cmd, timeOutMillis / portTICK_PERIOD_MS);
Now whether I have timeoutMillis set to 5 or 50 or whatever, it is taking 1000ms for i2c_master_cmd_begin((i2c_port_t)i2c_num, cmd, timeOutMillis / portTICK_PERIOD_MS); to return.
During this 1000ms the SCL is gating out at my set frequency of 100khz See attached JPG
Thank you for you time!
Gene
Sketch
Debug Message
Other Steps to Reproduce
I also see same when using Arduino 2.0.14 Espessif.
I have checked existing issues, online documentation and the Troubleshooting Guide