Teensy 4.0 I2S Support

Status
Not open for further replies.
Blackaddr, thanks a lot for your detailed explanation!
However, I have not understood where to change the setting of I2S drive strength . . . can that be changed on-the-fly after initialization of the I2S lines? Probably not. So I searched for the files where the I2S is initialized for T4. Is it here ??? Strange that totally different pins are initialized in configI2S (pin 5: MCLK, pin 4: BCLK, pin 3: TX):

Luckily, it can be changed on the fly! To explain a little, the output driver (PAD register) settings are done on a per-pin basis rather than 'function' basis. Each pin can be configured for several different functions such as ADC, I2C, SPI, etc. via the MUX register for the pin. Changing a pins function does not change the output driver pad for you. You as a software developer must do that yourself. At the moment, it looks like the Teensy code never touches the output pad settings for any pins, for any function. In most cases, the default pad configuration is probably fine, but not optimal.

This is why you can change the output driver settings for any pin at any time without worrying about what function it's configured for. I think it's reasonable to assume the Teensy code might start configuring the output pads in the various object begin() functions, but as of today the pad registers are never touched.

So, the registers I indicated in the above post for I2S and I2C correspond to the pins I'm using for those functions. Since the Teensy library never touches their pad configuration, I can configure them myself at any time, but it's probably good practice to wait until after begin() is called if you want to override the library's behavior whatever that is.
 
Thanks all for this thread! My T4 and Audio Shield Rev. C arrived just today, and I was starting to mate them with a solder marriage when I thought I'd better check postings for compatibility one more time ... I want to use additional I2S inputs, but I will wait until AS Rev. D is out.
 
Can anyone confirm that AudioInputI2S works with the Teensy 4.0?

It does not work for me. I can play sounds out via AudioOutputI2S but I can't bring audio in using AudioInputI2S.


My Setup:


