espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.69k stars 7.42k forks source link

Problems while running i2s and i2c at the same time. #4686

Closed ameerhazo closed 3 years ago

ameerhazo commented 3 years ago

Environment

Problem Description

Using I2S together with I2C (Wire library) is causing bus busy errors and I2C sensor measurements to not make sense.

Expected Behavior

I2S and I2C working together in parallel in different cores (tested in pure IDF project and everything works as it should be).

Actual Behavior

see problem description.

Steps to reproduce

  1. install I2S driver and use Wire.begin() in setup().

Code to reproduce this issue

/*
 *  I2S Port initiate
*/

const i2s_port_t I2S_PORT = I2S_NUM_0;

/*
 * Payload Messages and variables
 */

const int BLOCK_SIZE = 128;

void setupSPH0645(void)
{

    esp_err_t err;

    Serial.println("Configuring I2S...");
    //ESP_LOGI(TAG, "Configuring I2S...");
    // The I2S config as per the example
    const i2s_config_t i2s_config = {
        .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
        .sample_rate = 44100,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
        .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
        .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 8,
        .dma_buf_len = BLOCK_SIZE
    };

    // The pin config as per the setup
    const i2s_pin_config_t pin_config = {
        .bck_io_num = 26,
        .ws_io_num = 25,
        //.bck_io_num = 14,
        //.ws_io_num = 12,
        .data_out_num = I2S_PIN_NO_CHANGE,
        .data_in_num = 33
        //.data_in_num = 26
    };

    err = i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);

    if (err != ESP_OK)
    {
        //ESP_LOGE(TAG, "Failed installing driver: %d\n", err);    
        Serial.printf("Failed installing driver: %d\n", err);
        while(true);
    }

    err = i2s_set_pin(I2S_PORT, &pin_config);

    if(err != ESP_OK)
    {
        //ESP_LOGE(TAG, "Failed setting pin: %d\n", err);
        Serial.printf("Failed setting pin: %d\n", err);
        while(true);
    }

    //ESP_LOGI(TAG, "I2S driver installed.");
    Serial.println("I2S driver installed.");

}

extern "C" void app_main() {
     initArduino();
     //wire begin for sensors
    setupSPH0645();
    Wire.begin(I2C_SDA, I2C_SCL);
    Serial.begin(115200);
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

   }

Any help would be greatly appreciated. Thank you.

stale[bot] commented 3 years ago

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

kimble4 commented 3 years ago

I'm seeing similar problems, using I2S audio output with a MAX98357A along with a pair of PCF8574 IO expanders (one driving a 16x2 LCD, the other a series of LED and relay). I2C on its own works fine, as does the I2S audio, so it doesn't appear to be a hardware problem.

When I attempt to use both I get choppy audio, and there is a torrent of Bus Busy errors and the IO expander output ports start flicking on and off at random. It also seems to break OTA updates (they proceed slowly then time out), I suspect due to some timing issue, but haven't investigated.

It doesn't seem to make a difference whether I set up the I2C or I2S first: Whichever is set up first works fine, until the other is started.

me-no-dev commented 3 years ago

@ameerhazo did you resolve the issue?

ameerhazo commented 3 years ago

Hi @me-no-dev, I've since transitioned to fully using my own implementation of the IDF I2C API instead of the Wire library and havent had any problems after that.

me-no-dev commented 3 years ago

@ameerhazo we are going to move Arduino's Wire to use IDF APIs soon as well. Currently it's missing write without STOP and once that is implemented, all chips will use the same IDF API underneath