espressif / esp-adf

Espressif Audio Development Framework
Other
1.55k stars 687 forks source link

es8388 i2c address 0x20 or 0x10? (AUD-3789) #809

Closed jw-redpanda closed 2 years ago

jw-redpanda commented 2 years ago

I am confused about the i2c address used by es8388.

From the official diagram pdf here of ESP32-LyraT-v4.3, es8388 i2c slave address is 0x20. This 0x20 is also seen in esp-adf es8388.h

However, from the es8388 original chip vendor es8388 DS pdf here, it says the chip address as below: It is a seven-bit chip address followed by a RW bit. The chip address must be 001000x, where x equals AD0. In that case, the i2c address is either 0x10 or 0x11 (AD0 is 0 or 1 respectively)

When running the audio pipeline samples, I dumped the ES8388_ADDR, it is indeed 0x20.

I am developing a custom audio board, which uses es8388 and other i2c devices. One of these i2c devices uses 0x20 address. If I follow the official spec (0x10), it has no conflict of address. However, if Lyra-T is correct, the conflict exists.

Can anyone help clarify my confusion? Many thanks.

jw-redpanda commented 2 years ago

I answer my question below.

ES8388_ADDR 0x20 is a bit mis-leading as it is in fact a 7-bit address + 0 (W bit), i.e. 0x10 + 0 = 0x20

esp_err_t i2c_bus_read_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg, int reglen, uint8_t *outdata, int datalen)
{
    I2C_BUS_CHECK(bus != NULL, "Handle error", ESP_FAIL);
    i2c_bus_t *p_bus = (i2c_bus_t *) bus;
    I2C_BUS_CHECK(p_bus->i2c_port < I2C_NUM_MAX, "I2C port error", ESP_FAIL);
    I2C_BUS_CHECK(outdata != NULL, "Not initialized output data buffer pointer", ESP_FAIL);
    esp_err_t ret = ESP_OK;
    mutex_lock(_busLock);
    i2c_cmd_handle_t cmd;
    cmd = i2c_cmd_link_create();
    ret |= i2c_master_start(cmd);
    ret |= i2c_master_write_byte(cmd, addr, I2C_ACK_CHECK_EN);
    ret |= i2c_master_write(cmd, reg, reglen, I2C_ACK_CHECK_EN);
    ret |= i2c_master_stop(cmd);
    ret |= i2c_master_cmd_begin(p_bus->i2c_port, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    cmd = i2c_cmd_link_create();
    ret |= i2c_master_start(cmd);
    // it changes the addr value, 7-bit address + 0 (W bit) to 7bit address + 1 (R bit)
    ret |= i2c_master_write_byte(cmd, addr | 0x01, I2C_ACK_CHECK_EN);

    for (int i = 0; i < datalen - 1; i++) {
        ret |= i2c_master_read_byte(cmd, &outdata[i], 0);
    }
    ret |= i2c_master_read_byte(cmd, &outdata[datalen - 1], 1);

    ret = i2c_master_stop(cmd);
    ret = i2c_master_cmd_begin(p_bus->i2c_port, cmd, 1000 / portTICK_RATE_MS);
    i2c_cmd_link_delete(cmd);

    mutex_unlock(_busLock);
    I2C_BUS_CHECK(ret == 0, "I2C Bus ReadReg Error", ESP_FAIL);
    return ret;
}

Thus, es8388 uses 0x10 actually (when CE pin is low)