Using i2c bus for SMBUS (Smart Battery Fuel Gauge)

greenlava
Posts: 1
Joined: Wed Jun 08, 2022 7:38 pm

Using i2c bus for SMBUS (Smart Battery Fuel Gauge)

Postby greenlava » Wed Sep 14, 2022 4:05 pm

Hi There:

I'm trying to interface an SMBUS Battery Fuel gauge by TI (BQ40Z50-R2) using the i2c peripheral on an ESP32-S3 module. I have successfully sent and received commands to the part using an i2c cmd that looks like the following:

Code: Select all

        i2c_cmd_handle_t cmd = i2c_cmd_link_create();
        i2c_master_start(cmd);
        i2c_master_write_byte(cmd, addr << 1 | WRITE_BIT, ACK_CHECK);
        i2c_master_write_byte(cmd, command, ACK_CHECK);
        i2c_master_write_byte(cmd, len, ACK_CHECK);
        for (size_t i = 0; i < len-1; ++i)
        {
            i2c_master_write_byte(cmd, data[i], ACK_CHECK);
        }
        i2c_master_write_byte(cmd, data[len-1], false);
        i2c_master_stop(cmd);
        i2c_master_cmd_begin(masterNum, cmd, masterTimeout);

        i2c_cmd_link_delete(cmd);
In this code, I'm sending Start bit, Address|Write, an internal command (0x44), number of bytes to send (2), then the function I want to query (0x0006), followed by a stop bit. This communications sets up the BQ40Z50-R2 to return the value of the function requested.

The next step is to read back the data from the function. The expectation is:

Start Bit, Address | Write, Command, RESEND START, Address|Read, now the slave returns to me an arbitrary number of bytes, with the first byte being an expected byte count. I would then set up the correct number of i2c_master_read_byte() commands based on the byte count the slave informed me of.

Here is a code snippet:

Code: Select all

        i2c_cmd_handle_t cmd = i2c_cmd_link_create();
        i2c_master_start(cmd);
        i2c_master_write_byte(cmd, addr << 1 | WRITE_BIT, ACK_CHECK);
        i2c_master_write_byte(cmd, command, ACK_CHECK);
        i2c_master_start(cmd);
        i2c_master_write_byte(cmd, addr << 1 | READ_BIT, ACK_CHECK);
        uint8_t slave_len = 0;
        i2c_master_read_byte(cmd, &slave_len, I2C_MASTER_ACK);

        err =  i2c_master_cmd_begin(masterNum, cmd, masterTimeout);

        i2c_cmd_link_delete(cmd);
        printf("incoming bytes: %d\n", slave_len);
        cmd = i2c_cmd_link_create();

        for (size_t i = 0; i < slave_len - 1; ++i)
        {
            i2c_master_read_byte(cmd, &data[i], I2C_MASTER_ACK);
        }
        i2c_master_read_byte(cmd, &data[slave_len - 1], I2C_MASTER_NACK);
        i2c_master_stop(cmd);
        err = i2c_master_cmd_begin(masterNum, cmd, masterTimeout);
        i2c_cmd_link_delete(cmd);
The problem exists when I send my first i2c_master_cmd_begin() when the cmd packet doesn't include a stop bit, I hold time until my watchdog reset kicks in. Is there a way I can configure the i2c peripheral so that I can send a cmd packet without a stop bit? That way I can dynamically place the correct number of reads into my cmd packet?

Thanks for the help
Dan

EDP-IDF version ESP-IDF v4.4.1-dirty

rwbrwb
Posts: 1
Joined: Tue Apr 18, 2023 10:38 pm

Re: Using i2c bus for SMBUS (Smart Battery Fuel Gauge)

Postby rwbrwb » Tue Apr 18, 2023 10:39 pm

I'm trying to do the same thing.

Did you ever get this figured out so it works with the BQ40z50 correctly?

Who is online

Users browsing this forum: Bing [Bot] and 124 guests