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);
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);
Thanks for the help
Dan
EDP-IDF version ESP-IDF v4.4.1-dirty