wm8731+teensy schematics?

Status
Not open for further replies.

manatee

Active member
Hi !

Any good wm8731 + teensy schematics? i would like to try this codec but i«m have trouble to find a schematic for this...

Thanks in advance!
 
You have to understand that a codec is most times connected to a Teensy through 2 busses at the same time:
Firts and most important is the I2S bus (called audio interface in the wm8731 data sheet/block diagram) which transports the audio data in and out at high speed: The signals are Master clock, bit clock, L/R clock, data in, data out.
Second, there is the I2C bus (called control interface in the wm8731 data sheet/block diagram) which allows the Teensy to control the codec and which has only 2 signals, SCL and SDA.

Thus, in total, besides Vdd and GND, there are 7 signals to connect.
 
There are 2 ways to use the WM8731. Either Teensy or the WM8731 can create the I2S clock signals, which is called I2S master mode.

WM8731 is very commonly used in master mode. That's how it's used in the example code, in Arduino click File > Examples > Audio > HardwareTesting > WM8731MikroSine. If you go with this well worn path, you can probably make use of the schematic if MikroElectronika's MIKROE-506 audio board. Instructions for connecting that board to Teensy can be found in that example code.

The main downside to this approach is you can't also use Teensy's other audio inputs & outputs, like USB, ADC, DAC & PWM. All of those run sync'd to Teensy's clock. When a chip like WM8731 controls the audio timing, if you try to also use others with different timing you'll get audio glitches or artifacts.

WM8731 can also be configured to run in I2S slave mode. I don't have a schematic for you, but I can tell you I did test this years ago using a modified MicroE board. The mods involved removing the crystal and running Teensy's MCLK signal to the WM8731. When you use the design tool, you'll notice it has 2 different objects to control the WM8731. Which of those you use controls whether it gets configured for master or slave mode.

If you go with master mode for the WM8731, make sure you use the proper 11.2896 MHz crystal. If you use 12 MHz, you won't be able to configure for 44100 Hz sample rate which the audio library expects.
 
Ok, looking at this mutable instruments schematic:
https://imgur.com/a/OGNZrDd
i understand where to plug the SCL, SDA and SCK, what i dont know is where to plug (or if it«s necessary)the LRCKs and SIN on teensy
Any thoughts?

fwiw, the easiest thing (to avoid having the mod the audio library) should be to simply wire i2s/i2c signals as per the "audio board": https://www.pjrc.com/store/teensy3_audio.html ; the signals are just labelled differently than in the MI schematic:

I2S_SIN = RX = teensy pin 13
I2S_SOUT = TX = teensy pin 22
I2S_LRCK = LRCLK = teensy pin 23 (this goes to both DACLRC (5) and ADCLRC (7))
I2S_SCK = BCLK = teensy pin 9

for i2c, the mode pin (21) has to be tied to ground (as per the MI schematic). also (and depending what you want to do), i'd probably go with teensy = master / wm8731 = slave (if you wanted to use the audio library with minimal headaches), in which case no crystal, but MCLK (teensy pin 11) connected to XTI; the XTO pin can float (unlike the MI schematic).

also note that the portion you posted is basically straight out of the datasheet (p.56); it doesn't show the decoupling for AVDD, DBVDD, etc. everything else is about input/output conditioning, this will really depend on what it is that you want to achieve. the remainders of the MI schematic you posted is for modular signal levels (obviously) and the inputs and outputs are AC-coupled; this may or may not be what you want.
 