I wired up the Teensy Audio Adapter to a Teensy 4.0 using the pin remapping described by Paul (https://www.pjrc.com/store/teensy3_audio.html). Below is a picture of my wiring diagram that I made for myself.

View attachment 17212

Below is a picture of it actually wired.

View attachment 17213

Software:

I'm running Arduino 1.8.9 with Teensyduino 1.4-beta7. I'm running the ToneSweep and the PassThroughStereo examples from the Teensy Audio library.

Symptoms:

ToneSweep runs fun. PassThrougStereo, however, produces no audio at the output (yes, I am injecting audio into the system). Most curiously, going back to ToneSweep, if I simply add a line instantiating an AudioInputI2S object, it breaks ToneSweep:

Code:
AudioInputI2S      audioInput;  //I added this
AudioSynthToneSweep myEffect;   //this was here
AudioOutputI2S      audioOutput;        // audio shield: headphones & line-out

// The tone sweep goes to left and right channels
AudioConnection c1(myEffect, 0, audioOutput, 0);
AudioConnection c2(myEffect, 0, audioOutput, 1);

Note that I don't need to connect audioInput to anything; simply including the line in the sketch prevents the ToneSweep sketch from making any audio. It compiles fine. It simply doesn't output any audio.

Has anyone confirmed that AudioInputI2S works with Teensy4?

Chip

see: https://forum.pjrc.com/threads/5734...o-Audio-Shield?p=213469&viewfull=1#post213469
 
@DD4WH - Have you had a chance yet to look whether the T4 has cured the "twin peaks" bug that has driven me (and possibly you) crazy over the past couple of years with quadrature I2S inputs on the T3.6?
I'm just wiring mine up to test.

For those who don't know what I'm talking about, this bug cause the two I2S input channels to be out of synch by a single sample randomly on program reload or power-up, and when present will remain until the next upload or power-up. It is disastrous for quadrature signal processing because it completely destroys the phase relationship between the two channels. I'm pinning a lot of hope on the possibility that it's gone away on the the T4 :rolleyes:
 
That's a common problem in all digital audio applications and not restricted to Teensy or I2S. You need to sync to a master timecode to overcome it.
 
Not arguing with you, and I know it's not just a Teensy problem, but I can't think of a single reason why this should be true, after all we have clocks all around the I2S interface, and 44.1 ksamples/sec is hardly a high speed interface. Is it the codec that's the problem, the DMA interface, or what?
 
Not arguing with you, and I know it's not just a Teensy problem, but I can't think of a single reason why this should be true, after all we have clocks all around the I2S interface, and 44.1 ksamples/sec is hardly a high speed interface. Is it the codec that's the problem, the DMA interface, or what?

The CODEC and I2S are fine. The problem is the software module generating the audio signal is usually decoupled from the I2S interface, often by driver code which includes a buffer. As you point out, sometimes it sends the right channel for any timecode ahead of the left channel and you get the one sample delay. Usually drivers that use a FIFO don't have this problem as the samples are ordered, but you get a delay instead. The correct solution is to generate a local sync which triggers generation of the left, then the right channel, whilst telling the driver to use the previous left, then the right channel, buffers. This sync can just be the rising edge of LRCLK if you just want an internal reference.
 
@MikeDB - thanks. Yep, I just confirmed that the trouble still exists on the T4, see here. Are you saying that a mere mortal might have a shot at fixing the problem, or is it so buried in low-level stuff as to be impractical? It just seems that since the Teensy is the Master, and the codec the slave in this case, it should be possible to control all timing issues.

Is there any info anywhere on past attempts to address it?
 
@MikeDB - thanks. Yep, I just confirmed that the trouble still exists on the T4, see here. Are you saying that a mere mortal might have a shot at fixing the problem, or is it so buried in low-level stuff as to be impractical? It just seems that since the Teensy is the Master, and the codec the slave in this case, it should be possible to control all timing issues.

Is there any info anywhere on past attempts to address it?

Well I'm going to have to fix it come what may as I have a blank PCB for a Pi4, a T4 and several 5102 DACs arriving from China any day now. The T4 adds SPDIF and extends the Pi's limited I2S capabilities. It's just as well I saw your post as otherwise I might not have noticed this problem immediately
 
This is why you can change the output driver settings for any pin at any time without worrying about what function it's configured for. I think it's reasonable to assume the Teensy code might start configuring the output pads in the various object begin() functions, but as of today the pad registers are never touched.

@Blackaddr: Thanks a lot! After hours of searching for my issue, I resoldered all connections and now the T4 & audio shield combination seems to work reliably up to 120ksps sample rate. With higher sample rates, there are drizzling noises and distortions. I could not cure them with different output driver settings. I will wait for audio shield rev D and see whether I can get higher sample rates with shorter and more direct connections on that upcoming board.
 
@bicycleguy: looks good! My working setup is very similar! How high can you tune up the sample rate until your setup gives distorted audio?
 
@Blackaddr: Thanks a lot! After hours of searching for my issue, I resoldered all connections and now the T4 & audio shield combination seems to work reliably up to 120ksps sample rate. With higher sample rates, there are drizzling noises and distortions. I could not cure them with different output driver settings. I will wait for audio shield rev D and see whether I can get higher sample rates with shorter and more direct connections on that upcoming board.

Unfortunately, I have to say that the crackling noise returned. I made numerous attempts to cure that by returning to sample rate 44100sps, by inserting different resistor values into the MCLK line, by changing the drive strength at IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09, and I shortened every wire connection from the T4 to the Teensy audio shield to a maximum of 2cm.

I do not seem to be able to get reliable audio from T4 plus Teensy audio shield . . .

T4_and_audio_shield.JPG

Would be nice if anybody has additional ideas?
 
Last edited:
...
Would be nice if anybody has additional ideas?

I'm trying to get the setup here:https://forum.pjrc.com/threads/57421-Teensy4-Audio-Board?p=214104&viewfull=1#post214104

to run the default audio board stuff like:
SdCardTest, WavFilePlayer ect. along with the ILI9341_t3 display stuff like DemoSause.

With the additions below they run separately but haven't got audio (in particular the SdCardTest stuff) to work when attached to the display.
I started with the ones in the post below and gradually added more. Added comments on some pins of which app req'd them.
Turned some on and off to verify they definitely require it or even more refinement. So far I've only messed with output pins.

Code:
  //IOMUXC stuff below was required to get SDcard to work and to attach to other boards.
  //from: [url]https://forum.pjrc.com/threads/57167-Teensy-4-0-I2S-Support?p=213128&viewfull=1#post213128[/url]
  // defaults were all 0x10B0 which is keeper, Medium speed (100 Mhz), drive strength = R0/6 = 150/6 = 25 ohms (the second strongest drive strength available) // My changes were:
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00 = 0xF808; // SCL, pullup at 22K, open drain enable, low speed, drive strength at R0 (150 ohm)
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_01 = 0xF808; // SDA
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09 = 0x8; // MCLK, low speed, drive strength at R0 (150 ohm).
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_10 = 0x8; // BCLK
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11 = 0x8; // LRCLK
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_01 = 0x8; // OUT1A
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = 0x8; // SCK  mdr20190828 reqd in myT4_SdCardTest
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02 = 0x8; // MOSI  mdr20190828 reqd in myT4_SdCardTest
  
  IOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_06 = 0x8; // 4 BACKLIGHT, for myT4_DemoSauce cause I didn't use a resistor  mdr20190828
 
I fixed that by wrapping all wires between Teensy 3.6 and the audio shield in copper foil. Then I soldered the foil to Teensy's ground. Didn't try it with Teensy 4.0
Today I'm getting the breakout board for that: https://www.pjrc.com/breakout-board-for-teensy-4-0/
I don't want to mess with the wires again. I'll let you know how it goes.
So far, the $37 for T4, the audio and the breakout seems very reasonable.
I hope it's in my mailbox by now. 8)
 
Would be nice if anybody has additional ideas?
Frank,
Have you gotten rid of the crackling?

I had an issue where the T4 SCK pin13 was extremely sensitive just trying to play the 'WavFilePlayer'. The SCK would pick up some kind of noise and cause the SDcard to not work and a bunch of bussing and static.
I already posted some attempts in an earlier post and have since modified them as below:
Code:
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00 = 0x1F808; // SCL, hysterisus, pullup at 22K, open drain enable, low speed, drive strength at R0 (150 ohm)
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_01 = 0x1F808; // SDA
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09 = 0x8; // MCLK, low speed, drive strength at R0 (150 ohm).
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_10 = 0x8; // BCLK
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11 = 0x8; // LRCLK
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_01 = 0x8; // OUT1A
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02 = 0x8; // MOSI  mdr20190828 helped get to SDTEST1.WAV & SDTEST2.WAV test
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = 0x8; // SCK  mdr20190828 reqd in myT4_SdCardTest
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_01 = 0x10000;  //MISO  mdr20190831 hysterisus+default for WavFilePlayer
Each one of those changes seemed to either be required or helpful, none seemed to hurt. Note that I added hysteresis to the inputs.

However, in messing around with the ILI9341 display discovered that even without the display just adding its's req'd stuff:

#include "ILI9341_t3.h"
const uint8_t TFT_DC = 5;
const uint8_t TFT_CS = 9;
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

and adding

tft.begin(); as the first line in setup() seemed to cure the whole issue. I can remove all the tweaks above.

I think something is not getting set correctly somewhere with a T4 library.

Here's my complete code:
Code:
#define MYVERSION_STUFF "myT4WavDisplay, 2019/9/2"
/* Simple WAV file player example from WaveFilePlayer
 * mdr20190902  After installing 100 ohm resistor from T4 pin13 to audio board pin14 this will play but only after having played
 * 'myT4_DemoSauce' first, and then load and run.  Won't work from just plugging in. fixed, just have to add tft.begin(); to
 * make it work.  Don't need all the IOMUX stuff.
 * */

#include <SPI.h>
#include <SD.h>
#include "ILI9341_t3.h"
#include "font_Arial.h"
#include <Wire.h>
#include <SerialFlash.h>
#include <Audio.h>

// Use these with the Teensy Audio Shield and Teesny 4.0  mdr20190823
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  11
#define SDCARD_SCK_PIN   13

// TFT pins
const uint8_t TFT_DC = 5;
const uint8_t TFT_CS = 9;

ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
AudioPlaySdWav           playWav1;
// Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
AudioOutputI2S           audioOutput;
//AudioOutputSPDIF       audioOutput;
//AudioOutputAnalog      audioOutput;
AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);
AudioControlSGTL5000     sgtl5000_1;

