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

Thread: Teensy in Raspberry I2S based digital chain.

  1. #1
    Junior Member
    Join Date
    Sep 2018
    Posts
    18

    Teensy in Raspberry I2S based digital chain.

    Hello to all!
    I need some help with some I2S connection problems. I am testing some DSPs by inserting them into my (digital) audio chain.

    The starting point is:
    Raspberry PI3+ (Master) >
    Allo Isolator > (Passes Clocks according to Slave/Master direction)
    Kali Recklocker (Input Slave, Output Master) >
    TDA1543 based DAC

    I have been able to insert a Minisharc DSP (and it worked):
    Raspberry PI3+ (Master) >
    Minisharc DSP > (Input Slave, Output Master)
    Allo Isolator >
    Kali Recklocker (Input Slave, Output Master) >
    TDA1543 based DAC

    I am now trying to insert a Teensy 3.6 in place of the Minisharc:
    Raspberry PI3+ (Master) >
    Teensy 3.6 > (Input Slave, Output Slave)
    Allo Isolator >
    Kali Recklocker (Input Slave, Output Master) >
    TDA1543 based DAC

    Due to the fact that Teensy is Input and Output Slave, both the Kali Reclocker and Teensy are sharing the Clocks coming from Raspberry.
    The Teensy has been simply programmed to patch the I2S (stereo) signal through. (see picture)
    The Result is that only one specific channel is playing. Always same speaker is playing whichever channel I disable with a comment.
    The oscilloscope is the WCLK and BCLK Output from Raspberry: there are 32 bits per word cycle, so I would say BCLK is 1.4112 Mhz (44100*32).
    My understanding is that Teensy would be compatible with this I2S format ?
    Any ideas what is going on ?
    Thanks
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	20180907_192044.jpg 
Views:	23 
Size:	207.0 KB 
ID:	14682   Click image for larger version. 

Name:	20180907_190216.jpg 
Views:	20 
Size:	115.5 KB 
ID:	14683  

    Click image for larger version. 