I'm trying to make a new Teensy 3.5 based PCB which uses the WM8731 for audio in/out. I've had an enitire prototype PCB made (they're so cheap nowadays it seemed easier), but I've only populated the parts shown in the schematics below. I pieced this schematic together using the info on this site, and @blackaddr very useful guitar pedal schematic.

Screenshot 2019-02-16 at 12.55.05.jpg
Screenshot 2019-02-16 at 12.55.21.jpg

I'm attempting to run the WM8731 as a slave, with Teensy as host. I couldn't find example code to do this (only to use it in master mode). But have tried the following:

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#define ENABLE_CODEC

constexpr const int IN_BUILT_LED_PIN(13);

#ifdef ENABLE_CODEC
AudioInputI2S            audio_input;       //serial output works again if I comment these out
AudioOutputI2S           audio_output;
AudioControlWM8731       wm8731;
#else // !ENABLE_CODE
AudioInputAnalog        audio_input;
AudioOutputAnalog       audio_output;
#endif // !ENABLE_CODE

AudioSynthWaveformSine   sine_generator;
AudioConnection          patch_cord_1( sine_generator, 0, audio_output, 0 );


void setup() 
{
#ifdef ENABLE_CODEC
  wm8731.enable();
#endif
  
  AudioMemory( 256 );
  
  pinMode( IN_BUILT_LED_PIN, OUTPUT );
  
  sine_generator.amplitude(1.0f);
  sine_generator.frequency(440.0f);

#ifdef ENABLE_CODEC
  wm8731.volume(1.0f);
#endif

  Serial.begin(9600);

  Serial.println("Setup finished!");
}

void loop()
{

  digitalWrite( IN_BUILT_LED_PIN, HIGH );
  delay( 1000 );
  digitalWrite( IN_BUILT_LED_PIN, LOW );
  delay( 1000 );

  //wm8731.enable();
}

If I comment out ENABLE_CODEC, I can see a sine wave at the Teensy's in-build DAC. I've checked the codec is getting power, and from what I can see the I2C and I2S busses are sending data (tested with oscilloscope). But I don't see any data (expected sine wave) coming out at LOUT pin (or ROUT). I notice that Serial.print() stops working when I try to use the Audio Codec, but the light keeps flashing, so the code hasn't crashed. (It works if I comment out the I2S ins and outs). Am I doing something silly? Hopefully so!
 
Ah yeah, thanks very much, Paul! I hadn't even considered that. I've fixed this now, and it solves the issue with Serial.print(). Still no sine wave though. :( Do my connections look correct in the schematic? I'm seeing lots of digital activity on LRCLK, but MCLCK and BCLK just seem to be at a negative voltage (around -1.6V). I shall investigate further..

Here's the corrected code
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#define ENABLE_CODEC

//constexpr const int IN_BUILT_LED_PIN(13);

#ifdef ENABLE_CODEC
AudioInputI2S            audio_input;
AudioOutputI2S           audio_output;
//AudioInputAnalog        audio_input;
//AudioOutputAnalog       audio_output;
AudioControlWM8731       wm8731;
#else // !ENABLE_CODE
AudioInputAnalog        audio_input;
AudioOutputAnalog       audio_output;
#endif // !ENABLE_CODE

AudioSynthWaveformSine   sine_generator;
AudioConnection          patch_cord_1( sine_generator, 0, audio_output, 0 );


void setup() 
{  
#ifdef ENABLE_CODEC
  wm8731.enable();
#endif
  
  AudioMemory( 256 );
  
  sine_generator.amplitude(1.0f);
  sine_generator.frequency(440.0f);

#ifdef ENABLE_CODEC
  wm8731.volume(1.0f);
#endif

  Serial.begin(9600);

  Serial.println("Setup finished!");
}

void loop()
{
  delay( 1000 );
  Serial.println("loop");
}
 
I must confess, I haven't used WM8731 in slave mode (Teensy as I2S master) since the very earliest days of the audio library. Before we had the STGL5000, I did some of the earliest development using a MicroE-506 hacked for master mode, where I desoldered the crystal and connected MCLK. But that hardware suffered a "learning experience" not long after the first SGTL5000 prototype which later became the audio shield we sell today. Since then I've bought a couple more of those MikroElektronia WM8731 boards, replaced the crystal (for 44.1 kHz use), and only used them in their intended master mode (Teensy as I2S slave).
 
I must confess, I haven't used WM8731 in slave mode (Teensy as I2S master) since the very earliest days of the audio library. Before we had the STGL5000, I did some of the earliest development using a MicroE-506 hacked for master mode, where I desoldered the crystal and connected MCLK. But that hardware suffered a "learning experience" not long after the first SGTL5000 prototype which later became the audio shield we sell today. Since then I've bought a couple more of those MikroElektronia WM8731 boards, replaced the crystal (for 44.1 kHz use), and only used them in their intended master mode (Teensy as I2S slave).

Interesting reading, thanks Paul! I'd be really interested to hear from anyone that has got the WM8731 codec working in slave mode (Teensy as IS2 master) using the teensy audio library.
 
Interesting reading, thanks Paul! I'd be really interested to hear from anyone that has got the WM8731 codec working in slave mode (Teensy as IS2 master) using the teensy audio library.

As mentioned above, my BALibrary uses the WM8731 in slave mode. I provide a replacement for the default AudioControlWM8731 called BAAudioControlWM8731. It provides some robustness enhancement on the I2C bus as well as exposes a few more features.
 
Thanks @blackaddr, I plan to try this out next. Does my schematic look correct to you?

I don't see any obvious difference vs my design for the I2S/I2C lines other than the pullups for I2C. 4.7K is a little weak for 3.3V, mine are in the 2K range. This shouldn't be a big problem though. You need to figure out if it's the I2C that's not working our just the I2S. When you use the codec control class in the Teensy library, it will silently fail if there are bus errors (missing ACKs, etc.). You can either modify the Teensy Audio library to report any errors, or you can look at my class mentioned above which will at least retry on an error. You can modify my class to print if errors occur.

If the I2C is working fine with no bus errors reported, try putting the device in analog bypass mode and feed an analog signal to the codec input. This can check the analog audio path without needing the I2S bus working. IF all that checks out, you know there is something wrong with the I2S stuff.
 
I don't see any obvious difference vs my design for the I2S/I2C lines other than the pullups for I2C. 4.7K is a little weak for 3.3V, mine are in the 2K range. This shouldn't be a big problem though. You need to figure out if it's the I2C that's not working our just the I2S. When you use the codec control class in the Teensy library, it will silently fail if there are bus errors (missing ACKs, etc.). You can either modify the Teensy Audio library to report any errors, or you can look at my class mentioned above which will at least retry on an error. You can modify my class to print if errors occur.

If the I2C is working fine with no bus errors reported, try putting the device in analog bypass mode and feed an analog signal to the codec input. This can check the analog audio path without needing the I2S bus working. IF all that checks out, you know there is something wrong with the I2S stuff.

Thanks @blackaddr I had another look at this last night. It turns out my schematic *is* slightly wrong. CSB and MODE pins were connect to GND net, NOT AGND or DGND, so were basically connected to each other and nothing else. Now that is fixed (with a bit of hacky wire) I'm seeing ACKs come back from the chip on my logic analyser. So at least the chip isn't dead! I'll try your library next so I can add more logging about what is going on. Will report back..
 
I can confirm WM8731 is working in slave mode.

I found my last MicroE-506 board and wired it up to a Teensy 3.2. The connections are exactly the same as master mode, except I removed the crystal and 2 capacitors, and connected MCLK (pin 11) to WM8731 XTI/MCLK.

DSC_0329_web.jpg

The output is driving headphones and the input connects to an iphone6 (last one Apple made with a headphone jack) playing music,

Here's the code I ran.

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform       waveform1;      //xy=245,160
AudioInputI2S            i2s1;           //xy=265,252
AudioOutputI2S           i2s2;           //xy=429,158
AudioAnalyzeRMS          rms2;           //xy=436,323
AudioAnalyzeRMS          rms1;           //xy=444,265
AudioConnection          patchCord1(waveform1, 0, i2s2, 0);
AudioConnection          patchCord2(waveform1, 0, i2s2, 1);
AudioConnection          patchCord3(i2s1, 0, rms1, 0);
AudioConnection          patchCord4(i2s1, 1, rms2, 0);
AudioControlWM8731       wm8731m1;       //xy=292,379
// GUItool: end automatically generated code


void setup() {
  wm8731m1.enable();

  AudioMemory(15);

  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(440);
  waveform1.amplitude(0.9);

  wm8731m1.volume(0.50);
  wm8731m1.inputSelect(AUDIO_INPUT_MIC);
  // wm8731m1.inputSelect(AUDIO_INPUT_LINEIN); // not connected on MikroE-506
}

elapsedMillis msec;

// Print a simple level meter
void loop() {
  if (msec > 40) {
    if (rms1.available() && rms2.available()) {
      msec = 0;
      int level_left = rms1.read() * 30.0;
      int level_right = rms2.read() * 30.0;
      printchar(' ', 30 - level_left);
      printchar('<', level_left);
      Serial.print("||");
      printchar('>', level_right);
      Serial.println();
    }
  }
}

void printchar(char c, int num) {
  for (int i=0; i < num; i++) {
    Serial.write(c);
  }
}

I can hear the sine output on the headphones, and the serial monitor is responding to the incoming music.

sc.png

A couple more photos....

DSC_0330_web.jpg

DSC_0331_web.jpg

Here's the schematic for that MikroE-506

m506.png
 
I don't see any obvious difference vs my design for the I2S/I2C lines other than the pullups for I2C. 4.7K is a little weak for 3.3V, mine are in the 2K range. This shouldn't be a big problem though. You need to figure out if it's the I2C that's not working our just the I2S. When you use the codec control class in the Teensy library, it will silently fail if there are bus errors (missing ACKs, etc.). You can either modify the Teensy Audio library to report any errors, or you can look at my class mentioned above which will at least retry on an error. You can modify my class to print if errors occur.

If the I2C is working fine with no bus errors reported, try putting the device in analog bypass mode and feed an analog signal to the codec input. This can check the analog audio path without needing the I2S bus working. IF all that checks out, you know there is something wrong with the I2S stuff.

I tried your BALibary, and 'commented in' the serial output. The I2C appears to be working fine, I get SUCCESS on all Wire transactions. At least the chip is alive and working in some capacity. So it seems it's the I2S that's failing somehow. I shall try your idea with testing the analog audio path next (I'm assuming I can do this with setAdcBypass()?).

If this works, any idea how I could have screwed up the I2S? I'm seeing activity on these data buses. I would have expected to see noise coming out of the line out if the data was wrong, but I just get 0v. Is there a way to interrogate the chip for I2S errors? I can't see one in the datasheet,
 
Hi everybody,
I've been away from the forum for many months for health reasons, and because I was unable to solve the audio board quadrature bug in which the two channels are randomly offset by a single sample on power-up or program reload.

BUT now I'm back, and last night I stumbled across this thread.

As it happens I am faced with exactly the same problem. In yet another attempt to solve the quadrature offset problem I've been trying to use a WM8731 codec - so far unsuccessfully. :( I decided against using the Mikroe board because of the lack of line-out connections. Instead, I'm working with the WM8731 chip directly, mounted on an Adafruit 28 pin TSSOP breakout board. I have also made an adapter board that has the same pinout as the Teensy Audio board and plugs in directly in the sockets on all my T3.6 and T3.2 boards. The WM8731 works (or at least should!) in slave mode.

Right now all the timing and data signals seem to be correct (MCLK, BLCK, the two LRC signals, and the I2Sout from the Teensy) as seen on the 'scope. The timing looks good. BUT there is no response on the WM8731 output pins. I've checked the I2C connection lines and they are active during the enable phase... It's equally catatonic on both Teensy 3.2 and 3.6...

My plan for today is 1) try another WM8731 chip, 2) try using the BALibrary enable/set-up, and 3) continue to scratch my head. I'll post a couple of photos of the setup.

