First, a bit of context:
- Using ESP32S3-WROOM module, programming in VSCode using Platformio with ESP-IDF last stable version 5.4.
- The I2C bus has 3 different sensors attach to it: LIS3DH accelerometer (0x19), OPT3004 ambient light sensor (0x44) and GP8211S 0-10v digital to analog converter (0x58).
- It's a custom pcb design, with a 12VDC power supply, a lithium-polymer battery charger, and a LDO that regulates battery voltage to 3,3V.
My issue is that the GP8211S DAC IC is not responding to I2C commands, so I tried to use the i2c_master_probe() function to scan, in case I mistaken the address of the device. However when I call this function, nothing comes out via the SDA pin nor the SCL pin.
Here is the code I made for this:
Code: Select all
#include "gp8211s.h"
#include "esp_log.h"
#include "driver/i2c_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#define TAG "GP8211S"
gp8211s_t *GP8211S_PARAMS = nullptr;
static const uint8_t GP8211S_I2C_ADDR = 0x58; // I2C Address GP8211S
i2c_master_dev_handle_t gp8211s_i2c_dev_handle;
#define GP8211S_REG_CONFIG 0x01
#define GP8211S_REG_DAC 0x02
/**
* @brief Initialize the DAC GP8211S I2C device
*
*/
gp8211s_status_t gp8211s_i2c_init_device(void);
/**
* @brief Converts a percentage (0-100) to a 16-bit register value for the GP8211S DAC
*
* @param percentage percentage value to convert (0-100)
* @return uint16_t 16-bit register value corresponding to the percentage
*/
uint16_t gp8211s_convert_percentage(uint8_t percentage);
gp8211s_status_t gp8211s_init(gp8211s_t *gp8211s_params)
{
//ESP_LOGI(TAG, "%s - Initializing DAC GP8211S", __func__);
if (gp8211s_params == NULL)
{
ESP_LOGE(TAG, "%s - Null parameters", __func__);
return GP8211S_ERR;
}
GP8211S_PARAMS = gp8211s_params;
//Initialize I2C
if (gp8211s_i2c_init_device() != GP8211S_OK)
{
ESP_LOGE(TAG, "%s - Error initializing I2C device", __func__);
return GP8211S_ERR;
}
// write config register for 0-10v output
uint8_t config[2];
config[0] = GP8211S_REG_CONFIG; // config register address
config[1] = 0x77; // 0-10v output mode
esp_err_t err = i2c_master_transmit(gp8211s_i2c_dev_handle, config, sizeof(config), 1000);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "%s - Error writing to device: %s", __func__, esp_err_to_name(err));
return GP8211S_ERR;
}
ESP_LOGI(TAG, "%s - DAC GP8211S initialized", __func__);
return GP8211S_OK;
}
gp8211s_status_t gp8211s_change_percentage(uint8_t percentage)
{
if (GP8211S_PARAMS == NULL)
{
ESP_LOGE(TAG, "%s - Null parameters", __func__);
return GP8211S_ERR;
}
// write config register for 0-10v output
uint8_t config[2];
config[0] = GP8211S_REG_CONFIG; // config register address
config[1] = 0x77; // 0-10v output mode
esp_err_t err = i2c_master_transmit(gp8211s_i2c_dev_handle, config, sizeof(config), 1000);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "%s - Error writing to device: %s", __func__, esp_err_to_name(err));
return GP8211S_ERR;
}
// calculate register value from percentage
uint16_t reg_val = gp8211s_convert_percentage(percentage);
ESP_LOGI(TAG, "%s - Percentage: %d - Register value: %04X", __func__, percentage, reg_val);
// write register value to DAC
if (reg_val > 0x7FFF) reg_val = 0x7FFF;
uint8_t data[3];
data[0] = GP8211S_REG_DAC; // DAC value register address
data[1] = reg_val & 0xFF; // LSB
data[2] = (reg_val >> 8) & 0x7F; // MSB (only 7 bits used)
err = i2c_master_transmit(gp8211s_i2c_dev_handle, data, sizeof(data), 1000);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "%s - Error writing to device: %s", __func__, esp_err_to_name(err));
return GP8211S_ERR;
}
return GP8211S_OK;
}
gp8211s_status_t gp8211s_i2c_init_device(void)
{
if (GP8211S_PARAMS == NULL)
{
ESP_LOGE(TAG, "%s - Null parameters", __func__);
return GP8211S_ERR;
}
i2c_device_config_t dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = GP8211S_I2C_ADDR,
.scl_speed_hz = 100000,
.scl_wait_us = 0,
.flags = 0,
};
// Test - probe I2C addresses
ESP_LOGI(TAG, "%s - Probing I2C addresses...", __func__);
uint8_t addr_check = 0;
esp_err_t err;
while (addr_check < 0xff)
{
err = i2c_master_probe((i2c_master_bus_handle_t)GP8211S_PARAMS->i2c_master_bus_handle, addr_check, 1000);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "%s - Error probing I2C address 0x%02X: %s", __func__, addr_check, esp_err_to_name(err));
}
else
{
ESP_LOGI(TAG, "%s - I2C device found in address: 0x%02X", __func__, addr_check);
}
addr_check++;
}
err = i2c_master_bus_add_device((i2c_master_bus_handle_t)GP8211S_PARAMS->i2c_master_bus_handle, &dev_cfg, &gp8211s_i2c_dev_handle);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "%s - Error adding I2C device to the bus: %s", __func__, esp_err_to_name(err));
return GP8211S_ERR;
}
return GP8211S_OK;
}
uint16_t gp8211s_convert_percentage(uint8_t percentage)
{
// scale 0-100 is 0x0000-0x7ffff
if (percentage > 100) percentage = 100; // limit to 100%
uint16_t reg_val = (uint16_t)((percentage * 0x7FFF) / 100); // convert value to register value
return reg_val;
}
Code: Select all
void main_crear_handle_i2c_master(void)
{
// Create I2C master handle
i2c_master_bus_config_t i2c_master_config = {
.i2c_port = 1,
.sda_io_num = (gpio_num_t)PIN_I2C_SDA,
.scl_io_num = (gpio_num_t)PIN_I2C_SCL,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.intr_priority = 1,
.trans_queue_depth = 10,
.flags = {
.enable_internal_pullup = 1,
.allow_pd = 0}};
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_master_config, &i2c_master_handle));
if (i2c_master_handle == NULL)
{
ESP_LOGE(TAG, "Error creating I2C master handle");
}
}Here is an image of the schematic of these ICs connections:

