Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2C spikes on master init #393

Closed
berkutta opened this issue Mar 2, 2017 · 3 comments
Closed

I2C spikes on master init #393

berkutta opened this issue Mar 2, 2017 · 3 comments

Comments

@berkutta
Copy link

berkutta commented Mar 2, 2017

I'm using a own function names "i2c_master_init()" to initialize the i2c subsystem on the ESP32. After calling this function I get pulses/spikes on SDA/SCL which some Slaves interprets as an "START". This behaviour results in errors on later real "START"'s which prevents to directly use those Slaves. A workaround is to make a dummy request to those Slaves ("START", WRITE ADDRESS", "STOP")

My hardware consists of no external Pullups. I've used the Sparkfun ESP32 Thing together with an MPU-6050. I was able to reproduce the same Issue with a HTU21D Sensor.

My function "i2c_master_init()" consists of the following startup tasks:

void i2c_master_init()
{
    int i2c_master_port = I2C_MASTER_NUM;
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_MASTER_SDA_IO;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = I2C_MASTER_SCL_IO;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
    i2c_param_config(i2c_master_port, &conf);
    i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

My sequence to make those "dummy" requests is the following:

i2c_cmd_handle_t cmd_ping = i2c_cmd_link_create();
i2c_master_start(cmd_ping);
i2c_master_write_byte(cmd_ping, (0x68 << 1) | WRITE_BIT, ACK_CHECK_DIS);
i2c_master_stop(cmd_ping);
int ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd_ping, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd_ping);

After this "dummy" sequence I can normally talk to the slave device:

i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (0x68 << 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x6B, ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);

On this image you can see an overview of the spike (Trigger point) and the followed byte write's:
ds1z_quickprint10

Here is a closeup of the spike:
ds1z_quickprint11

This is a closeup of the "dummy" request + data write. You can clearly see that on the "dummy" request the sensor doesn't work properly (confused state machine due to the spike) and afterwords work perfectly with it's address:
ds1z_quickprint12

@costaud
Copy link
Collaborator

costaud commented Mar 3, 2017

Thanks for the very clear description. I think it might be related to "no external Pullups", I will try to look into this.

@berkutta
Copy link
Author

berkutta commented Mar 3, 2017

I tried to reproduce this issue with strong Pullups on SDA and SCL (1kOhm). Exactly the same behaviour.
I've even tried to use a Ferrite bead between ESP32 and Sensor on both lines. This helped in some situatons on the ESP8266. But no luck on the ESP32..

@costaud
Copy link
Collaborator

costaud commented Mar 19, 2017

Add set level code in i2c_set_pin can fix the issue. Trying to merge to idf ASAP.

esp_err_t i2c_set_pin(i2c_port_t i2c_num, gpio_num_t sda_io_num, gpio_num_t scl_io_num, gpio_pullup_t sda_pullup_en, gpio_pullup_t scl_pullup_en, i2c_mode_t mode)
{
    .......
    if (sda_io_num >= 0) {
        gpio_set_level(sda_io_num, 1);
        PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[sda_io_num], PIN_FUNC_GPIO);
        ......
    }
    if (scl_io_num >= 0) {
        gpio_set_level(scl_io_num, 1);
        PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[scl_io_num], PIN_FUNC_GPIO);
        .......
    }
    ......   
}

igrr pushed a commit that referenced this issue Mar 23, 2017
Fix I2C spikes on master init.
This issue is reported from #393
Before I2C io init, set high level on SDA/SCK IOs.
@igrr igrr closed this as completed in 91d35f0 Mar 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants