Use two unidirectional I2S ports simultaneously

chris-kuhr
Posts: 3
Joined: Fri Dec 25, 2020 9:01 am

Use two unidirectional I2S ports simultaneously

Postby chris-kuhr » Fri Dec 25, 2020 9:30 am

Hi *,

I want to hook up an INVENSENSE ICS-43432 i2s mems mic to the first i2s port and an Adafruit Class D i2s to the second port.
They need not to be in sync.

Both i2s ports work, when I use them separately. But if I want to use them simultaneously, I get stuttering and crackling sound out of the speaker.
This happens when I set the i2s pin for the input port, even without any read operation on it.
If I memset the output samples to zero, there is silence.

I am using an Olimex ESP-POE-ISO board.

Does anyone know what the problem might be?


the code:

Code: Select all

#include <driver/i2s.h>

#define BUF_SIZE 512
#define SAMPLERATE 48000

const i2s_port_t I2S_PORT_IN = I2S_NUM_0;
const i2s_port_t I2S_PORT_OUT = I2S_NUM_1;

int32_t samples_stereo[BUF_SIZE*2];

// sine wave 1.5kHz @ 48000Hz
int lenSine = 32;
float sine[32] = {
  0.0,
  -0.195090322016118,
  -0.382683432365079,
  -0.555570233019592,
  -0.707106781186539,
  -0.831469612302538,
  -0.923879532511281,
  -0.980785280403227,
  -1.0,
  -0.980785280403233,
  -0.923879532511293,
  -0.831469612302555,
  -0,70710678118656,
  -0.555570233019617,
  -0.382683432365107,
  -0.195090322016147,
  0.0,
  0.195090322016108,
  0.382683432365071,
  0.555570233019585,
  0.707106781186532,
  0.831469612302532,
  0.923879532511278,
  0.980785280403226,
  1.0,
  0.980785280403235,
  0.923879532511297,
  0.83146961230256,
  0.707106781186567,
  0.555570233019626,
  0.382683432365117,
//  0.195090322016158,

};




void setup()
{
  Serial.begin(115200);
  
  Serial.println("Configuring I2S...");
  esp_err_t err;
  
  const i2s_config_t i2s_config_in = {
      .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
      .sample_rate = SAMPLERATE,                        
      .bits_per_sample = I2S_BITS_PER_SAMPLE_24BIT, 
      .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 = 4,                          
      .dma_buf_len = BUF_SIZE                     
  };

  const i2s_config_t i2s_config_out = {
      .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX),
      .sample_rate = SAMPLERATE,                        
      .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, 
      .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, 
      //.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 = 4,                           
      .dma_buf_len = BUF_SIZE                     
  };
  
  i2s_pin_config_t pin_config_in = {
      .bck_io_num = 4,  // IIS_SCLK
      .ws_io_num = 3,   // IIS_LCLK
      .data_out_num = -1,// IIS_DSIN
      .data_in_num = 5  // IIS_DOUT
  };

  i2s_pin_config_t pin_config_out = {
      .bck_io_num = 14,  // IIS_SCLK
      .ws_io_num = 13,   // IIS_LCLK
      .data_out_num = 15,// IIS_DSIN
      .data_in_num = -1  // IIS_DOUT
  };

  err = i2s_driver_install(I2S_PORT_IN, &i2s_config_in, 0, NULL);
  if (err != ESP_OK) {
    Serial.printf("Failed installing INPUT driver: %d\n", err);
    while (true);
  }
  
  err = i2s_driver_install(I2S_PORT_OUT, &i2s_config_out, 0, NULL);
  if (err != ESP_OK) {
    Serial.printf("Failed installing OUTPUT driver: %d\n", err);
    while (true);
  }


  err = i2s_set_pin(I2S_PORT_IN, &pin_config_in);
  if (err != ESP_OK) {
    Serial.printf("Failed setting DIN pin: %d\n", err);
    while (true);
  }
  
  
  err = i2s_set_pin(I2S_PORT_OUT, &pin_config_out);
  if (err != ESP_OK) {
    Serial.printf("Failed setting  DOUT pin: %d\n", err);
    while (true);
  }

  Serial.println("I2S driver installed and running.");
    
  memset(samples_stereo, 0, BUF_SIZE*2);
}

void loop() {
  int bytesRead;
                
// i2s_read(I2S_PORT_IN, (char *)samples, BUF_SIZE*4, (size_t*)&bytesRead, portMAX_DELAY); 

  for( int i=0; i< BUF_SIZE; i+=lenSine){
    memcpy(&samples_stereo[i], (int32_t*)sine, lenSine);
    memcpy(&samples_stereo[BUF_SIZE+i], (int32_t*)sine, lenSine);
  }
  //memset(&samples_stereo[0], 0, BUF_SIZE*2);
  
  int bytesWritten;      
  i2s_write(I2S_PORT_OUT, (char *)samples_stereo, BUF_SIZE*8, (size_t*)&bytesWritten, portMAX_DELAY); 
}

chris-kuhr
Posts: 3
Joined: Fri Dec 25, 2020 9:01 am

Re: Use two unidirectional I2S ports simultaneously

Postby chris-kuhr » Thu Jan 07, 2021 5:17 pm

I found the solution.

Thanks to this thread:
https://www.esp32.com/viewtopic.php?t=6115

The input port needs to be setup as I2S_MODE_SLAVE.

lladam
Posts: 44
Joined: Tue Jul 20, 2021 12:14 am

Re: Use two unidirectional I2S ports simultaneously

Postby lladam » Thu Dec 07, 2023 3:17 am

Hi ,
did you test the TWO I2S port?
seems it can't work?

Who is online

Users browsing this forum: No registered users and 160 guests