The voltage in the SDA and SCL pins is ok in standby, measured with multimeter.
I have a logic analyzer to debug the I2C lines, here is the attempt to communicate with the GP8211S IC (address 0x58) before adding the i2c_master_probe code:

After this unsuccessful attempsts to communicate with the GP8211S IC, I added the i2c_master_probe function in order to test the I2C bus, the result was that no data came out from the I2C lines in the logic analyzer, and this data shows in the firmware logs:
Code: Select all
I (7908) GP8211S: gp8211s_i2c_init_device - Probing I2C addresses...
E (8918) i2c.master: I2C software timeout
E (8918) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (8918) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x00: ESP_ERR_TIMEOUT
E (9928) i2c.master: I2C software timeout
E (9928) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (9928) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x01: ESP_ERR_TIMEOUT
E (10938) i2c.master: I2C software timeout
E (10938) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (10938) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x02: ESP_ERR_TIMEOUT
E (11948) i2c.master: I2C software timeout
E (11948) i2c.master: probe device timeout. Please check if xfer_timeout_ms and pull-ups are correctly set up
E (11948) GP8211S: gp8211s_i2c_init_device - Error probing I2C address 0x03: ESP_ERR_TIMEOUTI know I must miss something, I've search the forum and the documentation, but I can't seem to find answer to these issues. I'll appreciate any input that could help me solved this.
