Skip to content

Not compatible with new i2c driver #126

@Orfait

Description

@Orfait

When using esp-idf 5.4, if your project already use I2C with the new driver, you will run into error at runtime (the project compiles fine).

Reading the m5gfx code helped me to understand that only i2c_set_pin() is called.

As a very dirty fix, as added this code at the top of src/lgfx/platforms:esp32/common.cpp, just before namespace lgfx, then replaced the 3 calls of i2c_set_pin() with m5gfx_i2c_set_pin().

////////////////////////////////////////////////////////////////////////////////////////////
#include "esp_check.h"
static const char *I2C_TAG = "i2c";
#define I2C_NUM_ERROR_STR              "i2c number error"
#define I2C_SDA_IO_ERR_STR             "sda gpio number error"
#define I2C_SCL_IO_ERR_STR             "scl gpio number error"
#define I2C_GPIO_PULLUP_ERR_STR        "this i2c pin does not support internal pull-up"
#define I2C_SCL_SDA_EQUAL_ERR_STR      "scl and sda gpio numbers are the same"
#define I2C_IO_INIT_LEVEL              (1)

esp_err_t m5gfx_i2c_set_pin(i2c_port_t i2c_num, int sda_io_num, int scl_io_num, bool sda_pullup_en, bool scl_pullup_en, i2c_mode_t mode)
{
    ESP_RETURN_ON_FALSE(( i2c_num < I2C_NUM_MAX ), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
    ESP_RETURN_ON_FALSE(((sda_io_num < 0) || ((GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)))), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SDA_IO_ERR_STR);
    ESP_RETURN_ON_FALSE(scl_io_num < 0 ||
#if SOC_I2C_SUPPORT_SLAVE
              (GPIO_IS_VALID_GPIO(scl_io_num) && mode == I2C_MODE_SLAVE) ||
#endif // SOC_I2C_SUPPORT_SLAVE
              (GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)),
              ESP_ERR_INVALID_ARG, I2C_TAG,
              I2C_SCL_IO_ERR_STR);
    ESP_RETURN_ON_FALSE(sda_io_num < 0 ||
              (sda_pullup_en == GPIO_PULLUP_ENABLE && GPIO_IS_VALID_OUTPUT_GPIO(sda_io_num)) ||
              sda_pullup_en == GPIO_PULLUP_DISABLE, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_GPIO_PULLUP_ERR_STR);
    ESP_RETURN_ON_FALSE(scl_io_num < 0 ||
              (scl_pullup_en == GPIO_PULLUP_ENABLE && GPIO_IS_VALID_OUTPUT_GPIO(scl_io_num)) ||
              scl_pullup_en == GPIO_PULLUP_DISABLE, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_GPIO_PULLUP_ERR_STR);
    ESP_RETURN_ON_FALSE((sda_io_num != scl_io_num), ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SCL_SDA_EQUAL_ERR_STR);

    int sda_in_sig, sda_out_sig, scl_in_sig, scl_out_sig;
    sda_out_sig = i2c_periph_signal[i2c_num].sda_out_sig;
    sda_in_sig = i2c_periph_signal[i2c_num].sda_in_sig;
    scl_out_sig = i2c_periph_signal[i2c_num].scl_out_sig;
    scl_in_sig = i2c_periph_signal[i2c_num].scl_in_sig;
    if (sda_io_num >= 0) {
        gpio_set_level((gpio_num_t)sda_io_num, I2C_IO_INIT_LEVEL);
        gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[sda_io_num], PIN_FUNC_GPIO);
        gpio_set_direction((gpio_num_t)sda_io_num, GPIO_MODE_INPUT_OUTPUT_OD);

        if (sda_pullup_en == GPIO_PULLUP_ENABLE) {
            gpio_set_pull_mode((gpio_num_t)sda_io_num, GPIO_PULLUP_ONLY);
        } else {
            gpio_set_pull_mode((gpio_num_t)sda_io_num, GPIO_FLOATING);
        }
        esp_rom_gpio_connect_out_signal(sda_io_num, sda_out_sig, 0, 0);
        esp_rom_gpio_connect_in_signal(sda_io_num, sda_in_sig, 0);
    }
    if (scl_io_num >= 0) {
        if (mode == I2C_MODE_MASTER) {
            gpio_set_level((gpio_num_t)scl_io_num, I2C_IO_INIT_LEVEL);
            gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[scl_io_num], PIN_FUNC_GPIO);
            gpio_set_direction((gpio_num_t)scl_io_num, GPIO_MODE_INPUT_OUTPUT_OD);
            esp_rom_gpio_connect_out_signal(scl_io_num, scl_out_sig, 0, 0);
        } else {
            gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[scl_io_num], PIN_FUNC_GPIO);
            gpio_set_direction((gpio_num_t)scl_io_num, GPIO_MODE_INPUT);
        }
        esp_rom_gpio_connect_in_signal(scl_io_num, scl_in_sig, 0);
        if (scl_pullup_en == GPIO_PULLUP_ENABLE) {
            gpio_set_pull_mode((gpio_num_t)scl_io_num, GPIO_PULLUP_ONLY);
        } else {
            gpio_set_pull_mode((gpio_num_t)scl_io_num, GPIO_FLOATING);
        }
    }
#if !SOC_I2C_SUPPORT_HW_CLR_BUS
    i2c_context[i2c_num].scl_io_num = scl_io_num;
    i2c_context[i2c_num].sda_io_num = sda_io_num;
#endif
    return ESP_OK;
}
////////////////////////////////////////////////////////////////////////////////////////////

It seems to be working, but I am conviced that this is not the right way to do...
I am only posting this issue to point out the need to manage the new I2C driver (or not using it anymore) and to help those how are in the same case as me.

Have a good day :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions