MAX44009 two I2C reads without a stop in between

udragger
Posts: 4
Joined: Sat Feb 06, 2021 4:29 pm

MAX44009 two I2C reads without a stop in between

Postby udragger » Sat Feb 06, 2021 4:45 pm

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 4874 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 4874 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?

boarchuz
Posts: 604
Joined: Tue Aug 21, 2018 5:28 am

Re: MAX44009 two I2C reads without a stop in between

Postby boarchuz » Sun Feb 07, 2021 4:07 am

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

udragger
Posts: 4
Joined: Sat Feb 06, 2021 4:29 pm

Re: MAX44009 two I2C reads without a stop in between

Postby udragger » Sun Feb 07, 2021 10:01 am

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.

boarchuz
Posts: 604
Joined: Tue Aug 21, 2018 5:28 am

Re: MAX44009 two I2C reads without a stop in between

Postby boarchuz » Sun Feb 07, 2021 5:57 pm

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;
}

udragger
Posts: 4
Joined: Sat Feb 06, 2021 4:29 pm

Re: MAX44009 two I2C reads without a stop in between

Postby udragger » Mon Feb 08, 2021 11:01 am

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.

danvica
Posts: 6
Joined: Fri Apr 09, 2021 3:18 am

Re: MAX44009 two I2C reads without a stop in between

Postby danvica » Thu May 20, 2021 6:00 pm

Hi,
did you find a solution ? Thanks

udragger
Posts: 4
Joined: Sat Feb 06, 2021 4:29 pm

Re: MAX44009 two I2C reads without a stop in between

Postby udragger » Fri May 21, 2021 9:42 pm

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.

Who is online

Users browsing this forum: No registered users and 70 guests