esp-adf icon indicating copy to clipboard operation
esp-adf copied to clipboard

I2C fails with hw NACK on ES8388 while I2S stream is running (AUD-5942)

Open RaresCon opened this issue 1 year ago • 19 comments

Environment

  • Audio development kit: none - ESP32-WROOM-32D with ES8388 breakout board
  • Audio kit version (for ESP32-LyraT/ESP32-LyraT-Mini/ESP32-S3-Korvo-2): -
  • [Required] Module or chip used: ESP32-WROOM-32D
  • [Required] IDF version: 5.3.1
  • [Required] ADF version: e9f72307c73159711b33775e543df22d6e607449 (v2.7.1)
  • Build system: idf.py
  • [Required] Running log:
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:7176
load:0x40078000,len:15564
ho 0 tail 12 room 4
load:0x40080400,len:4
--- 0x40080400: _init at ??:?

load:0x40080404,len:3904
entry 0x40080640
I (31) boot: ESP-IDF c8fc5f64-dirty 2nd stage bootloader
I (31) boot: compile time Dec 24 2024 20:01:10
I (31) boot: Multicore bootloader
I (36) boot: chip revision: v3.1
I (40) boot.esp32: SPI Speed      : 40MHz
I (45) boot.esp32: SPI Mode       : DIO
I (49) boot.esp32: SPI Flash Size : 4MB
I (54) boot: Enabling RNG early entropy source...
I (59) boot: Partition Table:
I (63) boot: ## Label            Usage          Type ST Offset   Length
I (70) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (77) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (85) boot:  2 factory          factory app      00 00 00010000 00300000
I (92) boot: End of partition table
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=31d38h (204088) map
I (175) esp_image: segment 1: paddr=00041d60 vaddr=3ffbdb60 size=04ca4h ( 19620) load
I (182) esp_image: segment 2: paddr=00046a0c vaddr=40080000 size=0960ch ( 38412) load
I (198) esp_image: segment 3: paddr=00050020 vaddr=400d0020 size=bb420h (767008) map
I (461) esp_image: segment 4: paddr=0010b448 vaddr=4008960c size=11620h ( 71200) load
I (502) boot: Loaded app from partition at offset 0x10000
I (502) boot: Disabling RNG early entropy source...
I (515) cpu_start: Multicore app
I (523) cpu_start: Pro cpu start user code
I (523) cpu_start: cpu freq: 160000000 Hz
I (523) app_init: Application information:
I (526) app_init: Project name:     bt_sink_demo
I (531) app_init: App version:      94a59cc2-dirty
I (537) app_init: Compile time:     Dec 24 2024 20:43:05
I (543) app_init: ELF file SHA256:  d8acfe86e...
I (548) app_init: ESP-IDF:          c8fc5f64-dirty
I (553) efuse_init: Min chip rev:     v0.0
I (558) efuse_init: Max chip rev:     v3.99
I (563) efuse_init: Chip rev:         v3.1
I (568) heap_init: Initializing. RAM available for dynamic allocation:
I (575) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (581) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (587) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (593) heap_init: At 3FFCC628 len 000139D8 (78 KiB): DRAM
I (600) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (606) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (612) heap_init: At 4009AC2C len 000053D4 (20 KiB): IRAM
I (620) spi_flash: detected chip: generic
I (623) spi_flash: flash io: dio
I (639) coexist: coex firmware version: 4482466
I (640) main_task: Started on CPU0
I (640) main_task: Calling app_main()
I (650) BLUETOOTH_EXAMPLE: [ 1 ] Init Bluetooth
I (650) BTDM_INIT: BT controller compile version [b022216]
I (650) BTDM_INIT: Bluetooth MAC: ac:15:18:e9:25:1a
I (660) phy_init: phy_version 4830,54550f7,Jun 20 2024,14:22:08
I (1340) BLUETOOTH_EXAMPLE: [ 2 ] Start codec chip
W (1340) i2c_bus_v2: I2C master handle is NULL, will create new one
D (1350) i2c.common: new bus(0) at 0x3ffd4770
W (1350) i2c.master: Please check pull-up resistances whether be connected properly. Otherwise unexpected behavior would happen. For more detailed information, please read docs
I (1360) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
I (1370) gpio: GPIO[23]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
D (1380) i2c.common: bus clock source frequency: 80000000hz
I (1400) gpio: GPIO[0]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (1400) ES8388_DRIVER: init,out:00, in:00
I (1410) AUDIO_HAL: Codec mode is 2, Ctrl:1
I (1410) BLUETOOTH_EXAMPLE: [ 3 ] Create audio pipeline for playback
I (1420) BLUETOOTH_EXAMPLE: [4] Create i2s stream to write data to codec chip
D (1420) i2s_common: tx channel is registered on I2S0 successfully
D (1430) i2s_common: DMA malloc info: dma_desc_num = 3, dma_desc_buf_size = dma_frame_num * slot_num * data_bit_width = 1248
D (1440) i2s_std: Clock division info: [sclk] 160000000 Hz [mdiv] 14 [mclk] 11289600 Hz [bdiv] 8 [bclk] 1411200 Hz
D (1450) i2s_common: MCLK is pinned to GPIO3 on I2S0
D (1460) i2s_std: The tx channel on I2S0 has been initialized to STD mode successfully
D (1460) i2s_common: i2s tx channel enabled
E (1470) i2c.master: I2C hardware NACK detected
E (1470) i2c.master: I2C transaction unexpected nack detected
E (1480) i2c.master: s_i2c_synchronous_transaction(872): I2C transaction failed
I (1490) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
I (1500) gpio: GPIO[23]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
E (1510) i2c.master: i2c_master_transmit(1074): I2C transaction failed
E (1510) i2c.master: I2C hardware NACK detected
E (1520) i2c.master: I2C transaction unexpected nack detected
E (1520) i2c.master: s_i2c_synchronous_transaction(872): I2C transaction failed
I (1530) gpio: GPIO[22]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
I (1540) gpio: GPIO[23]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0
E (1550) i2c.master: i2c_master_transmit(1074): I2C transaction failed
I (1560) BLUETOOTH_EXAMPLE: [4.1] Get Bluetooth stream
W (1570) BT_BTC: A2DP Enable with AVRC
I (1580) A2DP_STREAM: Unhandled A2DP event: 4
W (1580) AUDIO_THREAD: Make sure selected the 'CONFIG_SPIRAM_BOOT_INIT' and 'CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY' by 'make menuconfig'
I (1590) AUDIO_THREAD: The audio_a2dp_stream_thread task allocate stack on internal memory
I (1600) BLUETOOTH_EXAMPLE: [4.2] Register all elements to audio pipeline
I (1610) BLUETOOTH_EXAMPLE: [4.3] Link it together [Bluetooth]-->bt_stream_reader-->i2s_stream_writer-->[codec_chip]
I (1620) AUDIO_PIPELINE: link el->rb, el:0x3ffd6244, tag:bt, rb:0x3ffd7060
I (1630) BLUETOOTH_EXAMPLE: [ 5 ] Initialize peripherals
I (1630) BLUETOOTH_EXAMPLE: [5.1] Create Bluetooth peripheral
I (1640) BLUETOOTH_EXAMPLE: [5.2] Start all peripherals
I (1640) AUDIO_THREAD: The esp_periph task allocate stack on internal memory
I (1650) BLUETOOTH_EXAMPLE: [ 6 ] Set up  event listener
I (1660) BLUETOOTH_EXAMPLE: [6.1] Listening event from all elements of pipeline
I (1670) BLUETOOTH_EXAMPLE: [ 7 ] Start audio_pipeline
I (1670) AUDIO_ELEMENT: [bt-0x3ffd6244] Element task created
I (1680) AUDIO_THREAD: The i2s task allocate stack on internal memory
I (1690) AUDIO_ELEMENT: [i2s-0x3ffd4e08] Element task created
I (1690) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:139732 Bytes

