GIGA R1 audio ADC to I2S pass through not working

Hi everyone,

I'm facing troubles with the audio peripherals on GIGA R1 Wifi board.
I am trying to use it to develop a multichannel audio processing algorithm (2 channels in, N channels out).

I bought this chip from Adafruit as an external DAC output driven by GIGA R1 I2S outputs:

I'm using the following pins from the GIGA R1 board for the I2S output (J5 header):

  • LRCLK: PI0
  • BCLK: PI1
  • DIN: PI3

I am using Arduino_AdvancedAnalog library to drive the I2S external DAC, the internal ADC and the internal DAC.
It works if I feed the I2S signal with a sinewave generated at runtime or with samples from a wav file on a USB stick (using the I2S_DAC_Output.ino example from Arduino_AdvancedAnalog library).

Nevertheless I did not succeed in getting a clean audio input from GIGA internal ADC (pins A0/A1) and feed the signal to this external DAC.
I can hear the input signal but I get a huge distorded noise on top of it by listening to the sound from the PCM5100.

It works if I use the internal 12 bits DAC (pins A12/A13) though.

Here is my current test code:

#include <Arduino_AdvancedAnalog.h>

#define SAMPLE_RATE 48000
#define FRAME_SIZE  256
#define NB_BUFFERS  32

#define I2S
#define DAC

uint32_t frame_counter = 0;

#define DAC_RESOLUTION AN_RESOLUTION_12
#define DAC_MAX_VAL (256 * 2 << (DAC_RESOLUTION * 2))
#define ADC_RESOLUTION AN_RESOLUTION_16
#define ADC_MAX_VAL (256 * 2 << (ADC_RESOLUTION * 2))

AdvancedADC adc1(A0);
AdvancedADC adc2(A1);
#ifdef DAC
AdvancedDAC dac1(A12);
AdvancedDAC dac2(A13);
#endif

#ifdef I2S
// WS, CK, SDI, SDO, MCK
AdvancedI2S i2s(PI_0, PI_1, NC, PI_3, NC);
#endif

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  // ADC init
  Serial.println("Initialize ADC");
  if (!adc1.begin(ADC_RESOLUTION, SAMPLE_RATE, FRAME_SIZE, NB_BUFFERS)) {
      Serial.println("Failed to start ADC1!");
      while (1);
  }
  if (!adc2.begin(ADC_RESOLUTION, SAMPLE_RATE, FRAME_SIZE, NB_BUFFERS)) {
      Serial.println("Failed to start ADC2!");
      while (1);
  }
#ifdef DAC
  // DAC init
  Serial.println("Initialize DAC");
  if (!dac1.begin(DAC_RESOLUTION, SAMPLE_RATE, FRAME_SIZE, NB_BUFFERS)) {
      Serial.println("Failed to start DAC1!");
      while (1);
  }
  if (!dac2.begin(DAC_RESOLUTION, SAMPLE_RATE, FRAME_SIZE, NB_BUFFERS)) {
      Serial.println("Failed to start DAC2!");
      while (1);
  }
#endif
#ifdef I2S
  // I2S init
  Serial.println("Initialize I2S");
  if (!i2s.begin(AN_I2S_MODE_OUT, SAMPLE_RATE, FRAME_SIZE, 32)) {
      Serial.println("Failed to start I2S");
      while (1);
  }
#endif
}

