Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I2S mic not working since 4.4 (IDFGH-8138) #9635

Closed
3 tasks done
MikeBailleul opened this issue Aug 25, 2022 · 21 comments
Closed
3 tasks done

I2S mic not working since 4.4 (IDFGH-8138) #9635

MikeBailleul opened this issue Aug 25, 2022 · 21 comments
Assignees
Labels
Awaiting Response awaiting a response from the author Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF

Comments

@MikeBailleul
Copy link

MikeBailleul commented Aug 25, 2022

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: espressif/arduino-esp32#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

@MikeBailleul MikeBailleul added the Type: Bug bugs in IDF label Aug 25, 2022
@MikeBailleul MikeBailleul changed the title I2S mic not working with 4.4 I2S mic not working since 4.4 Aug 25, 2022
@espressif-bot espressif-bot added the Status: Opened Issue is new label Aug 25, 2022
@github-actions github-actions bot changed the title I2S mic not working since 4.4 I2S mic not working since 4.4 (IDFGH-8138) Aug 25, 2022
@happychriss
Copy link

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
};`

@L-KAYA
Copy link
Collaborator

L-KAYA commented Aug 29, 2022

I've tried on the latest release/v4.4 branch, it works well now, this bug(only_lefthas no sound) should has already been fixed in commit 56a89b920dcf47c7c1d34cbd00ff745ffd7b3246.

@espressif-bot espressif-bot added the Awaiting Response awaiting a response from the author label Aug 29, 2022
@MikeBailleul
Copy link
Author

MikeBailleul commented Aug 30, 2022

How do I test for a specific commit of the IDF?
Is this the right way in platform.ini?

platform = espressif32
platform_packages = framework-espidf @ https://github.com/espressif/esp-idf.git#56a89b920dcf47c7c1d34cbd00ff745ffd7b3246

If yes, it does not work for me. I receive only NaN values from the mic.

@L-KAYA
Copy link
Collaborator

L-KAYA commented Aug 30, 2022

Maybe you can try release/v4.4 branch directly instead of a specific commit, hope it can work

platform_packages = framework-espidf @ https://github.com/espressif/esp-idf/tree/release/v4.4

@MikeBailleul
Copy link
Author

MikeBailleul commented Aug 30, 2022

I believe you meant this?

platform_packages = framework-espidf @ https://github.com/espressif/esp-idf.git#release/v4.4

because your suggestion was not building.

And, still no luck: NaN values.

@L-KAYA
Copy link
Collaborator

L-KAYA commented Aug 31, 2022

I ran that example directly on IDF release/v4.4 and modified slightly to make it build:

#include <stdio.h>
#include "driver/i2s.h"

// you shouldn't need to change these settings
#define SAMPLE_BUFFER_SIZE 512
#define SAMPLE_RATE 8000
// most microphones will probably default to left channel but you may need to tie the L/R pin low
#define I2S_MIC_CHANNEL I2S_CHANNEL_FMT_ONLY_LEFT
// either wire your microphone to the same pins or change these to match your wiring
#define I2S_MIC_SERIAL_CLOCK GPIO_NUM_32
#define I2S_MIC_LEFT_RIGHT_CLOCK GPIO_NUM_25
#define I2S_MIC_SERIAL_DATA GPIO_NUM_33

// don't mess around with this
i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_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
};

// and don't mess around with this
i2s_pin_config_t i2s_mic_pins = {
    .bck_io_num = I2S_MIC_SERIAL_CLOCK,
    .ws_io_num = I2S_MIC_LEFT_RIGHT_CLOCK,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = I2S_MIC_SERIAL_DATA
};

void setup(void)
{
    // start up the I2S peripheral
    i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM_0, &i2s_mic_pins);
}

int32_t raw_samples[SAMPLE_BUFFER_SIZE] = {0};

void loop(void)
{
    // read from the I2S device
    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, raw_samples, sizeof(int32_t) * SAMPLE_BUFFER_SIZE, &bytes_read, portMAX_DELAY);
    int samples_read = bytes_read / sizeof(int32_t);
    // dump the samples out to the serial channel.
    for (int i = 0; i < samples_read; i++) {
        printf("%d ", raw_samples[i]);
    }
    printf("\n");
}

void app_main(void)
{
    setup();
    while (1) {
        loop();
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

The code ran as expected for me, maybe you can take a try as well. If it works, we can just waiting for the release of v4.4.3

@MikeBailleul
Copy link
Author

I tried your sample code, it does not work with my INMP441 mic.

@L-KAYA
Copy link
Collaborator

L-KAYA commented Sep 1, 2022

Have you tried to use I2S_CHANNEL_FMT_RIGHT_LEFT or I2S_CHANNEL_FMT_ONLY_RIGHT

@MikeBailleul
Copy link
Author

Interesting, I2S_CHANNEL_FMT_ONLY_RIGHT worked! I2S_CHANNEL_FMT_RIGHT_LEFT did not.
Why is that tough?

@L-KAYA
Copy link
Collaborator

L-KAYA commented Sep 2, 2022

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)?

@MikeBailleul
Copy link
Author

Got it, but if it has been fixed on release/4.4, then why did I still had the bug when I tried this release a few comments earlier in this thread?

Not too sure about which channel is it using, I tried to pull L/R up and down and switch between only_left/only_right but I do not see any difference.

@L-KAYA
Copy link
Collaborator

L-KAYA commented Sep 2, 2022

Weird, have you updated to the latest release/v4.4? Anyway, I'll take an another try next week.

@MikeBailleul
Copy link
Author

Yes like so:

platform = espressif32
platform_packages = framework-espidf @ https://github.com/espressif/esp-idf.git#release/v4.4

And it does not work. I mean, it works only if I use I2S_CHANNEL_FMT_ONLY_RIGHT which is fine by me anyway, I just wanted to raise the issue.

@Jason2866
Copy link

@MikeBailleul You can try

platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.1/platform-espressif32-2.0.5.1.zip

i use a very actual IDF commit. The mentioned commit is there.

@gpantazis
Copy link

So I can confirm that on tag v4.4.4 I am still having this issue. I am 90% certain that I was NOT seeing this issue in tag 4.4.1 but can't guarantee it (and switching right now is not that simple).

Specifically:
Using an ESP-EYE (esp32 based) I am unable to read the mic using I2S_CHANNEL_FMT_ONLY_LEFT but can successfully read it using I2S_CHANNEL_FMT_ONLY_RIGHT. According to the ESP-EYE schematic pin 5 (L/R) of the microphone (MSM261S4030H0) is tied to ground, which should mean, only the left channel should be producing any output.

Separately I have a custom board with an ESP32 connected to an I2S ADC programmed to only output on the left channel. This also does not work on tag v4.4.4 but did work on old firmware compiled with tag v4.4.1. Curiously though it works when I use I2S_CHANNEL_FMT_ONLY_RIGHT. It seems that somewhere the meaning of these two was switched or mangled?

I can temporarily use the wrong channel_format but that seems strange.

@gpantazis
Copy link

@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?

@khseal
Copy link

khseal commented Mar 18, 2023

I had the same issue. Thank you for the hint.

@L-KAYA
Copy link
Collaborator

L-KAYA commented Mar 20, 2023

Appologize for the late reply!

I'll take further test this week, if there is any workaround or patch, I'll post here for preview

@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development and removed Status: Opened Issue is new labels Mar 20, 2023
@L-KAYA
Copy link
Collaborator

L-KAYA commented Mar 21, 2023

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

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Selected for Development Issue is selected for development labels Mar 21, 2023
@gpantazis
Copy link

@L-KAYA Thank you for tracking down the fix! I will await v4.4.5 (v4.5?) for our project as the using the opposite channel is simple enough currently.

@espressif-bot espressif-bot added Status: Reviewing Issue is being reviewed and removed Status: In Progress Work is in progress labels Mar 31, 2023
espressif-bot pushed a commit that referenced this issue Apr 8, 2023
@espressif-bot espressif-bot added Status: Done Issue is done internally Resolution: NA Issue resolution is unavailable and removed Status: Reviewing Issue is being reviewed labels May 15, 2023
@L-KAYA
Copy link
Collaborator

L-KAYA commented Jun 20, 2023

FYI, the fix has already released in v4.4.5 (commit d337d9dc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Response awaiting a response from the author Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Type: Bug bugs in IDF
Projects
None yet
Development

No branches or pull requests

8 participants