I (1700) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1
I (1710) AUDIO_PIPELINE: Pipeline started
I (1710) BLUETOOTH_EXAMPLE: [ 8 ] Listen for all pipeline events
  • Compiler version: 13.2.0_20240530
  • Operating system: Windows
  • (Windows only) Environment type: Plain Command Prompt
  • Using an IDE?: Yes - VS Code without IDF extension
  • Power supply: USB

Problem Description

I am trying to use the A2DP Sink example from player examples on an ESP32-WROOM-32D with ES8388 breakout board, using a custom board setup in ADF. While everything works fine without changing the volume after the I2S stream is initialized, trying to change the volume or in fact trying to send any I2C command to the codec results in a hardware NACK. Before initializing the I2S stream, everything works fine with I2C communication and configuration (the NACKs in the running log are from me trying to change the volume with audio_hal_set_volume() in app_main). I have tried multiple solutions found around the internet, like changing the I2C/I2S port or adding external pull-up resistors, but nothing seems to work. Even though the NACKs come from setting the volume, I have tried to read the codec's volume for example from its registers and this produces NACKs as well.

Expected Behavior

Being able to set/read any register with I2C commands while I2S stream is running.

Actual Behavior

Getting HW NACKs for any I2C command after the initialization of the I2S stream.

Steps to Reproduce

  1. Use ESP32-WROOM-32D with ES8388
  2. Try to change the volume after the device is connected through BT or try to change the volume in the code

