Closed
Description
- [ Y ] I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
- [ N ] I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
- [ Y ] I have searched the issue tracker for a similar issue and not found a similar issue.
Environment
- Development Kit: LOLIN D32
- Module or chip used: ESP32-WROOM-32
- IDF version: v3.3
- Build System: Make
- Compiler version: xtensa-esp32-elf-gcc.exe (crosstool-NG crosstool-ng-1.22.0-80-g6c4433a5) 5.2.0
- Operating System: Windows
- Power Supply: USB
Problem Description
A continuation of https://esp32.com/viewtopic.php?f=13&t=13016
The ESP-IDF docs do not specify a minimum I2C clock speed so I assumed that a low speed of for example 1K would be possible. But it is not.
This is the source doc:
uint32_t clk_speed; /*!< I2C clock frequency for master mode, (no higher than 1MHz for now) */
Expected Behavior
Setting a I2C clock speed < 5000 using ESP-IDF should enable approx. that clock speed (5% deviation is fine). Or return an error that the value is out of bounds.
Actual Behavior
Setting a clock speed of 1000 results in a real clock speed of 5511. See below of other examples.
I ran a few tests using a logic analyzer.
Test using separate short 10 centimer wires for VCC GND SCL SDA.
The actual clock speed is inconsistent when specifying values lower than 5K:
STATUS I2C CLK_SPEED SCL MeasuredSpeed
=======================================
Error 100 5800 !
Error 1000 5511 !
Error 2000 10000 !
Ok 4000 3989
Ok 5000 4983
Ok 20000 19750
Ok 100000 94120
Ok 400000 320000
Code to reproduce this issue
if (param_ptr_config->manage_i2c_driver == true) {
// Config
i2c_config_t i2c_conf = { 0 };
i2c_conf.mode = I2C_MODE_MASTER;
i2c_conf.master.clk_speed = param_ptr_config->i2c_clk_speed;
i2c_conf.scl_io_num = param_ptr_config->i2c_scl_gpio_num;
i2c_conf.sda_io_num = param_ptr_config->i2c_sda_gpio_num;
i2c_conf.scl_pullup_en = param_ptr_config->i2c_scl_pullup_en;
i2c_conf.sda_pullup_en = param_ptr_config->i2c_sda_pullup_en;
f_retval = i2c_param_config(param_ptr_config->i2c_port_num, &i2c_conf);
if (f_retval != ESP_OK) {
ESP_LOGE(TAG, "ABORT. i2c_param_config() error (%i)", f_retval);
// LABEL
goto cleanup;
}
// ...
}