void setup() {
  tft.begin();   //this seems to make the audio work
  tft.setRotation( 1 );
  tft.fillScreen(ILI9341_BLACK);

  // Serial
  if( true ) {
    Serial.begin( 9600 );
    tft.setTextColor(ILI9341_YELLOW);
    tft.setFont(Arial_18);
    tft.setCursor(10, 42);
    tft.print(MYVERSION_STUFF);
    tft.setTextColor(ILI9341_GREEN);
    tft.setFont(Arial_18);
    while (!Serial && millis() < 5000) { // wait for Arduino Serial Monitor
      tft.fillRect(118, 182, 42, 18, ILI9341_BLACK);
      tft.setCursor(118, 182);
      tft.print((5000.0 - (float)millis()) / 1000.0, 1);
      tft.print(" sec");
      delay(100);
    }
  }
//Serial.begin(9600);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(8);

  // Comment these out if not using the audio adaptor board.
  // This may wait forever if the SDA & SCL pins lack
  // pullup resistors
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.4);

  //mdr20190828
  //from: https://forum.pjrc.com/threads/57167-Teensy-4-0-I2S-Support?p=213128&viewfull=1#post213128
  // defaults were all 0x10B0 which is keeper, Medium speed (100 Mhz), drive strength = R0/6 = 150/6 = 25 ohms (the second strongest drive strength available) // My changes were:
  //page 658 if nanual
  //*
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_00 = 0x1F808; // SCL, pullup at 22K, open drain enable, low speed, drive strength at R0 (150 ohm)
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_01 = 0x1F808; // SDA
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09 = 0x8; // MCLK, low speed, drive strength at R0 (150 ohm).
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_10 = 0x8; // BCLK
  IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_11 = 0x8; // LRCLK
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B1_01 = 0x8; // OUT1A
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02 = 0x8; // MOSI  mdr20190828 helped get to SDTEST1.WAV & SDTEST2.WAV test
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = 0x8; // SCK  mdr20190828 reqd in myT4_SdCardTest
  IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_01 = 0x10000;  //MISO  mdr20190831 hysterisus+default for WavFilePlayer
  //*/
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);

  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}

void playFile(const char *filename)
{
  Serial.print("Playing file: ");
  Serial.println(filename);
    tft.fillScreen(ILI9341_BLACK);
    tft.setTextColor(ILI9341_YELLOW);
    tft.setFont(Arial_24);
    tft.setCursor(10, 80);
    tft.print(filename);

  // Start playing the file.  This sketch continues to
  // run while the file plays.
  playWav1.play(filename);

  // A brief delay for the library read WAV info
  delay(5);
  tft.setTextColor(ILI9341_GREEN);
  tft.setFont(Arial_18);
  // Simply wait for the file to finish playing.
  unsigned long started=millis();
  while (playWav1.isPlaying()) {
    
      tft.fillRect(118, 182, 62, 18, ILI9341_BLACK);
      tft.setCursor(118, 182);
      tft.print((float)(millis()-started) / 1000.0, 1);
      tft.print(" sec");
      delay(100);
// uncomment these lines if you audio shield
    // has the optional volume pot soldered
    //float vol = analogRead(15);
    //vol = vol / 1024;
    // sgtl5000_1.volume(vol);
  }
}


void loop() {
  playFile("SDTEST1.WAV");  // filenames are always uppercase 8.3 format
  delay(500);
  playFile("SDTEST2.WAV");
  delay(500);
  playFile("SDTEST3.WAV");
  delay(500);
  playFile("SDTEST4.WAV");
  delay(1500);
}
 
Frank, Have you gotten rid of the crackling?

No, unfortunately not. I spent many hours on that and have not succeeded in performing reliable I2S In and Out with the Teensy 4.0.

The very same hardware (Teensy Audio Shield, PCM1808 & PCM5102) with the T3.6 work perfectly, but not with the Teensy 4.0.

I have stopped working with the T4 for that reason, I will have to wait for someone to build a reliable audio board specifically for T4 or cure the register setting issue.

Please note that I2S out works perfectly with the T4. It is the I2S in (PCM1808 ADC or SGTL5000 codec) that produces the problems.

Yes, could be you are right that there is a settings problem somewhere in the lib, but thats pure speculation from my side and I am not advanced enough to be able to work my way through those register settings . . . would be good if it is possible to use the same audio ADC/DAC hardware that works with the T3.6 . . .

On travel at the moment, so I cannot test your code, sorry!

All the best,

Frank DD4WH
 
