I2C - Using both Ports - First Transaction fails

kb3523
Posts: 10
Joined: Thu Mar 08, 2018 11:32 pm

I2C - Using both Ports - First Transaction fails

Postby kb3523 » Sat Mar 21, 2020 4:15 pm

Dear ESP community,

If the i2c driver is 'installed twice', the first transaction of the first initialized port fails. Afterwards the communication happens without any error on both ports.
Am I initializing both ports correctly? Is there anything else I could consider?

My current ESP-IDF Version is: v4.0-dev-1443

Thank you all in advance


I can reproduce it with the following steps, its enough to have only one i2c device connected to the first initialized port to test it:

Code: Select all

#define I2C_DISTRIBUTED I2C_NUM_0
#define I2C_LOCAL       I2C_NUM_1
#define TEST_DEV_ADDR 0x20

esp_err_t i2c_master_init( i2c_port_t port );
int8_t bus_checkForACK(i2c_port_t port, uint8_t dev_addr);

void test_this_it_fails()
{
    i2c_master_init(I2C_LOCAL);
    i2c_master_init(I2C_DISTRIBUTED);

    while ( bus_checkForACK(I2C_LOCAL, 0x20 ) != ESP_OK )
    {
            printf("First Transaction on First initialized bus failed! \n ");
    }
}


//****************************************************************************
int8_t bus_checkForACK(i2c_port_t port, uint8_t dev_addr)
{
    i2c_cmd_handle_t cmd_link = i2c_cmd_link_create();

    i2c_master_start(cmd_link);
    i2c_master_write_byte(cmd_link, (dev_addr << 1) | I2C_MASTER_WRITE, true);
    esp_err_t ret = i2c_master_cmd_begin(port, cmd_link, pdMS_TO_TICKS(1000));
    i2c_cmd_link_delete(cmd_link);
    return (int8_t)ret;
}

esp_err_t i2c_master_init( i2c_port_t port )
{
    i2c_config_t conf;
    if ( I2C_DISTRIBUTED )
    {
        conf.mode = I2C_MODE_MASTER;
        conf.sda_io_num = GPIO_I2C_DIST_SDA;
        conf.scl_io_num = GPIO_I2C_DIST_SCL;
        conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
        conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
        conf.master.clk_speed = I2C_START_FREQ;
    }
    else if ( I2C_LOCAL )
    {
        conf.mode = I2C_MODE_MASTER;
        conf.sda_io_num = GPIO_I2C_LOCAL_SDA;
        conf.scl_io_num = GPIO_I2C_LOCAL_SCL;
        conf.sda_pullup_en = GPIO_PULLUP_DISABLE;
        conf.scl_pullup_en = GPIO_PULLUP_DISABLE;
        conf.master.clk_speed = 1000000;
    }
    else
    {
        printf("I2C Invalid Config! \n");
        return 0xFF;
    }
    if ( i2c_param_config(port, &conf) != ESP_OK )
    {
        printf("I2C Invalid Config! \n");
        return 0xFF;
    }

    return i2c_driver_install(port, conf.mode,
                              I2C_MASTER_RX_BUF_DISABLE,
                              I2C_MASTER_TX_BUF_DISABLE, ESP_INTR_FLAG_IRAM);

}


vonnieda
Posts: 145
Joined: Tue Nov 07, 2017 3:42 pm

Re: I2C - Using both Ports - First Transaction fails

Postby vonnieda » Sat Mar 21, 2020 7:00 pm

kb3523 wrote:
Sat Mar 21, 2020 4:15 pm
Dear ESP community,

If the i2c driver is 'installed twice', the first transaction of the first initialized port fails. Afterwards the communication happens without any error on both ports.
Am I initializing both ports correctly? Is there anything else I could consider?

My current ESP-IDF Version is: v4.0-dev-1443

Thank you all in advance


I can reproduce it with the following steps, its enough to have only one i2c device connected to the first initialized port to test it:

Code: Select all

#define I2C_DISTRIBUTED I2C_NUM_0
#define I2C_LOCAL       I2C_NUM_1
#define TEST_DEV_ADDR 0x20

esp_err_t i2c_master_init( i2c_port_t port );
int8_t bus_checkForACK(i2c_port_t port, uint8_t dev_addr);

void test_this_it_fails()
{
    i2c_master_init(I2C_LOCAL);
    i2c_master_init(I2C_DISTRIBUTED);

    while ( bus_checkForACK(I2C_LOCAL, 0x20 ) != ESP_OK )
    {
            printf("First Transaction on First initialized bus failed! \n ");
    }
}


//****************************************************************************
int8_t bus_checkForACK(i2c_port_t port, uint8_t dev_addr)
{
    i2c_cmd_handle_t cmd_link = i2c_cmd_link_create();

    i2c_master_start(cmd_link);
    i2c_master_write_byte(cmd_link, (dev_addr << 1) | I2C_MASTER_WRITE, true);
    esp_err_t ret = i2c_master_cmd_begin(port, cmd_link, pdMS_TO_TICKS(1000));
    i2c_cmd_link_delete(cmd_link);
    return (int8_t)ret;
}

esp_err_t i2c_master_init( i2c_port_t port )
{
    i2c_config_t conf;
    if ( I2C_DISTRIBUTED )
    {
        conf.mode = I2C_MODE_MASTER;
        conf.sda_io_num = GPIO_I2C_DIST_SDA;
        conf.scl_io_num = GPIO_I2C_DIST_SCL;
        conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
        conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
        conf.master.clk_speed = I2C_START_FREQ;
    }
    else if ( I2C_LOCAL )
    {
        conf.mode = I2C_MODE_MASTER;
        conf.sda_io_num = GPIO_I2C_LOCAL_SDA;
        conf.scl_io_num = GPIO_I2C_LOCAL_SCL;
        conf.sda_pullup_en = GPIO_PULLUP_DISABLE;
        conf.scl_pullup_en = GPIO_PULLUP_DISABLE;
        conf.master.clk_speed = 1000000;
    }
    else
    {
        printf("I2C Invalid Config! \n");
        return 0xFF;
    }
    if ( i2c_param_config(port, &conf) != ESP_OK )
    {
        printf("I2C Invalid Config! \n");
        return 0xFF;
    }

    return i2c_driver_install(port, conf.mode,
                              I2C_MASTER_RX_BUF_DISABLE,
                              I2C_MASTER_TX_BUF_DISABLE, ESP_INTR_FLAG_IRAM);

}


You have an error in your code that is likely causing the issue.

Code: Select all

 if ( I2C_DISTRIBUTED )
Should be

Code: Select all

 if (port == I2C_DISTRIBUTED)
And likewise for the next conditional.

Jason

kb3523
Posts: 10
Joined: Thu Mar 08, 2018 11:32 pm

Re: I2C - Using both Ports - First Transaction fails

Postby kb3523 » Sat Mar 21, 2020 9:06 pm

Lol. This is so obvious, I dont know how I could not notice this.. :D
Maybe I should stop working for today :) Thank you, please consider thes topic closed. Is there an option to close the topic with the resolution: "Used did not have eyes to read his own code, others had.." ;)

Who is online

Users browsing this forum: cdollar, Google [Bot] and 59 guests