Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 33 of 33

Thread: I2C problems with Teensy 3.6 and WM8731 codec

  1. #26
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Germany NRW
    ha! the cs42448 looks even "better" to try that - max i2c speed 100kHz..

  2. #27
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Colmar, France
    Quote Originally Posted by Frank B View Post
    lol, of course it's fun. but it requires fiddling as soon you change a little detail..
    Maybe I play with my cs42448 and use longer wires to see if I can reproduce the problem. Have to read the datasheet first, if it is a "slow" I2C device, too... It would be a chance to use my new o'scope
    The words "longer wires" are crucial - there it is where the root of all problems lies. The I2C standard had been invented by Philips to allow communication between ICs which would all sit on the same PCB or on different PCBs with a fixed and defined wiring, i.e. inside a TV. That was in times where 100kHz was still respectfully considered being RF or at least "high frequency", and where everything beyond 1GHz was still in the metaphysic domain. I'm pretty sure that the Philips engineers didn't think of hobbyists breadboarding i2c communication with "flying" Dupont wires, sometimes adding or removing ICs to or from the bus, and all that besides MCUs which are now clocked much higher than the "usual" 4MHz...

  3. #28
    Not strictly connected, but I managed to get the I2C and I2S working between Teensy 3.5 and WM8731. I'm not using any resistors in series on any of the data lines. See image in last post of this thread (scematic posted further up thread).

  4. #29
    Senior Member
    Join Date
    May 2016
    I've been working on this problem for the past few days. I bought a cheapo logic analyzer ($12 on Amazon) and it has been amazingly helpful in working out exactly what is going on!
    Here are my conclusions:
    1) With the resistors the unit is rock solid with the Wire library (with the exception below). I have run it for 24+ hours without error on its own with a Teensy 3.2 and a Teensy 3.6, and also when it was sharing the I2C bus with a SI5131A clock generator that was continuously generating a frequency sweep from 10 to 15 MHz - thus keeping the bus busy. No problems.
    2) with the Audio library I2S functions AudioInputI2S and/or AudioInputI2S active the results were a very mixed bag. With a simple sketch of an audio I2S pass-through, such as I posted in the first post of the thread, there were occasional NACK errors. Now the AudioControlWM8731 control does not recognize the I2C status reported by Wire.endTransmission, and any hard error can cause failure. So I modified and included the BALibrary, which repeats a I2C writes until the transmission is error free. This can repair occasional errors, and with this the pass-through code works most of the time.

    However, with a more complex Audio library based program (such as my SDR and music software) the WM8731 code generates NACK errors on EVERY transmission!!! This is where the logic analyzer became invaluable. You can see the lack of ACK in each data packet. Go back to a simpler program and the problem disappears. So I removed Audio blocks one at a time and found that inclusion of objects AudioInputI2S or AudioOutputI2S caused the problems when the codec.enable() function is called.

    Then I stumbled on another thread in the forum about exactly the same problem with the AK4558 codec here here. They also found the AudioInputI2S and AudioOutputI2S objects to cause problems with I2C. The conjecture there is that the fact that both include a call to begin() function in the class constructor is the culprit, and Blackaddr suggested taking the begin() function out of the constructor and forcing the user to call begin() after all initialization is complete. Unfortunately the thread stopped at that point.

    So I made my own version of those two Audio objects with empty constructors. The begin() function in each is already declare public. I modified my code to call codec.enable() near the begining of setup() and at the very end called myInput.begin() and myOutput.begin() at the very end of setup(). And that fixed it!!! The logic analyzer showed all NACK errors disappeared and the system worked.

    I have no idea what the interference between the I2C and the audio blocks is, or why the SGTL5000 is robust to the problem. Apparently it's not unique to the WM8731, it seems that the AK4558 has the same problem!

  5. #30
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    In the thread linked above, I had reported a trick for disabling and renabling the BCLK of the I2S bus. You can disable the bus, do your I2C config, then renable the I2S bus.
    // On the T3.6:
    CORE_PIN9_CONFIG = PORT_PCR_MUX(1); // disable the clock to stop the I2S
    // ...configure the codec...
    CORE_PIN9_CONFIG = PORT_PCR_MUX(6); // turn the I2S clock back on
    Alternatively if you do not need I2C and I2S running concurrently, then using custom I2S objects to defer their startup can solve the problem as well.

    For me, this was not acceptable because after the codec is configured and audio is running, I still need I2C to adjust codec parameters like headphone volume so I had to go the route of retry-on-failure. If you need simultaneous operation of I2C and I2S on the WM8731 and failures (and thus retries) were not acceptable, then I never found a solution using only typical pullups.

  6. #31
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    I'm working with this today, using a Teensy 3.6 connected to the MicroE-506 board, which has a mic input but the line in signals aren't connected on that board.

    I can sometimes reproduce the problem. Here's the code I'm running, which plans an octave scale of beeps. No input signals needed.

    #include <Audio.h>
    AudioOutputI2S      out;
    AudioSynthWaveform  wave;
    AudioConnection     c1(wave, 0, out, 0);
    AudioConnection     c2(wave, 0, out, 1);
    AudioControlWM8731  codec;
    float freq;
    void setup() {
      freq = 220.0;
    void loop() {
      freq = freq * 1.08333333;
      if (freq > 440.0) freq = 220.0;

  7. #32
    Senior Member
    Join Date
    May 2016
    Paul - Blackaddr and I found that the problem was much, much worse when I2S input/output is running... Like you I was able to run Audio stuff - with a few errors - without I2S...

    The reason for trying the WM8731 was that the SGTL5000 Audio board is still driving me crazy (after 2+ years) with random one-sample delays between the L/R channel in I2S inputs. It's not noticeable in normal music/audio work. This problem occurs either on program upload or power on/off (more prevalvent on upload) and once the problem establishes itself its there until a reboot. It completely destroys phase integrity in quadrature signal processing. Others have had the same problem in the context of SDRI submitted a bug report at the time, with no response. My conjecture is that the L-R frames in the I2S packets are getting confused either in the codec, or in the DMA software. I thought I'd try the WM8731 to see if I could help isolate the problem.

  8. #33
    Senior Member DD4WH's Avatar
    Join Date
    Oct 2015
    Central Europe
    Hi Derek,

    unfortunately I can confirm that the WM8731 (together with an STM32F4 / STM32F7) has exactly the same problem of an occasional random one sample delay. You are right, that is not very nice in the context of processing I & Q audio data, which has to be exactly 90 degrees out of phase . . .

    We called this phenomenon the "twin peak", because in the context of Software Defined Radio, you can observe a second peak in the spectrum display whenever this one sample delay occurs in the codec.

    The phenomenon is thus NOT restricted to a single model of codec. Additionally it is NOT restricted to a single production batch of codecs of the WM8731, because users of our SDR software have observed this phenomenon in several HUNDREDS of codecs of different age and origin.

    Bob Larkin has found a nice solution using cross correlations (reported here in the forum) to easily measure the phase difference between I & Q and -whenever this phenomenon occurs- to reset the codec until the problem is gone.

    I have used a somewhat different approach and built in an algorithm by Moseley & Slump to correct I & Q phase and amplitude imperfections which simultaneously allows to check the correct 90 degree phase difference.

    We have not found any other means to circumvent this problem than to reset the codec and the hope that the delay is gone . . .

    All the best,

    Frank DD4WH

Posting Permissions

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