Name:	20180907_190206.jpg 
Views:	18 
Size:	116.3 KB 
ID:	14684  
    Last edited by Bart11; 09-07-2018 at 06:57 PM.

  2. #2
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,347
    Quote Originally Posted by Bart11 View Post
    The oscilloscope is the WCLK and BCLK Output from Raspberry: there are 32 bits per word cycle, so I would say BCLK is 1.4112 Mhz (44100*32).
    My understanding is that Teensy would be compatible with this I2S format ?
    Any ideas what is going on ?
    Thanks
    maybe because I2S audio library is 64 bit per word frame?

  3. #3
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Yes, that must be the problem. Which begs the question: how do I modify the audio library?

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    I2S stereo (master) does use 64 bits per frame. Long ago it was 32 bits per frame, but was changed to 64 for compatibility with the MEMS mics.

    I2S quad channel (master only) is still 32 bits per frame. Someday it too will be updated to 64, but as of verson 1.43 it's still 32.

    However, in slave mode, whatever device you connect to Teensy is in control of the clocks. Teensy has no choice but to (try to) work with whatever ratio it uses.

  5. #5
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Hello Paul,
    ...so you are implying that (in slave mode) Teensy should be working correctly even with 32bits/frame and that the problem lies somwhere else ?
    (I am feeding the clocks from RPI)
    Thanks
    B.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    I don't know. The only testing I've done with slave mode is the WM8731 chip using this example.

    https://github.com/PaulStoffregen/Au...1MikroSine.ino

  7. #7
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,347
    Quote Originally Posted by Bart11 View Post
    Hello Paul,
    ...so you are implying that (in slave mode) Teensy should be working correctly even with 32bits/frame and that the problem lies somwhere else ?
    (I am feeding the clocks from RPI)
    Thanks
    B.
    maybe by changing
    Code:
    	dma.TCD->SADDR = (void *)((uint32_t)&I2S0_RDR0 + 2);
    to

    Code:
    	dma.TCD->SADDR = (void *)((uint32_t)&I2S0_RDR0);
    in the "input_i2s.cpp" file of the audio library (inside void AudioInputI2Sslave::begin(void))
    Teensy should work by taking the lower two bytes of the I2S port

  8. #8
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Thanks for the help, I'll try it and let you know.
    (The reason I am so keen to wire up the teensy is that it can only work on 44.1khz and does not perform Asynchronous Resampling. What some percieve as a limit to me is a great advantage! My experience is that ASRC degrades sound.)

  9. #9
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,347
    Quote Originally Posted by Bart11 View Post
    Thanks for the help, I'll try it and let you know.
    (The reason I am so keen to wire up the teensy is that it can only work on 44.1khz and does not perform Asynchronous Resampling. What some percieve as a limit to me is a great advantage! My experience is that ASRC degrades sound.)
    You may know, that it is (relatively) easy to modify the audio functionality to work with any sampling frequency you want by adding some functions to your sketch (i.e. without touching the audio library.

  10. #10
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Will keep this in mind. Thanks for the tip.
    Will try the code change first and report asap.

  11. #11
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Ps at this point I will really look into this. The I2S protocol should work even if there is a different word length between transimtter and receiver. If I am transmitting 16 bits, the receiver should be able to handle this even if it is expecting 32 bits. Maybe I wired wrongly. Will re-check everything and come back.

  12. #12
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Quote Originally Posted by WMXZ View Post
    maybe by changing
    Code:
    	dma.TCD->SADDR = (void *)((uint32_t)&I2S0_RDR0 + 2);
    to

    Code:
    	dma.TCD->SADDR = (void *)((uint32_t)&I2S0_RDR0);
    in the "input_i2s.cpp" file of the audio library (inside void AudioInputI2Sslave::begin(void))
    Teensy should work by taking the lower two bytes of the I2S port
    Hello !
    I have repeated the experiment by placing the Teensy between Kali reclocker and the TDA1543 chip.
    I have modified the "input_i2s.cpp" as per your instructions.
    Still, only one channel is playing: the output Data line is active only when WCLK is LOW.
    There is something interesting going on though ! If I comment (disable) one of the two AudioConnectios, only half of the samples (of the Single playing channel) appear in the output.
    If I reverse the comments, data appears on the complementary half (of the playing channel). (Please note the pictures)
    I would guess this has to do with the output_i2s part of the equation. The Teensy is definitely providing Left and Right Input channel data to the Left Output channel.
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	20180909_175735.jpg 
Views:	23 
Size:	71.6 KB 
ID:	14693   Click image for larger version. 

Name:	20180909_181602.jpg 
Views:	24 
Size:	65.5 KB 
ID:	14694  

    Click image for larger version. 

Name:	20180909_181705.jpg 
Views:	23 
Size:	67.2 KB 
ID:	14695  

  13. #13
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Quote Originally Posted by PaulStoffregen View Post
    I2S stereo (master) does use 64 bits per frame. Long ago it was 32 bits per frame, but was changed to 64 for compatibility with the MEMS mics.

    I2S quad channel (master only) is still 32 bits per frame. Someday it too will be updated to 64, but as of verson 1.43 it's still 32.

    However, in slave mode, whatever device you connect to Teensy is in control of the clocks. Teensy has no choice but to (try to) work with whatever ratio it uses.
    Hello !

    I have checked what I2S bus specifications states about different word length compatibility. In theory I2S should work whatever the word length:

    3.1 Serial Data
    Serial data is transmitted in two’s complement with the MSB first.
    The MSB is transmitted first because the transmitter and receiver
    may have different word lengths. It isn’t necessary for the transmitter
    to know how many bits the receiver can handle, nor does the
    receiver need to know how many bits are being transmitted.
    When the system word length is greater than the transmitter word
    length, the word is truncated (least significant data bits are set to ‘0’)
    for data transmission. If the receiver is sent more bits than its word
    length, the bits after the LSB are ignored. On the other hand, if the
    receiver is sent fewer bits than its word length, the missing bits are
    set to zero internally. And so, the MSB has a fixed position, whereas
    the position of the LSB depends on the word length. The transmitter
    always sends the MSB of the next word one clock period after the
    WS changes.


    https://www.sparkfun.com/datasheets/...rds/I2SBUS.pdf

  14. #14
    Member houtson's Avatar
    Join Date
    Aug 2015
    Location
    Scotland
    Posts
    34
    Quote Originally Posted by WMXZ View Post
    You may know, that it is (relatively) easy to modify the audio functionality to work with any sampling frequency you want by adding some functions to your sketch (i.e. without touching the audio library.
    WMXZ - do you have any links or details as to how to do this (change audio lib sampling frequency), thanks

  15. #15
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,347
    Quote Originally Posted by houtson View Post
    WMXZ - do you have any links or details as to how to do this (change audio lib sampling frequency), thanks
    Sorry, I was on travel,
    Have a look in https://github.com/WMXZ-EU/microSoundRecorder how to mix up basic audio-library functionality and own modification
    (OK, there is much more in it, but maybe it helps as starting point)

  16. #16
    Member houtson's Avatar
    Join Date
    Aug 2015
    Location
    Scotland
    Posts
    34
    Quote Originally Posted by WMXZ View Post
    Sorry, I was on travel,
    Have a look in https://github.com/WMXZ-EU/microSoundRecorder how to mix up basic audio-library functionality and own modification
    (OK, there is much more in it, but maybe it helps as starting point)
    Walter - microSoundRecorder looks great - your coding ability and understanding of Teensy surpasses mine by a mile or 10 (just graduating from Arduino to VSCode).

    I very roughly follow what you are doing to change the sample rates with the PDB timer and then matching I2S.

    For my immediate needs (slowing down audio sampling for an effect) I've ended up just matching successive samples to simulate a lower sampling rate.

    I will definitely come back microSoundRecorder when I get a bit of time to look at how to do it properly - thanks for the point in the right direction.

  17. #17
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    Quote Originally Posted by Bart11 View Post
    I have repeated the experiment by placing the Teensy between Kali reclocker and the TDA1543 chip.
    I have modified the "input_i2s.cpp" as per your instructions.
    Still, only one channel is playing: the output Data line is active only when WCLK is LOW.
    There is something interesting going on though ! If I comment (disable) one of the two AudioConnectios, only half of the samples (of the Single playing channel) appear in the output.
    If I reverse the comments, data appears on the complementary half (of the playing channel). (Please note the pictures)
    I would guess this has to do with the output_i2s part of the equation. The Teensy is definitely providing Left and Right Input channel data to the Left Output channel.
    I'm trying to understand what I should do here to reproduce this problem.

    As I understand, you've got a non-Teensy I2S master sending data with BCLK/LRCLR ratio of 32. Is the Teensy 3.6 running just a simple program with I2S slave input & output connected to each other, so the output should be the same as the input (but slightly delayed)? Or is something more complex running on the Teensy? Are these scope pictures just watching Teensy's I2S TX pin and the BCLK signal arriving from other hardware? Or something else?

    Really, my main question is what should I wiring up here on my workbench to try to recreate this problem?

    The quad channel I2S still uses BCLK/LRCLK ratio of 32. Maybe I could use another Teensy running quad channel output in master mode as a stand-in for the non-Teensy hardware?

  18. #18
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Quote Originally Posted by PaulStoffregen View Post
    I'm trying to understand what I should do here to reproduce this problem.

    As I understand, you've got a non-Teensy I2S master sending data with BCLK/LRCLR ratio of 32. Is the Teensy 3.6 running just a simple program with I2S slave input & output connected to each other, so the output should be the same as the input (but slightly delayed)? Or is something more complex running on the Teensy? Are these scope pictures just watching Teensy's I2S TX pin and the BCLK signal arriving from other hardware? Or something else?

    Really, my main question is what should I wiring up here on my workbench to try to recreate this problem?

    The quad channel I2S still uses BCLK/LRCLK ratio of 32. Maybe I could use another Teensy running quad channel output in master mode as a stand-in for the non-Teensy hardware?

    Hello Paul,
    thanks for your reply. Your assumptions are all correct.
    * Yes, the Raspberry RPI3 was master sending data with BCLK/LRCLK ratio of 32. (i.e. two words, each word containing 16 bits). I have Volumio installed and playing music 44.1Khz WAV files (CD Red Book).
    * Yes, the Teensy was running ONLY the code I listed above. It was just a test to see if I can get data thorugh the Teensy without any changes whatsoever. Output should be same as Input.
    * Yes BCLK and LRCLK are coming from the Raspberry, while the output is Teensy's TX pin. I can take another picture comparing TX and RX if you wish.
    My setup was:
    RPI pin 35 to Teensy pin 23 LRCLK
    RPI pin 12 to Teensy pin 9 BCLK
    RPI pin 40 DOUT to Teensy pin 13 RX
    RPI pin 39 to Teensy GND
    You would be measuring Teensy pin 22 TX
    Regarding the use of the quad channel, it is not exactly clear to me how it transmits data. If the BCLK/LRCLK ratio is 32, I would assume it uses two LRCLK cycles to transmit all four channels in one tap. I... don't think we could test it that way.
    I can do more experiments if you wish. Today I was trying to connect another player with BCLK/LRCLK = 64 but I did not get any signal out.

  19. #19
    Junior Member
    Join Date
    Sep 2018
    Posts
    18

    32 bit words

    This would be the input from a Player with BCLK/LRCLK ratio of 64. No signal on Teensy's TX at the moment. Will repeat.
    In the photo It is nicely visible that only 16 bits of the 32 available are transmitted.
    (LRCLK and RX)
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	20180923_173930.jpg 
Views:	17 
Size:	55.2 KB 
ID:	14787  

  20. #20
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    To reproduce the problem using two Teensies, I would do the following:
    Teensy1 transmits whatever WAV using I2S master mode as output. Teensy2 would have I2S Input slave and I2S Ouput slave (the code I've listed above)
    Connect pins 9 together.
    Connect pins 23 together.
    Teensy1 pin 22 goes to Teensy2 pin 13
    Connect GNDs together.
    On Teensy2 pin 22 (TX) you should have the same output (delayed) as from Teensy1 pin 22 (TX)
    Teensy2 should be transparent with Teensy1 acting as master.
    I cannot try this because I only own 1 Teensy

  21. #21
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    Quote Originally Posted by Bart11 View Post
    This would be the input from a Player with BCLK/LRCLK ratio of 64. No signal on Teensy's TX at the moment.
    Did you undo the edit (msg #7) to the I2S code for this test? If you have that change in the code, then Teensy will be retransmitting the low 16 bits.

  22. #22
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Yes, it's back to original !

  23. #23
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    I've got it wired up on my desk right now, with BCLK/LRCLK ratio of 64. It seems to be working. I can't reproduce the no-data-output problem.

    Here's the hardware, using a Teensy 3.2 as I2S master transmitting to a Teensy 3.6 as I2S slave. The connections are exactly as you described in msg #20.

    Click image for larger version. 

Name:	DSC_0220_web.jpg 
Views:	25 
Size:	175.5 KB 
ID:	14794

    Click image for larger version. 

Name:	DSC_0222_web.jpg 
Views:	22 
Size:	126.9 KB 
ID:	14795

    Here is what I see on my oscilloscope. The green trace is the data from Teensy 3.2 (pin 22) to Teensy 3.6 (pin 13) and the red trace is the output from Teensy 3.6 (pin 22). I match wire colors to the oscilloscope prode & trace colors, so hopefully it's easy to see.

    Click image for larger version. 

Name:	file.png 
Views:	23 
Size:	63.8 KB 
ID:	14796

    This is the code I ran on the Teensy 3.2 to transmit data as I2S master on only the left channel.

    Code:
    #include <Audio.h>
    
    AudioSynthWaveformSine   sine1;          //xy=119,137
    AudioOutputI2S           i2s1;           //xy=280,136
    AudioConnection          patchCord1(sine1, 0, i2s1, 0);
    
    void setup() {
      AudioMemory(10);
      sine1.frequency(440);
      sine1.amplitude(0.9);
    }
    
    void loop() {
    }
    This is the code I ran on the Teensy 3.6, to receive and retransmit the data in I2S slave mode.

    Code:
    #include <Audio.h>
    
    AudioInputI2Sslave       i2sslave1;      //xy=129,136
    AudioOutputI2Sslave      i2sslave2;      //xy=311,136
    AudioConnection          patchCord1(i2sslave1, 0, i2sslave2, 0);
    AudioConnection          patchCord2(i2sslave1, 1, i2sslave2, 1);
    
    void setup() {
      AudioMemory(10);
    }
    
    void loop() {
    }

  24. #24
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,606
    I changed the Teensy 3.2 to transmit with BCLK/LRCLK ratio of only 32, by using the quad channel output. This is with Teensyduino 1.44 on Arduino 1.8.7 (at some point in the future quad I2S will become a ratio of 64 like stereo is, but for 1.44 it's still a ratio of 32).

    This is the code I ran on the Teensy 3.2. I only changed "AudioOutputI2S" to "AudioOutputI2SQuad".

    Code:
    #include <Audio.h>
    
    AudioSynthWaveformSine   sine1;          //xy=119,137
    AudioOutputI2SQuad       i2s1;           //xy=280,136
    AudioConnection          patchCord1(sine1, 0, i2s1, 0);
    
    void setup() {
      AudioMemory(10);
      sine1.frequency(440);
      sine1.amplitude(0.9);
    }
    
    void loop() {
    }
    The Teensy 3.6 is running the same code, copying I2S input to output using slave mode.

    Here's what I see on my oscilloscope.

    Click image for larger version. 

Name:	file.png 
Views:	25 
Size:	67.8 KB 
ID:	14797

    I can't seem to reproduce the problem of the left channel appearing on every other output cycle.

  25. #25
    Junior Member
    Join Date
    Sep 2018
    Posts
    18
    Hello Paul,
    that was great help. At this point I really wonder where the problem might lie. I will try to repeat this setup and see what comes out.
    Thanks for now !
    B.

Posting Permissions

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