ESP32-ES8388

Code to Reproduce This Issue

The code is the one from the example, the code can be found on my fork, the modifications for my setup can be found in the HEAD commit on the new-local-branch.

Debug Logs

The logs can be found in the running log section.

Other Items If Possible

  • [ * ] sdkconfig sdkconfig.zip

  • [ * ] elf file in the build folder (Note this may contain all the code details and symbols of your project.) bt_sink_demo.zip

RaresCon avatar Dec 24 '24 19:12 RaresCon

Is there any update for this issue?

RaresCon avatar Jan 27 '25 16:01 RaresCon

Hi @RaresCon Software solution reference: bugfix/improve_es8311_i2c_stability Hardware solution: Add a 33pF capacitor and a 33Ω resistor low-pass filter to the CLK and SDA lines near the I2C pins of the audio codec chip.

ALToast avatar Feb 08 '25 07:02 ALToast

Hi @RaresCon Software solution reference: bugfix/improve_es8311_i2c_stability Hardware solution: Add 33pF/33Ω filters to the CLK and SDA lines near the ES8311 I2C pin.

Hi @ALToast Thanks for your response. I am using a ES8388, is there a software solution for it as well? I am sure the registers are not the same as on ES8311. I will also try the filtering solution.

RaresCon avatar Feb 08 '25 08:02 RaresCon

Hi @RaresCon In terms of software, the ES8388 does not have registers for the I2C. Please try reducing the I2C frequency and adjusting the glitch_ignore_cnt parameter. If you have tried a hardware solution, please let me know the results. Thanks

ALToast avatar Feb 10 '25 02:02 ALToast

Hi @RaresCon In terms of software, the ES8388 does not have registers for the I2C. Please try reducing the I2C frequency and adjusting the glitch_ignore_cnt parameter. If you have tried a hardware solution, please let me know the results. Thanks

Hi @ALToast I have tried the software solution above, reducing the I2C frequency to 70K, 50K, and 30K, none has worked. I also tried increasing the glitch_ignore_cnt to 15 while using these frequencies.

Regarding the hardware possible solution, I don't have the caps and resistors yet, but I will try it next week and tell you if I have any success. I will try to write a QSPI solution to change the I2C register writing.

Is there any other way to change the volume of the I2S stream? Could there be a bug in the I2C driver?

RaresCon avatar Feb 16 '25 09:02 RaresCon

I got the same issue on ES8388 codec.

Image

Image

It will show up at start, or sometimes at the volume adjustment. It's a random problem. It basically doesn't affect the playback, but it will affect the volume adjustment. The manifestation is that when an error occurs, only one of the audio channels may have its volume adjusted.

GCTechnology avatar Feb 17 '25 15:02 GCTechnology

I got the same issue on ES8388 codec.

Image

Image

It will show up at start, or sometimes at the volume adjustment. It's a random problem. It basically doesn't affect the playback, but it will affect the volume adjustment. The manifestation is that when an error occurs, only one of the audio channels may have its volume adjusted.

Similar issue on https://github.com/espressif/esp-idf/issues/14715 and https://github.com/espressif/esp-idf/issues/14030

GCTechnology avatar Feb 17 '25 15:02 GCTechnology

Hi @GCTechnology I have conducted multiple tests using the ESP32-LyraT development board, and the issue mentioned above did not occur on this board. I would like to know if your hardware is based on the ESP32-LyraT SCH reference.

Image

ALToast avatar Feb 26 '25 12:02 ALToast

Hi @RaresCon In terms of software, the ES8388 does not have registers for the I2C. Please try reducing the I2C frequency and adjusting the glitch_ignore_cnt parameter. If you have tried a hardware solution, please let me know the results. Thanks

Hi @ALToast I have tried the software solution above, reducing the I2C frequency to 70K, 50K, and 30K, none has worked. I also tried increasing the glitch_ignore_cnt to 15 while using these frequencies.