With the Teensy 4, I've gotten stereo audio to flow on both the STGL5000 and on my AIC3206. With the Teensy 3.6, I've got 4-channel audio to flow on both the STGL5000 and with my AIC3206. Now, I'd like to move to 4-channels with the Teensy 4.

I've looked through this thread, and I've looked at the i.MX RT1064 reference manual a bit, but it clearly looks to be some heavy lifting in order to understand all of the terms.

Has anyone gotten two AICs to work with the Teensy4? Whether STGL5000 or otherwise? Is there code that you could share?

Chip
 
Thanks again for the hints! ADC works together with DAC !

Connections for documentation:

Teensy 4.0 with ADC PCM1808 module (line-in Input), running simultaneously with the DAC PCM5102 (headphone output):
ADC PCM1808 connections to Teensy 4.0:
FMT = GND
MD1 = GND
MD0 = GND
GND = GND
+5V = Vin
3V3 = 3V3 --> the PCM1808 needs BOTH, +5Volts AND 3V3 connected
BCK = pin 21
OUT = RX = pin 8
LRC = LRCLK = pin 20
SCK = MCL = pin 23

DAC PCM5102 connected as in post #19

Running examples:
PassThroughStereo, FilterFIR --> a 100 tap FIR Filter uses 2.5% of the processor load of the Teensy 4.0 @44.1ksps sample rate, thats incredible !

All the best,

Frank DD4WH

I got my pcm1808 all wired up.. but no joy. did you have to change PassThroughStereo or FilterFIR at all? [edit] ah, right.. saw you were having problems too...
 
With the Teensy 4, I've gotten stereo audio to flow on both the STGL5000 and on my AIC3206. With the Teensy 3.6, I've got 4-channel audio to flow on both the STGL5000 and with my AIC3206. Now, I'd like to move to 4-channels with the Teensy 4.

I've looked through this thread, and I've looked at the i.MX RT1064 reference manual a bit, but it clearly looks to be some heavy lifting in order to understand all of the terms.

Has anyone gotten two AICs to work with the Teensy4? Whether STGL5000 or otherwise? Is there code that you could share?

Chip

I’m currently trying in my extremely rare free time (advancing slowly) to get SAI1 running in 4 audio channel (2 I2S_TX channels) mode. I think that in the end, it will be simpler than synchronizing 2 independent stereo SAIs. But I’m really annoyed by the fact that most SAI1 TX signals (BCLK, SYNC, TX1) are only available at the bottom pads and not on regular pins...
 
Thanks for all your hints on getting rid of the crackle noise. I finally succeeded by using RF perf board with a ground plane and set up the Teensy 4.0 and DAC PCM5102a and ADC PCM1808 on it.

See here for the hardware setup: https://forum.pjrc.com/threads/5726...nd-audio-board?p=217492&viewfull=1#post217492

Now also the ADC PCM1808 works without crackling noise up to 256ksps sample rate (although it is rated to work only up to 96kHz).

Thanks again and keep up the good work!

All the best,

Frank DD4WH
 
Hiya!

I made up a quick adapter PCB to connect the 4.0 and a Rev B Audio board based on chipaudette's wiring diagram here:
https://forum.pjrc.com/threads/57167-Teensy-4-0-I2S-Support?p=212481&viewfull=1#post212481

I'm not using the passthrough so i can't vouch for it working for that, but it does make pretty sounds otherwise!

Here are the eagle files:
View attachment TeensyAudioAdapterAdapter.zip

LayoutPic.PNG

The vias are marked in blue, and the resistor value is 100ohm
I'm just getting into milling so it's got fat traces and is single sided, but it works!
 

Attachments

  • LayoutPic.PNG
    LayoutPic.PNG
    35.4 KB · Views: 281
Last edited:
Thanks for sending me that link! I'm mostly using the synth engines, so my apologies for not digging in the posts, i missed that functionality

I'll probably hand solder in the points with magnet wire on my board but here's a double sided version of the board with the pin connections listed in MichaelMiessners post:
https://forum.pjrc.com/threads/57341-Bad-wiring-posted-somewhere-for-Teesny-4-0-to-Audio-Shield?p=214981&viewfull=1#post214981

Boards and Schematic Update:
View attachment TeensyAudioAdapterAdapterUpdated.zip

LayoutPicUpdate.PNG

Please excuse my schematic, and the board distances are set for my mill so your mileage may vary
 
Status
Not open for further replies.
Back
Top