Page 1 of 1

MAX44009 two I2C reads without a stop in between

Posted: Sat Feb 06, 2021 4:45 pm
by udragger
Hi all,
I have been trying to use MAX44009 light sensor, it stores the illumination data in two registers and the datasheet specifies that they need to be read one after another without generating a stop signal in between the two reads. Otherwise the two values may be out of sync.
I have not figured out a way how to set up the communication in ESP-IDF (on ESP32) so that no stop signal is sent between the two reads.

That is how the communication is supposed to be done:
Communication.jpg
Communication.jpg (55.44 KiB) Viewed 4970 times
This is my code that does not work:

Code: Select all

i2c_cmd_handle_t cmd1 = i2c_cmd_link_create();
i2c_master_start(cmd1);
i2c_master_write_byte(cmd1, (MAX44009_ADDRESS << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd1, 0x03, ACK_CHECK_EN);
i2c_master_start(cmd1);
i2c_master_write_byte(cmd1, (MAX44009_ADDRESS << 1) | I2C_MASTER_READ, ACK_CHECK_EN);
i2c_master_read_byte(cmd1, register3, NACK_VAL);

//i2c_master_stop(cmd1); //if I uncomment this, the code works, but the two registers may not be synchronized

esp_err_t ret1 = i2c_master_cmd_begin(i2c_num, cmd1, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd1);

i2c_cmd_handle_t cmd2 = i2c_cmd_link_create();
i2c_master_start(cmd2);
i2c_master_write_byte(cmd2, (MAX44009_ADDRESS << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd2, 0x04, ACK_CHECK_EN);
i2c_master_start(cmd2);
i2c_master_write_byte(cmd2, (MAX44009_ADDRESS << 1) | I2C_MASTER_READ, ACK_CHECK_EN);
i2c_master_read_byte(cmd2, register4, NACK_VAL);

i2c_master_stop(cmd2);

esp_err_t ret2 = i2c_master_cmd_begin(i2c_num, cmd2, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd2);
I have hooked up a logic analyzer and I can see that it does not clock the ACK or NAK after the first read and times out there:
Logic analyzer.jpg
Logic analyzer.jpg (65.23 KiB) Viewed 4970 times
The second read is never started. If I add a stop signal between the two reads, everything works, but there is a risk that the two values may be out of sync with each other.

Is it possible to do this type of communication on an ESP32?

Re: MAX44009 two I2C reads without a stop in between

Posted: Sun Feb 07, 2021 4:07 am
by boarchuz
The IDF I2C example has a function showing how to set up a standard multi-byte read like this:
https://github.com/espressif/esp-idf/bl ... .c#L62-L78

Re: MAX44009 two I2C reads without a stop in between

Posted: Sun Feb 07, 2021 10:01 am
by udragger
Thank you, but a multi byte read from a single register is not what I need. I need two single byte reads from two registers without a stop signal in between.
MAX44009 IC will not autoincrement the register if I read several bytes in a row.

Re: MAX44009 two I2C reads without a stop in between

Posted: Sun Feb 07, 2021 5:57 pm
by boarchuz

Code: Select all

static esp_err_t read_max44009(i2c_port_t i2c_num, uint8_t *byte_low, uint8_t* byte_high)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (MAX44009_ADDRESS << 1) | I2C_MASTER_WRITE, 1);
    i2c_master_write_byte(cmd, 0x03, 1);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (MAX44009_ADDRESS << 1) | I2C_MASTER_READ, 1);
    i2c_master_read_byte(cmd, byte_low, I2C_MASTER_NACK);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (MAX44009_ADDRESS << 1) | I2C_MASTER_WRITE, 1);
    i2c_master_write_byte(cmd, 0x04, 1);
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (MAX44009_ADDRESS << 1) | I2C_MASTER_READ, 1);
    i2c_master_read_byte(cmd, byte_high, I2C_MASTER_NACK);
    i2c_master_stop(cmd);
    // should check return values ^
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

Re: MAX44009 two I2C reads without a stop in between

Posted: Mon Feb 08, 2021 11:01 am
by udragger
This was the first thing that I tried. It does not work and times out similarly to using two command links. Logic analyzer shows that it gets stuck after reading the first byte.

Re: MAX44009 two I2C reads without a stop in between

Posted: Thu May 20, 2021 6:00 pm
by danvica
Hi,
did you find a solution ? Thanks

Re: MAX44009 two I2C reads without a stop in between

Posted: Fri May 21, 2021 9:42 pm
by udragger
I did not, it looks like a bug/limitation in IDF or hardware. I am using two separate reads as a workaround for the time being.