Regarding the hardware possible solution, I don't have the caps and resistors yet, but I will try it next week and tell you if I have any success. I will try to write a QSPI solution to change the I2C register writing.

Is there any other way to change the volume of the I2S stream? Could there be a bug in the I2C driver? Hi @RaresCon

The issue is caused by the slave chip not returning the ACK signal. If you capture the I2C waveform, you will be able to observe this phenomenon. The low-pass filtering resistors on the I2C pins in the ESP32-LyraT SCH are also based on the slave chip's recommendations. You can also reduce the amplitude of audio data in the software, but it is recommended to use a codec chip to handle it.

Image

ALToast avatar Feb 27 '25 02:02 ALToast

Hi @RaresCon @GCTechnology Any progress on the issue?

ALToast avatar Mar 06 '25 08:03 ALToast

Hi @RaresCon @GCTechnology Any progress on the issue?

Hi @ALToast Unfortunetly, no, I had some other issues to resolve and I couldn't get the low value capacitors and resistors yet. I will try next week to buy them somewhere.

RaresCon avatar Mar 06 '25 09:03 RaresCon

Hi @RaresCon @GCTechnology Any progress on the issue?

So far, no solution has been found. I‘m trying to solve this problem because it was found and posted by the customer as a bug. :(

This is the hardware schematic diagram of our project.

Image

GCTechnology avatar Mar 07 '25 02:03 GCTechnology

.

Any updates to this problem?

Rck27 avatar Mar 09 '25 15:03 Rck27

I tried it using LPF and HPF, but the error still persistIMG-20250310-WA0042.jpeg

Here's some picture of the signal

Rck27 avatar Mar 10 '25 10:03 Rck27

Hi @ALToast,

I have tried to add the resistors and capacitors on the SDA/SCL lines between the slave board and the ESP-WROOM-32D and it does not solve the problem. I guess it might be because of the length of the connections between the two.

RaresCon avatar Mar 22 '25 17:03 RaresCon

Hi @ALToast,

I have tried to add the resistors and capacitors on the SDA/SCL lines between the slave board and the ESP-WROOM-32D and it does not solve the problem. I guess it might be because of the length of the connections between the two.

We also tried to add resistors to shorten the rising time of SCL to reach the limit of 300ns, it worked in my case. However, it did not completely solve the problem. It merely reduced the frequency of the occurrence of errors. Image

Then I add a retry mechanism to the codec transceiver interface to avoid this. Modify es_write_reg and es_read_reg at es8388.c.

GCTechnology avatar Mar 23 '25 03:03 GCTechnology

Hi @ALToast, I have tried to add the resistors and capacitors on the SDA/SCL lines between the slave board and the ESP-WROOM-32D and it does not solve the problem. I guess it might be because of the length of the connections between the two.

We also tried to add resistors to shorten the rising time of SCL to reach the limit of 300ns, it worked in my case. However, it did not completely solve the problem. It merely reduced the frequency of the occurrence of errors. Image

Then I add a retry mechanism to the codec transceiver interface to avoid this. Modify es_write_reg and es_read_reg at es8388.c.

So the resistor (100R) has been added inline with the signal of SCL, similar to the LyraT-4.3 schematic? Or are you referring to the pull-up 2K resistor?

RaresCon avatar Mar 24 '25 10:03 RaresCon

@ALToast, should this schematic be used instead of LyraT-4.3's? I found this in the user guide for ES8388, which states that a resistor of 330 and cap of 2200pF, paired with a pull-up of 1K should be used for SCL/SDA.

Image

RaresCon avatar Mar 24 '25 10:03 RaresCon

@ALToast, should this schematic be used instead of LyraT-4.3's? I found this in the user guide for ES8388, which states that a resistor of 330 and cap of 2200pF, paired with a pull-up of 1K should be used for SCL/SDA.应该用这个原理图代替 LyraT-4.3 的原理图吗?我在 ES8388 的用户指南中找到了答案,指南中指出 SCL/SDA 应该使用 330 欧姆的电阻和 2200pF 的电容,并搭配 1K 的上拉电阻。

Image Hi @RaresCon

For 100kHz I2C communication, both of these low-pass filter combinations are effective. Of course, you can also try this combination. Additionally, it is important to note that the low-pass filter should be placed close to the I2C pin of the Codec.

ALToast avatar Jun 19 '25 12:06 ALToast