Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 34

Thread: wm8731+teensy schematics?

  1. #1
    Junior Member
    Join Date
    Mar 2015
    Posts
    9

    wm8731+teensy schematics?

    Hi !

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

    Thanks in advance!

  2. #2
    Junior Member
    Join Date
    Mar 2015
    Posts
    9
    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 its necessary)the LRCKs and SIN on teensy
    Any thoughts?

  3. #3
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,386
    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.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,942
    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.

  5. #5
    Senior Member
    Join Date
    Feb 2013
    Posts
    563
    Quote Originally Posted by manatee View Post
    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 its 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.

  6. #6
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    195
    I've designed an advanced audio board (TGA Pro) for the Teensy using a WM8731. The codec is the slave, Teensy is the master so all the other Teensy peripherals work correctly. You can find the product info at the link below. The link to the manual (datasheet) is at the bottom of the page. The schematics are available at the end of the manual.

    https://www.tindie.com/products/Blac...-audio-shield/

  7. #7
    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.

    Click image for larger version. 

Name:	Screenshot 2019-02-16 at 12.55.05.jpg 
Views:	37 
Size:	57.9 KB 
ID:	15923
    Click image for larger version. 

Name:	Screenshot 2019-02-16 at 12.55.21.jpg 
Views:	30 
Size:	84.8 KB 
ID:	15924

    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!

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,942
    AudioInputI2S uses pin 13 to receive data, so this is a conflict:

    Code:
    constexpr const int IN_BUILT_LED_PIN(13);

  9. #9
    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");
    }

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,942
    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).

  11. #11
    Quote Originally Posted by PaulStoffregen View Post
    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.

  12. #12
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    195
    Quote Originally Posted by unicornpower View Post
    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.

  13. #13
    Quote Originally Posted by Blackaddr View Post
    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?

  14. #14
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    195
    Quote Originally Posted by unicornpower View Post
    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.

  15. #15
    Quote Originally Posted by Blackaddr View Post
    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..

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,942
    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.

    Click image for larger version. 

Name:	DSC_0329_web.jpg 
Views:	28 
Size:	193.7 KB 
ID:	15968

    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.

    Click image for larger version. 

Name:	sc.png 
Views:	12 
Size:	28.8 KB 
ID:	15969

    A couple more photos....

    Click image for larger version. 

Name:	DSC_0330_web.jpg 
Views:	21 
Size:	154.0 KB 
ID:	15970

    Click image for larger version. 

Name:	DSC_0331_web.jpg 
Views:	23 
Size:	163.4 KB 
ID:	15971

    Here's the schematic for that MikroE-506

    Click image for larger version. 

Name:	m506.png 
Views:	42 
Size:	75.1 KB 
ID:	15972

  17. #17
    That's very helpful, thanks Paul!

  18. #18
    Quote Originally Posted by Blackaddr View Post
    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,

  19. #19
    Senior Member
    Join Date
    May 2016
    Posts
    115
    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

  20. #20
    Quote Originally Posted by DerekR View Post
    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..

  21. #21
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,942
    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.

  22. #22
    Quote Originally Posted by PaulStoffregen View Post
    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..

  23. #23
    Senior Member
    Join Date
    May 2016
    Posts
    115
    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.

  24. #24
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    195
    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.

  25. #25
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    19,942
    Quote Originally Posted by Blackaddr View Post
    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...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •