espressif / esp-idf

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

The problem of using two i2s interfaces at the same time in esp32s3 (IDFGH-7255) #8844

Open Kingwulin opened 2 years ago

Kingwulin commented 2 years ago

I want to use two i2s port,one as rx and another as tx But it is found that the two can work normally when they are separated, but the crash occurs when they are put together.

below is code:

void init_microphone(void)
{
    // Set the I2S configuration as PDM and 16bits per sample
    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_RX ,
        .sample_rate = 32000,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = I2S_COMM_FORMAT_STAND_I2S,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2,
        .dma_buf_count = 2,
        .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 = 12,
        .ws_io_num = 13,
        .data_out_num = I2S_PIN_NO_CHANGE,
        .data_in_num = 14,
    };

    // Call driver installation function before any I2S R/W operation.
    ESP_ERROR_CHECK( i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL) );

    ESP_ERROR_CHECK( i2s_set_pin(I2S_NUM_0, &pin_config) );

    ESP_ERROR_CHECK( i2s_set_clk(I2S_NUM_0, 32000, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO) );

}

#define I2S_SAMPLE_RATE     (16000)
#define SAMPLE_BITS     (16)

#define MASTER_WS_IO 36
#define MASTER_BCK_IO 37
#define DATA_OUT_IO 38
#define DATA_IN_IO 39
void hal_i2s_speaker_init(void)
{
    esp_err_t err;
    // master driver installed and send data
    i2s_config_t master_i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_TX ,
        .sample_rate = I2S_SAMPLE_RATE,
        .bits_per_sample = SAMPLE_BITS,
        .channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT,
        .communication_format = I2S_COMM_FORMAT_STAND_I2S,
        .dma_buf_count = 2,
        .dma_buf_len = 200,
        .use_apll = 0,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 ,
    };
    i2s_pin_config_t master_pin_config = {
        .mck_io_num = I2S_PIN_NO_CHANGE,
        .bck_io_num = MASTER_BCK_IO,
        .ws_io_num = MASTER_WS_IO,
        .data_out_num = DATA_OUT_IO,
        .data_in_num = I2S_PIN_NO_CHANGE
    };  

    err = i2s_driver_install(I2S_NUM_1, &master_i2s_config, 0, NULL);
    ESP_LOGI(TAG,"i2s_driver_install status %d",err);
    err = i2s_set_pin(I2S_NUM_1, &master_pin_config);
    ESP_LOGI(TAG,"i2s_set_pin status %d",err);
    i2s_set_clk(I2S_NUM_1, I2S_SAMPLE_RATE, (i2s_bits_per_sample_t)16, (i2s_channel_t)1);
}
L-KAYA commented 2 years ago

Hi @Kingwulin , Thanks for the report. Could you provide more descriptions of how they put together? Do you mean allocate both tx and rx channel on a same port meanwhile adopt different configurations? For the current driver, the tx and rx channels on ESP32 and ESP32S2 shares some register, so they are only allowed to using same configuration on a same port or different configurations on different ports. But yes, the tx and rx channel on ESP32C3 and ESP32S3 are separate, they support using different configurations on a same port, however, due to the limitation of the legacy driver, this is not supported for now, but will support while IDF v5.0 release. A brand new I2S driver will come out at that time.