Derek
 
Hi everybody,
I've been away from the forum for many months for health reasons, and because I was unable to solve the audio board quadrature bug in which the two channels are randomly offset by a single sample on power-up or program reload.

BUT now I'm back, and last night I stumbled across this thread.

As it happens I am faced with exactly the same problem. In yet another attempt to solve the quadrature offset problem I've been trying to use a WM8731 codec - so far unsuccessfully. :( I decided against using the Mikroe board because of the lack of line-out connections. Instead, I'm working with the WM8731 chip directly, mounted on an Adafruit 28 pin TSSOP breakout board. I have also made an adapter board that has the same pinout as the Teensy Audio board and plugs in directly in the sockets on all my T3.6 and T3.2 boards. The WM8731 works (or at least should!) in slave mode.

Right now all the timing and data signals seem to be correct (MCLK, BLCK, the two LRC signals, and the I2Sout from the Teensy) as seen on the 'scope. The timing looks good. BUT there is no response on the WM8731 output pins. I've checked the I2C connection lines and they are active during the enable phase... It's equally catatonic on both Teensy 3.2 and 3.6...

My plan for today is 1) try another WM8731 chip, 2) try using the BALibrary enable/set-up, and 3) continue to scratch my head. I'll post a couple of photos of the setup.

Derek

