项目背景
使用ESP32单片机开发,运用IDF5.1.3的环境和ADF的框架,开发一个智能音响。使用的开发板为乐鑫原厂开发板,型号为ESP32-korvo v1.1 。
具体过程是通过ES7210录音,然后由ES8311播放音频,ES7210和ES8311是经过iic进行读写寄存器配置音频录音和播放的。
然后现在的问题是在编译的过程中,日志一直报I2C Bus WriteReg Error和I2C Bus ReadReg Error。
日志报错如下:
I (1525) I2C_BUS: Start: 0
I (1525) I2C_BUS: Write byte: 0
I (1535) I2C_BUS: Write reg: 0
I (1535) I2C_BUS: Write reg: 0
I (1545) I2C_BUS: Stop: 0
I (2545) I2C_BUS: Cmd begin: 263
iic写入寄存器//bus === 0, addr === 0x18, reg === 68, data ==== 8, datalen ==== 1
E (2545) I2C_BUS: G:/Espressif/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:122 (i2c_bus_write_bytes):I2C Bus WriteReg Error
I (2555) I2C_BUS: Start: 0
I (2565) I2C_BUS: Write byte: 0
I (2565) I2C_BUS: Write reg: 0
I (2565) I2C_BUS: Write reg: 0
I (2575) I2C_BUS: Stop: 0
I (3575) I2C_BUS: Cmd begin: 263
iic写入寄存器//bus === 0, addr === 0x18, reg === 68, data ==== 8, datalen ==== 1
E (3575) I2C_BUS: G:/Espressif/esp-adf/components/esp_peripherals/driver/i2c_bus/i2c_bus.c:122 (i2c_bus_write_bytes):I2C Bus WriteReg Error
查询代码的错误位置在ESP-ADF中的i2c_bus.c文件中
代码如下:
esp_err_t i2c_bus_write_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg, int regLen, uint8_t *data, 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(data != NULL, "Not initialized input data pointer", ESP_FAIL);
esp_err_t ret = ESP_OK;
mutex_lock(p_bus->bus_lock);
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ret |= i2c_master_start(cmd);
ESP_LOGI(TAG, "Start: %d\n", ret);
ret |= i2c_master_write_byte(cmd, addr, 1);
ESP_LOGI(TAG, "Write byte: %d\n", ret);
ret |= i2c_master_write(cmd, reg, regLen, I2C_ACK_CHECK_EN);
ESP_LOGI(TAG, "Write reg: %d\n", ret);
ret |= i2c_master_write(cmd, data, datalen, I2C_ACK_CHECK_EN);
ESP_LOGI(TAG, "Write reg: %d\n", ret);
ret |= i2c_master_stop(cmd);
ESP_LOGI(TAG, "Stop: %d\n", ret);
ret |= i2c_master_cmd_begin(p_bus->i2c_port, cmd, 1000 / portTICK_RATE_MS);
ESP_LOGI(TAG, "Cmd begin: %d\n", ret);
i2c_cmd_link_delete(cmd);
mutex_unlock(p_bus->bus_lock);
printf("iic写入寄存器//bus === %d, addr === 0x%02x, reg === %d, data ==== %d, datalen ==== %d\n",p_bus->i2c_port, addr, reg[0], data[0], datalen);
I2C_BUS_CHECK(ret == 0, "I2C Bus WriteReg Error", ESP_FAIL);
return ret;
}
esp_err_t i2c_bus_read_bytes(i2c_bus_handle_t bus, int addr, uint8_t *reg, int reglen, uint8_t *outdata, int datalen)
{
printf("调用i2c_bus_read_bytes\n");
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(p_bus->bus_lock);
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);
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, 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(p_bus->bus_lock);
printf("iic读取寄存器//bus = %d, addr = 0x%02x, reg = %d, data = %d, datalen = %d\n",p_bus->i2c_port, addr, reg[0], outdata[0], datalen);
I2C_BUS_CHECK(ret == 0, "I2C Bus ReadReg Error", ESP_FAIL);
return ret;
}
调用上面代码的地方在es7210和es8311初始化的地方,代码如下
esp_err_t es7210_adc_init(audio_hal_codec_config_t *codec_cfg)
{
printf("初始化ES7210...es7210_adc_init");
esp_err_t ret = ESP_OK;
i2c_init();
ret |= es7210_write_reg(ES7210_RESET_REG00, 0xff);
ret |= es7210_write_reg(ES7210_RESET_REG00, 0x41);
ret |= es7210_write_reg(ES7210_CLOCK_OFF_REG01, 0x3f);
ret |= es7210_write_reg(ES7210_TIME_CONTROL0_REG09, 0x30); /* Set chip state cycle */
ret |= es7210_write_reg(ES7210_TIME_CONTROL1_REG0A, 0x30); /* Set power on state cycle */
ret |= es7210_write_reg(ES7210_ADC12_HPF2_REG23, 0x2a); /* Quick setup */
ret |= es7210_write_reg(ES7210_ADC12_HPF1_REG22, 0x0a);
ret |= es7210_write_reg(ES7210_ADC34_HPF2_REG20, 0x0a);
ret |= es7210_write_reg(ES7210_ADC34_HPF1_REG21, 0x2a);
/* Set master/slave audio interface */
audio_hal_codec_i2s_iface_t *i2s_cfg = &(codec_cfg->i2s_iface);
switch (i2s_cfg->mode) {
case AUDIO_HAL_MODE_MASTER: /* MASTER MODE */
ESP_LOGI(TAG, "ES7210 in Master mode");
ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x01);
/* Select clock source for internal mclk */
switch (get_es7210_mclk_src()) {
case FROM_PAD_PIN:
ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x00);
break;
case FROM_CLOCK_DOUBLE_PIN:
ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x80);
break;
default:
ret |= es7210_update_reg_bit(ES7210_MASTER_CLK_REG03, 0x80, 0x00);
break;
}
break;
case AUDIO_HAL_MODE_SLAVE: /* SLAVE MODE */
ESP_LOGI(TAG, "ES7210 in Slave mode");
ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x00);
break;
default:
ret |= es7210_update_reg_bit(ES7210_MODE_CONFIG_REG08, 0x01, 0x00);
}
ret |= es7210_write_reg(ES7210_ANALOG_REG40, 0x43); /* Select power off analog, vdda = 3.3V, close vx20ff, VMID select 5KΩ start */
ret |= es7210_write_reg(ES7210_MIC12_BIAS_REG41, 0x70); /* Select 2.87v */
ret |= es7210_write_reg(ES7210_MIC34_BIAS_REG42, 0x70); /* Select 2.87v */
ret |= es7210_write_reg(ES7210_OSR_REG07, 0x20);
ret |= es7210_write_reg(ES7210_MAINCLK_REG02, 0xc1); /* Set the frequency division coefficient and use dll except clock doubler, and need to set 0xc1 to clear the state */
ret |= es7210_config_sample(i2s_cfg->samples);
ret |= es7210_mic_select(ES7210_MIC_SELECT);
ret |= es7210_adc_set_gain(ES7210_MIC_SELECT, GAIN_24DB);
return ESP_OK;
}
esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg)
{
uint8_t datmp, regv;
int coeff;
esp_err_t ret = ESP_OK;
i2c_init(); // ESP32 in master mode
printf("==========================es8311_codec_init\n");
/* Enhance ES8311 I2C noise immunity */
ret |= es8311_write_reg(ES8311_GPIO_REG44, 0x08);
printf("ret=%d\n",ret);
/* Due to occasional failures during the first I2C write with the ES8311 chip, a second write is performed to ensure reliability */
ret |= es8311_write_reg(ES8311_GPIO_REG44, 0x08);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x30);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, 0x00);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, 0x10);
printf("555ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_ADC_REG16, 0x24);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, 0x10);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, 0x00);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_SYSTEM_REG0B, 0x00);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_SYSTEM_REG0C, 0x00);
printf("101010ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_SYSTEM_REG10, 0x1F);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_SYSTEM_REG11, 0x7F);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_RESET_REG00, 0x80);
printf("ret=%d\n",ret);
/*
* Set Codec into Master or Slave mode
*/
regv = es8311_read_reg(ES8311_RESET_REG00);
/*
* Set master/slave audio interface
*/
audio_hal_codec_i2s_iface_t *i2s_cfg = &(codec_cfg->i2s_iface);
switch (i2s_cfg->mode) {
case AUDIO_HAL_MODE_MASTER: /* MASTER MODE */
ESP_LOGI(TAG, "ES8311 in Master mode");
regv |= 0x40;
break;
case AUDIO_HAL_MODE_SLAVE: /* SLAVE MODE */
ESP_LOGI(TAG, "ES8311 in Slave mode");
regv &= 0xBF;
break;
default:
regv &= 0xBF;
}
ret |= es8311_write_reg(ES8311_RESET_REG00, regv);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, 0x3F);
printf("151515ret=%d\n",ret);
/*
* Select clock source for internal mclk
*/
switch (get_es8311_mclk_src()) {
case FROM_MCLK_PIN:
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
regv &= 0x7F;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
printf("ret=%d\n",ret);
break;
case FROM_SCLK_PIN:
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
regv |= 0x80;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
printf("ret=%d\n",ret);
break;
default:
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
regv &= 0x7F;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
printf("ret=%d\n",ret);
break;
}
int sample_fre = 0;
int mclk_fre = 0;
switch (i2s_cfg->samples) {
case AUDIO_HAL_08K_SAMPLES:
sample_fre = 8000;
break;
case AUDIO_HAL_11K_SAMPLES:
sample_fre = 11025;
break;
case AUDIO_HAL_16K_SAMPLES:
sample_fre = 16000;
break;
case AUDIO_HAL_22K_SAMPLES:
sample_fre = 22050;
break;
case AUDIO_HAL_24K_SAMPLES:
sample_fre = 24000;
break;
case AUDIO_HAL_32K_SAMPLES:
sample_fre = 32000;
break;
case AUDIO_HAL_44K_SAMPLES:
sample_fre = 44100;
break;
case AUDIO_HAL_48K_SAMPLES:
sample_fre = 48000;
break;
default:
ESP_LOGE(TAG, "Unable to configure sample rate %dHz", sample_fre);
break;
}
mclk_fre = sample_fre * MCLK_DIV_FRE;
coeff = get_coeff(mclk_fre, sample_fre);
if (coeff < 0) {
ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_fre, mclk_fre);
return ESP_FAIL;
}
/*
* Set clock parammeters
*/
if (coeff >= 0) {
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG02) & 0x07;
regv |= (coeff_div[coeff].pre_div - 1) << 5;
datmp = 0;
switch (coeff_div[coeff].pre_multi) {
case 1:
datmp = 0;
break;
case 2:
datmp = 1;
break;
case 4:
datmp = 2;
break;
case 8:
datmp = 3;
break;
default:
break;
}
if (get_es8311_mclk_src() == FROM_SCLK_PIN) {
datmp = 3; /* DIG_MCLK = LRCK * 256 = BCLK * 8 */
}
regv |= (datmp) << 3;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG02, regv);
printf("ret=%d\n",ret);
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG05) & 0x00;
regv |= (coeff_div[coeff].adc_div - 1) << 4;
regv |= (coeff_div[coeff].dac_div - 1) << 0;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG05, regv);
printf("202020ret=%d\n",ret);
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG03) & 0x80;
regv |= coeff_div[coeff].fs_mode << 6;
regv |= coeff_div[coeff].adc_osr << 0;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG03, regv);
printf("ret=%d\n",ret);
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG04) & 0x80;
regv |= coeff_div[coeff].dac_osr << 0;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG04, regv);
printf("ret=%d\n",ret);
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG07) & 0xC0;
regv |= coeff_div[coeff].lrck_h << 0;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG07, regv);
printf("ret=%d\n",ret);
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG08) & 0x00;
regv |= coeff_div[coeff].lrck_l << 0;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG08, regv);
printf("ret=%d\n",ret);
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06) & 0xE0;
if (coeff_div[coeff].bclk_div < 19) {
regv |= (coeff_div[coeff].bclk_div - 1) << 0;
} else {
regv |= (coeff_div[coeff].bclk_div) << 0;
}
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
printf("252525ret=%d\n",ret);
}
/*
* mclk inverted or not
*/
if (INVERT_MCLK) {
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
regv |= 0x40;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
printf("ret=%d\n",ret);
} else {
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG01);
regv &= ~(0x40);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG01, regv);
printf("ret=%d\n",ret);
}
/*
* sclk inverted or not
*/
if (INVERT_SCLK) {
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06);
regv |= 0x20;
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
printf("ret=%d\n",ret);
} else {
regv = es8311_read_reg(ES8311_CLK_MANAGER_REG06);
regv &= ~(0x20);
ret |= es8311_write_reg(ES8311_CLK_MANAGER_REG06, regv);
printf("ret=%d\n",ret);
}
ret |= es8311_write_reg(ES8311_SYSTEM_REG13, 0x10);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_ADC_REG1B, 0x0A);
printf("ret=%d\n",ret);
ret |= es8311_write_reg(ES8311_ADC_REG1C, 0x6A);
printf("323232ret=%d\n",ret);
AUDIO_RET_ON_FALSE(TAG, ret, return ret, "es8311 initialize failed");
/* pa power gpio init */
gpio_config_t io_conf;
memset(&io_conf, 0, sizeof(io_conf));
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = BIT64(get_pa_enable_gpio());
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
/* enable pa power */
es8311_pa_power(true);
codec_dac_volume_config_t vol_cfg = ES8311_DAC_VOL_CFG_DEFAULT();
dac_vol_handle = audio_codec_volume_init(&vol_cfg);
return ESP_OK;
}
所以请教各位大佬,具体是什么原因,导致IIC读写设备寄存器失败?
ESP32开发中,使用ADF环境,系统报错I2C Bus WriteReg Error和I2C Bus ReadReg Error
Who is online
Users browsing this forum: Bytespider and 1 guest