Porting Arduino I2C method to ESP32?
Posted: Sun Apr 09, 2017 7:48 pm
Hi,
I'm working with a custom PCB that has a TCA9548 I2C multiplexer. From one of my previous boards were I used a Teensy and Arduino to control the TCA9548, I've used this method to change the channel:
Now, I'm trying to port this code over to ESP32. I've got I2C configured, and when I just query for the existence of the device I get a successful ACK back.
This is the code I'm using to replace the above Arduino code:
I believe I can read data from the IC (at least it doesn't fail) using this code. This is for reading the same data that was written using the tca9548_set_channel(int) method.
The problem is that the tca9548_get_channel() method always returns 0. So either the tca9548_set_channel() method isn't doing what it should, or the tca9548_get_channel isn't working properly, or both.
Can you see anything obvious I'm doing wrong here?
I'm working with a custom PCB that has a TCA9548 I2C multiplexer. From one of my previous boards were I used a Teensy and Arduino to control the TCA9548, I've used this method to change the channel:
Code: Select all
void setActiveSensor(uint8_t i)
{
if (i > 7) return;
Wire.beginTransmission(TCA_ADDRESS);
Wire.write(1 << i);
Wire.endTransmission();
activeSensor = i;
}
This is the code I'm using to replace the above Arduino code:
Code: Select all
esp_err_t tca9548_set_channel(int channel)
{
//Contact the TCA9548. Does it respond with an ACK?
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (TCA_ADDRESS << 1)| I2C_MASTER_WRITE, ACK_CHECK_ON));
//i2c_master_write_byte(cmd, (1 << channel) | I2C_MASTER_WRITE, 1 /* expect ack */);
ESP_ERROR_CHECK(i2c_master_stop(cmd));
//Send the I2C command
esp_err_t result = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
if (result == ESP_OK)
{
printf("[OK] Found TCA9548!\n");
//The TCA9548 responded
uint8_t data[1];
//Write to the register to set the active channel.
cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (TCA_ADDRESS << 1) | I2C_MASTER_WRITE, ACK_CHECK_ON));
ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (channel << 1), ACK));
ESP_ERROR_CHECK(i2c_master_stop(cmd));
result = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return result;
}
else
{
//ESP_ERROR_CHECK(result);
printf("[ERROR] [TCA9548] I2C ERROR: %d\n", result);
return -1;
}
}
Code: Select all
uint8_t tca9548_get_channel()
{
//Contact the TCA9548. Does it respond with an ACK?
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (TCA_ADDRESS << 1)| I2C_MASTER_WRITE, ACK_CHECK_ON));
//i2c_master_write_byte(cmd, (1 << channel) | I2C_MASTER_WRITE, 1 /* expect ack */);
ESP_ERROR_CHECK(i2c_master_stop(cmd));
//Send the I2C command
esp_err_t result = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
if (result == ESP_OK)
{
uint8_t data[1];
//Read the active channel from the IC
cmd = i2c_cmd_link_create();
ESP_ERROR_CHECK(i2c_master_start(cmd));
ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (TCA_ADDRESS << 1) | I2C_MASTER_READ, ACK_CHECK_ON));
ESP_ERROR_CHECK(i2c_master_read_byte(cmd, data, ACK));
ESP_ERROR_CHECK(i2c_master_stop(cmd));
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_PERIOD_MS));
i2c_cmd_link_delete(cmd);
return data;
}
else
{
//ESP_ERROR_CHECK(result);
printf("[ERROR] [TCA9548] I2C ERROR: %d\n", result);
return -1;
}
Can you see anything obvious I'm doing wrong here?