Can't get I2S slave mode to work

njswede

Member
Hi!

As part of a larger project, I'm going to need to consume an I2S stream from a device that runs as a master, so the Teensy needs to run in slave mode. I'm using a Teensy 4.1.

I have BCLK hooked up to pin 21, LRCLK to pin 20 and the data to pin 8. Judging from the scope, the signals are OK.

From the top is LRCLK, data and BCLK.
1767303987111.png

Bit clock is measured t0 2.822MHz, frame clock is measured to 44.10kHz. Everything looks in order.

But, I'm not receiving any data. Below is my test code. Any ideas? I'm sure I've overlooked something stupid.

C++:
#include <Arduino.h>
#include <Audio.h>

AudioInputI2Sslave i2sInput;       // Audio input from I2S
AudioOutputI2Sslave i2sOutput;     // Audio output to I2S
AudioAnalyzeRMS          rms;           // RMS analyzer
AudioConnection          patchCord1(i2sInput, 0, rms, 0); // Connect input to RMS analyzer
AudioConnection myPatchCord1(i2sInput, 0, i2sOutput, 0); // Connect input to output left channel
AudioConnection myPatchCord2(i2sInput, 1, i2sOutput, 1); // Connect input to output right channel

void setup() {
  // put your setup code here, to run once:
  AudioMemory(12);
  Serial.begin(115000);
  delay(1000); // Wait for serial to initialize
  Serial.println("Starting I2S Slave Audio Example");

  i2sInput.begin();
  i2sOutput.begin();
}

void loop() {
    Serial.println(rms.available() ? "RMS data available" : "No RMS data yet");
    if (rms.available()) {
      Serial.printf("RMS Level Left: %f\n", rms.read());
    }
    delay(100);
}
 
Last edited:
The AudioInputI2Sslave object expects 16-bit audio, from the capture your device seems to be 32-bit?
 
The AudioInputI2Sslave object expects 16-bit audio, from the capture your device seems to be 32-bit?
It's set to run in 16 bit mode and as you can see, I'm getting bursts of 16 bits, then half a frame of silence. They way I thought it worked was that the edge of the LRCLK marks a new frame and then you read your 16 bits and wait for the next edge. Thus, it shouldn't make any difference if there's a delay before the next frame starts.

But I may very well be wrong...
 
You don’t need to call the I2S begin() methods. They’re called by the constructors, and doing so again may cause mayhem … not sure.
 
Back
Top