I'd be interested to hear how you get on with this, Derek. Were you able to confirm if the I2C setup transaction from Teensy to WM8731 completed successfully? If so you are in the same boat as me. I'll continue debugging when I get time and share my findings here..
 
If all else fails, maybe grab one of those MicroE-506 boards and wire it up the same as msg #16. They you'll be able to make side-by-side comparison of the hardware to see what's different.
 
If all else fails, maybe grab one of those MicroE-506 boards and wire it up the same as msg #16. They you'll be able to make side-by-side comparison of the hardware to see what's different.

Yup, that's definitely on my list of options! Only getting very limited to time to spend on it at the moment though..
 
Well, the good news is that I have the WM8731 chip working interfaced directly to the Teensy 3.6. It's working with BALibrary, but I still no have luck just with the Audio Lib WM8731 handler alone. But here's the problem: I'm getting lots of random I2C errors (and I mean lots!). I think the reason that the BALibrary works is that its I2C write() function checks the error status returned by endTransmission() and repeats the transmission until it gets SUCCESS. It can take many attempts. The SDA and SCL lines look clean on the scope. I've played around with the pull-ups, and the error rate seems to go up significantly above about 1.5k. I've settled on 1k (which is what the Mikroe board uses) but that seems low.

I took a look at at using the IC3_t3 library to see if that helps, but it doesn't play nice with the Audio library. The function calls get confused with the Wire library (which seems to be implicitly loaded inside the Audio lib.)

Anyway, once it's done with its I2C register loading it seems to work well, I've had a direct LineIn -> LineOut passthrough sketch running continuously for more than 36 hours without problems... I'm continuing to look into the I2C issues.
 
Try running your Teensy at a lower frequency (96 MHz or less) via the IDE. I also found lots of problems with I2C errors on WM8731. Two things made a huge improvement.
1. Turn the Teensy clock down.
2. Disable the I2S clock while the I2C was active.

Originally I thought it was a Teensy Library problem but the SGTL5000 has no issues. There is something about the Teensy/WM8731 combination that had issues.

Turning off the I2S clock is not a permanent solution. Best work around I found was repeating failed transfers.

I do not think the PCB is a factor.
 
There is something about the Teensy/WM8731 combination that had issues.

On this one, I'm going to wait until someone posts a complete (and hopefully small) program which demonstrates the problem.

You can see in msg #16 the hardware I have here for testing...
 
Status
Not open for further replies.
Back
Top