espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
12.97k stars 7.11k forks source link

I2C not working in 'Release' configuration #304

Closed holzachr closed 7 years ago

holzachr commented 7 years ago

When building in Debug configuration, I2C communication is working. When building in Release configuration, communication gets stuck before it really starts.

This is what the bus looks like at the first communication after reset (Debug config): i2c debug working - zoomed out

This is what the bus looks like at the first communication try after reset (Release config): i2c release failing - zoomed out

Close look at where data is supposed to start: i2c release failing - zoomed in 1

In error case, i2c_master_cmd_begin() does not return (with time set to portMAX_DELAY) or returns ESP_ERRTIMEOUT for any smaller value for ticks.

This is my initialialization. First I reconfigure GPIO32 + 33 for general use: i2c_config_t stI2cConfig; REG_CLR_BIT(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL); REG_CLR_BIT(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL); stI2cConfig.mode = I2C_MODE_MASTER; stI2cConfig.sda_io_num = GPIO_NUM_33; stI2cConfig.sda_pullup_en = GPIO_PULLUP_ENABLE; stI2cConfig.scl_io_num = GPIO_NUM_32; stI2cConfig.scl_pullup_en = GPIO_PULLUP_ENABLE; stI2cConfig.master.clk_speed = 400000; i2c_param_config(I2C_NUM_0, &stI2cConfig); i2c_set_data_mode(I2C_NUM_0, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST); i2c_driver_install(I2C_NUM_0, stI2cConfig.mode, 0, 0, 0);

This is how I access the bus: // I2C access: write register, then read value // Read register 1: W[0x68] [0x01] R[0x68] [0x00 = Value] i2c_cmd_handle_t i2cHandle = i2c_cmd_link_create(); i2c_master_start(i2cHandle); i2c_master_write_byte(i2cHandle, (I2C_ADDRESS << 1), true); i2c_master_write_byte(i2cHandle, (uint8_t)enRegister, true); i2c_master_write_byte(i2cHandle, (I2C_ADDRESS << 1) | 0x01, true); i2c_master_read_byte(i2cHandle, pu8Value, 1); esp_err_t result = i2c_master_cmd_begin(I2C_NUM_0, i2cHandle, portMAX_DELAY); i2c_cmd_link_delete(i2cHandle); return (result == ESP_OK);

I tried to stick with the I2C example as much as possible.

Any hints or reproduction are very welcome - thanks.

holzachr commented 7 years ago

I took time to try the esp-idf/examples/peripherals/i2c example, which behaves the same.

I don't have an actual BH1750 sensor, so I set up the example as suggested in the README.md file (by connecting the ESP32's master & slave ports GPIO18<-->GPIO25 and GPIO19<-->GPIO26), and started a run in "debug" configuration, which looks good. Then I set menuconfig to "release", make clean && make -j8 flash, and the master I2C peripheral is struggeling. I tried this procedure with two separate ESP-WROOM-32 modules each on a Watterott ESP-WROOM-32-BREAKOUT board.

i2c_example_debug.txt i2c_example_release.txt

mludvig commented 7 years ago

I just spent a good part of the day trying to make an I2C LCD display work and only now found this bug report. Recompiling in DEBUG mode indeed helped and my display now works as expected.

Using esp-idf git b8e2edc99f36 and gcc-5.2.0 [xtensa-esp32-elf-gcc (crosstool-NG crosstool-ng-1.22.0-59-g8d95cad) 5.2.0] compiling on ARM [Raspbian GNU/Linux 8 (jessie)]

costaud commented 7 years ago

I will take this issue : )

bobik78 commented 7 years ago

Did you configure the Debug/Release option through menuconfig?

holzachr commented 7 years ago

Right, configure through menuconfig.

bobik78 commented 7 years ago

I am trying to work with I2C EEPROM (FM24C64) and I can confirm that RELEASE configuration doesn't work at all and I2C bus is stuck on the beginning of any activity. But, also DEBUG configuration not works so good and after some I2C activity I start getting ERR_TIMEOUT errors from i2c_master_cmd_begin command . Do you have any idea how to solve this for now?

emtantra commented 7 years ago

@bobik78 im also with same issue (i2c matster EEPROM Selective (Random) Read problem #422)

bobik78 commented 7 years ago

Thanks Santhosh!

On Wed, Mar 15, 2017 at 10:27 PM, santhosh kumar notifications@github.com wrote:

@bobik78 https://github.com/bobik78 im also with same issue (i2c matster EEPROM Selective (Random) Read problem #422 https://github.com/espressif/esp-idf/issues/422)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espressif/esp-idf/issues/304#issuecomment-286714700, or mute the thread https://github.com/notifications/unsubscribe-auth/AM1DCtTxWLYtgt2L5ILJw_nCfOJGuG3Yks5rl8s3gaJpZM4Luxsl .

-- Kind Regards, Firmware Engineer LIFX

emtantra commented 7 years ago

we should thank to @nkolban for that.

costaud commented 7 years ago

I think this one can fix the issue. Try to merge into idk ASAP.

driver/i2c.c

static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)
{
       ......
        if (cmd->op_code == I2C_CMD_WRITE) {
            uint32_t wr_filled = 0;
            //TODO: to reduce interrupt number
            if (cmd->data) {
                while (p_i2c->tx_fifo_remain > 0 && cmd->byte_num > 0) {
                    WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), *cmd->data++);
                    p_i2c->tx_fifo_remain--;
                    cmd->byte_num--;
                    wr_filled++;
                }
            } else {
                WRITE_PERI_REG(I2C_DATA_APB_REG(i2c_num), cmd->byte_cmd);
                p_i2c->tx_fifo_remain--;
                cmd->byte_num--;
                wr_filled ++;
            }
            //Workaround for register field operation.
            I2C[i2c_num]->command[p_i2c->cmd_idx].byte_num = wr_filled;
            .......
holzachr commented 7 years ago

Works fine for me - thanks everyone!