void loop()
{
  bool out_available = true;

#ifdef I2S
  out_available = out_available && i2s.available();
#endif
#ifdef DAC
  out_available = out_available && dac1.available() && dac2.available();
#endif

  if(out_available && adc1.available() && adc2.available())
  {
    Serial.println("Frame " + String(frame_counter));
    //Serial.println(adc_input_buf[0]);
    //Serial.println(adc_input_buf.size());

    SampleBuffer inBuff1 = adc1.read();
    SampleBuffer inBuff2 = adc2.read();
#ifdef DAC
    SampleBuffer outBuff1 = dac1.dequeue();
    SampleBuffer outBuff2 = dac2.dequeue();
#endif
#ifdef I2S
    SampleBuffer txbuf = i2s.dequeue();
#endif

    for (size_t i=0; i<FRAME_SIZE; i++)
    {
#ifdef DAC
      outBuff1.data()[i] = map(inBuff1[i], 0, ADC_MAX_VAL - 1, -DAC_MAX_VAL / 2, DAC_MAX_VAL / 2 - 1);
      outBuff2.data()[i] = map(inBuff2[i], 0, ADC_MAX_VAL - 1, -DAC_MAX_VAL / 2, DAC_MAX_VAL / 2 - 1);
#endif
#ifdef I2S
      txbuf[2 * i] = (int16_t)map(inBuff1[i], 0, ADC_MAX_VAL - 1, -32768, 32767);     // L
      txbuf[2 * i + 1] = (int16_t)map(inBuff2[i], 0, ADC_MAX_VAL - 1, -32768, 32767); // R
#endif
    }

#ifdef DAC
    // Write contents of the output buffer to the DACs
    dac1.write(outBuff1);
    dac2.write(outBuff2);
#endif
#ifdef I2S
    // Write to i2s output buffer
    i2s.write(txbuf);
#endif

    // Release the input buffers
    inBuff1.release();
    inBuff2.release();

    frame_counter++;
  }
}

To replicate the issue, I just comment/uncomment those 2 define to disable/enable I2S or internal DAC:

#define I2S
#define DAC

Does anyone get any clue why I get this behavior?
Is it because the Advanced Analog library fails at synchronising the ADC/DAC and I2S DMA buffers?

Thanks for your help :slight_smile:

Describing a problem by using a "word salad" or vague sketches like “frizzy” doesn’t help anyone understand what’s really going on. In electronics, the basic language is the schematic not casual descriptions. If you're asking for help, you need to provide a clear, complete, and accurate schematic of your circuit. That includes every connection , not just the parts you think are important. Be sure to show:

  • All power and ground lines
  • All power sources and their voltages
  • Component values, part numbers, and orientation if important
  • Pin numbers and labels for all ICs and connectors

If you're using a breakout board, module, or prebuilt system, include a link to the datasheet or product page not just a name or part number. A photo of your wiring can help, but it does NOT replace a proper schematic.

Without this level of detail, people can only guess at what might be wrong. The more precise your documentation, the faster and more accurate the help you'll get.

Hi @gilshultz,

Thank you for your reply and to point out the missing elements you would need to help me out.

Here are a few precisions that I hope would help people to understand my setup.

I am using the following circuits:

Breakout Board:

Adafruit PCM5100 I2S DAC:

Audio Source:

  • MacBook Pro audio output Jack 3.5mm

I2S output:

  • I'm using STM32 M7 Core I2S2 output
  • From STM32H747xI/G datasheet (page 81), I chose the following pins:
    • LR Clock: I2S2_WS on pin PI0, available GIGA R1 J5 header (D69)
    • Bit Clock: I2S2_CK on pin PI1, available GIGA R1 J5 header (D70)
    • Digital Out: I2S_SDO on pin PI3, available GIGA R1 J5 header (D72)
  • No need to provide the master clock to the I2S/DAC chip according to the specification of the component

Input signal conditioning:

  • I used a bias with 10 k resistor and a 1uF capacitor for decoupling to fit the [0, 3.3V] analog range of the GIGA R1 ADC on pins A0 and A1
  • See attached schematic for more precision

Here pictures that should illustrate in more details:

  • A picture of the Adafruit I2S/DAC board with the details of the connections with the Arduino board
  • A photo of my setup with labels
  • A schema of the input bias filter

I will try to work on the full schematic using KiCad or so, but it would require more work so waiting for this I hope this is sufficient to see if there is something wrong.

At least would anyone see anything wrong with the code I shared?



I do not know but that would be a good starting point. Also how fast is the DAC updated and what type of load is on the output?