Some invalid I2C register reads

error404
Posts: 12
Joined: Thu May 12, 2022 8:54 am

Some invalid I2C register reads

Postby error404 » Thu Aug 31, 2023 6:05 am

ESP32 Wrover-E
IDF 4.4
ADF 2.4

Hi,
I'm currently facing some problems when reading registers from an IC via I2C.
I'm getting like hundres of correct reads, but at some point I get an incorrect one.

I've watched the I2C lines with an oscilloscope and the data looks fine, so the problem happens internally.
SCR01.PNG
SCR01.PNG (32.14 KiB) Viewed 2835 times
This is 78 (0x4E) as expected, but in the code I get 163 (0xA3). The picture shows exactly that register read, that returns an invalid value.


My code to read registers (This functions returns no errors, but a wrong reading at some point):

Code: Select all

esp_err_t i2c_ex_masterReadSlaveReg(i2c_port_t i2c_num, uint8_t i2c_addr, uint8_t i2c_reg, uint8_t *data_rd, size_t size)
{
	return i2c_master_write_read_device(i2c_num, i2c_addr, &i2c_reg, 1, data_rd, size, (1000 / portTICK_RATE_MS));
}
I also tested another one with the same result:

Code: Select all

esp_err_t i2c_ex_masterReadSlaveReg(i2c_port_t i2c_num, uint8_t i2c_addr, uint8_t i2c_reg, uint8_t *data_rd, size_t size)
{
    if (size == 0)
    {
        return ESP_OK;
    }
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (i2c_addr << 1), I2C_EX_ACK_CHECK_EN);
    i2c_master_write_byte(cmd, i2c_reg, I2C_EX_ACK_CHECK_EN);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (i2c_addr << 1) | I2C_MASTER_READ, I2C_EX_ACK_CHECK_EN);
    if (size > 1)
    {
        i2c_master_read(cmd, data_rd, size - 1, I2C_MASTER_ACK);
    }
    i2c_master_read_byte(cmd, data_rd + size - 1, I2C_MASTER_NACK);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, I2C_EX_TICKS_TO_WAIT);
    i2c_cmd_link_delete(cmd);
    return ret;
}

I think it is an internal timing issue. It is only happening when A2DP sink (https://github.com/espressif/esp-adf/bl ... _example.c) is active and music is playing (via bluetooth). Only when playing music. If bluetooth and A2DP are enabled without playing music from the connected device, everything is fine.

I'm reading the register every 100ms and after like 5-20min I'm getting one incorrect reading.

I'n every case I've watched, the wrong reading was 163 (0xA3). The datasheet of the IC says, that the 7bit (MSB) always reads 0.
Normally I expect values like 80(0x50) or 78(0x4E). Something below 128 (0x80).

There are 10k pullup resistors on SDA and SCL. Internal pullups disabled.

I2C config:

Code: Select all

.mode = I2C_MODE_MASTER,
.sda_io_num = IIM42652_SDA_GPIO,
.sda_pullup_en = GPIO_PULLUP_DISABLE,
.scl_io_num = IIM42652_SCL_GPIO,
.scl_pullup_en = GPIO_PULLUP_DISABLE,
.master.clk_speed = 100000	
I don't know what to do in that case. Maybe something with task priorities? Does I2C have a priority?

Thank you!

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Some invalid I2C register reads

Postby MicroController » Thu Aug 31, 2023 11:34 am

error404 wrote:
Thu Aug 31, 2023 6:05 am
There are 10k pullup resistors on SDA and SCL. Internal pullups disabled.
May want to play with those; enable internal pullups or change to e.g. 5k.
I don't know what to do in that case. Maybe something with task priorities? Does I2C have a priority?
No, as the I2C master, the ESP provides SCL. If, for whatever reason, there would be some delay on the ESP side, it would, worst-case, briefly stop SCL but not corrupt any data.


0xA3 happens to be (0x51<<1)+1, which may be a hint that the first bit (MSB) gets missed. In theory, this could happen through a glitch (iterference) on the SCL line, but why would that happen on exactly the same bit each time?
Another possibility is that there's a problem/glitch during the preceding write so that the read returns data from the wrong register.

And, of course, there's always the possibility that some code corrupts a byte in RAM used while transferring data from the I2C controller to application code.

ESP_Sprite
Posts: 9739
Joined: Thu Nov 26, 2015 4:08 am

Re: Some invalid I2C register reads

Postby ESP_Sprite » Fri Sep 01, 2023 1:56 am

MicroController wrote:
Thu Aug 31, 2023 11:34 am
error404 wrote:
Thu Aug 31, 2023 6:05 am
There are 10k pullup resistors on SDA and SCL. Internal pullups disabled.
May want to play with those; enable internal pullups or change to e.g. 5k.
Agree with this, 10K is generally too high for I2C communication. Note that internal pullups won't really do much here; they're generally around 50K so they won't make much difference.

error404
Posts: 12
Joined: Thu May 12, 2022 8:54 am

Re: Some invalid I2C register reads

Postby error404 » Fri Sep 01, 2023 7:09 am

MicroController wrote: May want to play with those; enable internal pullups or change to e.g. 5k.
I did try 1k and 4k7, but that did not make any difference. The error persisted.
But I'll use 4k7 from now on, thank you for the info!

MicroController wrote: 0xA3 happens to be (0x51<<1)+1, which may be a hint that the first bit (MSB) gets missed. In theory, this could happen through a glitch (iterference) on the SCL line, but why would that happen on exactly the same bit each time?
I'm with you on that one, but in the mean time I saw different cases with different register values and there is no easy correlation I can see (no shifting or bits missing/changed). The "invalid" reading isn't always 0xA3, it depends on the register value. But for every register value the "invalid" reading is the same all the time.

MicroController wrote: Another possibility is that there's a problem/glitch during the preceding write so that the read returns data from the wrong register.
The picture from the oscilloscope above is actually exactly the one reading that gets misinterpreted. So the external IC isn't sending a value from another register. And the signal itself is also fine. But maybe I misunderstood what you mean.

MicroController wrote: And, of course, there's always the possibility that some code corrupts a byte in RAM used while transferring data from the I2C controller to application code.
Yes, that's still a possibility, but very hard to find. I'll investigate.

ESP_Sprite wrote: Agree with this, 10K is generally too high for I2C communication. Note that internal pullups won't really do much here; they're generally around 50K so they won't make much difference.
Thanks for your input! I changed them to 4k7.


UPDATE: I'm getting rid of the problem by changing the master clock from 100kHz to 10kHz.

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Some invalid I2C register reads

Postby MicroController » Fri Sep 01, 2023 9:02 am

error404 wrote:
Fri Sep 01, 2023 7:09 am
UPDATE: I'm getting rid of the problem by changing the master clock from 100kHz to 10kHz.
You may want to experiment with I2C data timing.

Who is online

Users browsing this forum: forrest, Google [Bot] and 97 guests