espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.69k stars 7.29k forks source link

SPH0645 i2s microphone issue when migrate from legacy esp-idf version (IDFGH-5453) #7192

Open konradkoperek opened 3 years ago

konradkoperek commented 3 years ago

Environment

Hello, I'm migrating code from esp-idf v3.2 to version v4.2. I'm using SPH0645 i2s microphone to read sound data. When I was migrate code to the new idf, values which comes from microphone are 0. I run prevoius version of code which base on old idf and data are properly so it isn't hardware issue. I2s init function and reading data are same in this two projects:

#define LEN_WHOLE_BUFF            4096
#define LOW_FREQUENCY             51
#define HIGH_FREQUENCY            (( LEN_WHOLE_BUFF / 2 ) - 1 )

void i2sInit()
{
    i2s_config_t i2s_config = {
       .mode = I2S_MODE_MASTER | I2S_MODE_RX,
       .sample_rate = LEN_WHOLE_BUFF,
       .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
       .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
       .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_PCM | I2S_COMM_FORMAT_I2S_LSB ),
       .dma_buf_count = 3,
       .dma_buf_len =  512,
       .use_apll = 1,
       .intr_alloc_flags = ESP_INTR_FLAG_LEVEL3
    };
    i2s_pin_config_t pin_config =
    {
       .ws_io_num =MIC_WS, //PDM clock
       .data_in_num = MIC_DATA_IN, //PDM data
       .bck_io_num = MIC_BCK,
       .data_out_num = -1,
    };
    i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM_0, &pin_config);
}

//static void i2s_mesaurement( int * buff , int nos)
//{
//  size_t val = 0;
//  i2s_read(I2S_NUM_0 , buff, sizeof( int ) * nos, &val, portMAX_DELAY);
//}

void i2s_mesaurement( void * buff , int nos)
{
    size_t val = 0;
    i2s_read(I2S_NUM_0 , buff, 4 * nos, &val, portMAX_DELAY);
}

I saw one post which suggest that SPH0645 are incompatimble with timings in new idf. Could you confirm if it is issues with drivers in new idf? It is possibility to fix it ?

seanw214 commented 3 years ago

Try to set .communication_format to I2S_COMM_FORMAT_STAND_I2S and call i2s_set_clk() after i2s_set_pin(). These changes worked for me.

PaulAnurag commented 1 year ago

Hi @seanw214

I am trying to run the example for SPH0645LM4H mic which is not a PDM Mic.

IDF Version 4.4

Can anyone help me with the configurations. I am unable to read data. The configurations that I have set are:

// Set the I2S configuration as PDM and 16bits per sample
i2s_config_t i2s_config = {
    .mode = I2S_MODE_MASTER | I2S_MODE_RX,
    .sample_rate = CONFIG_EXAMPLE_SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2,
    .dma_buf_count = 8,
    .dma_buf_len = 200,
    .use_apll = 0,
};

// Set the pinout configuration (set using menuconfig)
i2s_pin_config_t pin_config = {
    .mck_io_num = I2S_PIN_NO_CHANGE,
    .bck_io_num = CONFIG_EXAMPLE_I2S_CLK_GPIO,
    .ws_io_num = 0,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = CONFIG_EXAMPLE_I2S_DATA_GPIO,
};

// Call driver installation function before any I2S R/W operation.
ESP_ERROR_CHECK( i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL) );
ESP_ERROR_CHECK( i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config) );
ESP_ERROR_CHECK( i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, CONFIG_EXAMPLE_SAMPLE_RATE, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO) );

}

Regards Anurag Paul

seanw214 commented 1 year ago

@PaulAnurag here are my configuration settings. I hope this helps.

const i2s_config_t i2s_config_1 = { .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX, .sample_rate = 16000, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, // I2S_COMM_FORMAT_STAND_MSB <- big-endian .intr_alloc_flags = ESP_INTR_FLAG_INTRDISABLED, // ESP_INTR_FLAG_INTRDISABLED //ESP_INTR_FLAG_LEVEL1 .dma_buf_count = 8, // number of buffers .dma_buf_len = 1024 /, //64 .use_apll = false, .tx_desc_auto_clear = false/ };

i2s_pin_config_t pin_config = {
    .bck_io_num = I2S_BCK_IO,     // GPIO2
    .ws_io_num = I2S_WS_IO,       // GPIO19
    .data_out_num = I2S_DO_IO,  // GPIO5
    .data_in_num = I2S_DI_IO};     // GPIO36
PaulAnurag commented 1 year ago

@seanw214 Is there any example code that you know which I can refer?