esp-idf: I2S mic not working since 4.4 (IDFGH-8138)

Answers checklist.

  • I have updated my IDF branch (master or release) to the latest version and checked that the issue is present there.
  • I have read the documentation ESP-IDF Programming Guide and the issue is not addressed there.
  • I have searched the issue tracker for a similar issue and not found a similar issue.

IDF version.

v4.4

Operating System used.

macOS

How did you build your project?

VS Code IDE

If you are using Windows, please specify command line type.

No response

Development Kit.

ESP32 Dev Module

Power Supply used.

USB

What is the expected behavior?

Using this sketch: https://github.com/atomic14/esp32-i2s-mic-test/blob/main/i2s_mic_test/i2s_mic_test.ino With a INMP441 configured as follow: WS -> 25 SCK -> 32 SD -> 33 L/R -> GND GND -> GND VDD -> 3.3V

It should output values of the sound received by the mic.

What is the actual behavior?

Only 0 values

Steps to reproduce.

I originally submitted an issue here: https://github.com/espressif/arduino-esp32/issues/7177 But I was redirected to esp-idf since it appears to be related to it.

A brief summary:

In platformio.ini, this does NOT work because it is using the latest release of arduino-esp32

platform = espressif32

By changing it to this, it works as intended

platform = espressif32@5.0.0

Later we discovered this commit in arduino-esp32 repo is where it stops to work normally

platform = espressif32
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#666c66d3d1c7437aaebaaadf2084927b7fc476c4

Debug Logs.

No response

More Information.

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 21

Commits related to this issue

Most upvoted comments

The bug was found, the rx_chan_mod on v4.4 is set to opposite value comparing to v5.0 and v5.1 image

Details

Concretely, the rx_chan_mod is actually related to msdb_right bit, meanwhile msdb_right is depended on the bits_per_sample. The correct relations are (ESP32 mono mode specific):

┌──────────────────┬─────────────┬───────────────┬──────────────────┐
│ bits_per_sample  │  msb_right  │  rx_chan_mod  │  sample_channel  │
├──────────────────┼─────────────┼───────────────┼──────────────────┤
│       16         │      1      │       1       │    only_right    │
├──────────────────┼─────────────┼───────────────┼──────────────────┤
│       16         │      1      │       2       │    only_left     │
├──────────────────┼─────────────┼───────────────┼──────────────────┤
│       32         │      0      │       2       │    only_right    │
├──────────────────┼─────────────┼───────────────┼──────────────────┤
│       32         │      0      │       1       │    only_left     │
└──────────────────┴─────────────┴───────────────┴──────────────────┘

The bug is that rx_chan_mod on v4.4 didn’t take msb_right into consideration, so that the left channel and the right channel are exchanged.

Solution

The bug will be fixed in the next minor version, for now, you can try the following way to get a temporary fix.

Workaround

  • You can set to the opposite channel when using 32 bit-width data.

  • Or, force to update the register after i2s install:

    #include "hal/i2s_hal.h"
    // ...
    i2s_driver_install();
    // ...
    i2s_ll_rx_set_chan_mod(&I2S0, 1);  // 32-bit only left
    

Fix patch

You can also try the patch:

0001-i2s-fixed-incorrect-channel-format-on-ESP32.patch

@L-KAYA Are there any updates on this? As stated the workaround is rather simple but it would be ideal to have this fixed. Anything else we can test?

It’s indeed a bug before, that only_left is actually only_right meanwhile only_right is still only_right, but it has been fixed on release/4.4 about 3 weeks ago.

Have you checked which channel your mic actually sampling (i.e. left when L/R pin of INMP441 is pulled down and right when it is pulled up)?

Thanks for raising this, I am having the same issue - also with Tasmota image: It seems to have stopped between 4.4.0 and 4.4.3

Working: platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.3/platform-espressif32-2.0.2.3.zip framework-espidf @ 3.40400.0 (4.4.0)

Not workingt: platform = https://github.com/tasmota/platform-espressif32 framework-espidf @ 3.40403.0 (4.4.3)

I am using the following I2S Config: ` i2s_config_t i2s_config_micro = { .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX), .sample_rate = 16000,

        //  The data word size is set at 32 bits and "I2S_PHILIPS_MODE" format. So a single stereo frame consists of two 32-bit PCM words or 8 bytes.
        //  The actual PCM audio data is 24 bits wide, is signed and is stored in little-endian format with 8 bits of left-justified 0 "padding".
        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,

        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // was I2S_CHANNEL_FMT_RIGHT_LEFT
        .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S),
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 4,
        .dma_buf_len = 1024,
        .use_apll = false,
        .tx_desc_auto_clear = false,
        .fixed_mclk = 0
};`