AudioInputI2Sslave to SGTL5000 analog output?

Status
Not open for further replies.

drewandre

New member
I'm working on a version of PJRC's audio shield that replaces the SD card with the RN52 bluetooth audio module -- RN52 controls both clock signals and outputs I2S data to Teensy 3.2 pin 13 using AudioInputI2Sslave. I'm having trouble understanding how to generate an analog output.

I understand Teensy cannot act as a slave and a master in the context of the audio library, so I don't expect Teensy to every handle any I2S output at all. I read on the SGTL5000 datasheet, though, that the SGTL5000 audio switch can route "Any single input [...] to any single or multiple outputs". If I have an I2S signal from the bluetooth module coming into a Teensy running the audio library (up to this point totally separate from the SGTL5000 module), can I then also split that signal off to the SGTL5000's I2S input (along with both clocks) and control SGTL5000 routing from the audio library using I2C?

In other words, I was hoping I could use an SGTL5000 input like const int myInput = AUDIO_INPUT_I2S; and then somehow instruct the SGTL5000 module to route that to its analog output?

Happy to share code and/or eagle files!
 
Last edited:
First let's be clear about what I2S master and slave mode means. It's not about input or output. Master mode means a device generates & outputs the clock signals. Slave mode means the device receives the clocks. An I2S slave can be a transmitter, a receiver, or even both at the same time (assuming it has 2 signal pins). Slave mode merely means that it will transmit and/or receive bits at the moments when the other device sends clock pulses.

Normally I2S is connected from 1 master to 1 slave. All the signals are unidirectional and there's no acknowledgements or other handshaking like with I2C, so you could connect 1 I2S master transmitter to several I2S slave receivers. In such a connection, only one of the I2S slaves could transmit data to the I2S master. All the signals (data & clocks) are unidirectional, so you can connect 1 output to multiple inputs, but obviously you need to avoid the conflict of connecting 2 outputs together.

But just because 2 devices are I2S doesn't necessarily mean they're compatible. This isn't like USB where settings are automatically discovered, but more like traditional serial where you have to make sure both sides use the same settings (number of data bits, stop bits, etc).

Sample rate (the LRCLK frequency) is the main setting to consider. The Teensy Audio library works at 44.1 kHz. When in I2S master mode, it's actually just slightly above, at 48 MHz / 1088 to be precise (or at least as precise as the 16 MHz crystal and PLL inside the chip). When in I2S slave mode, the audio library will attempt to run at whatever clock speed the I2S master sends, but all the code is written to assume 44.1 kHz.

I don't know much about this RN52 module. I can tell you there was a thread some time ago on this forum where someone tried to use another module (perhaps it was from FTDI?) which turned out to have a (not so well documented) maximum sample frequency of 16 kHz. So even though all the other I2S stuff should have been ok, it simply would not work at 44.1 kHz.

I2S slave mode running on Teensy has the caveat that it won't run perfectly in sync with the DAC & ADC & PWM objects. With I2S master mode, you can use those pins for other signals in & out and the entire library will run perfectly in sync at 44.1167 kHz. But in slave mode, combining those non-I2S objects will result in different parts of the library attempting to run at different speeds. Surprisingly a couple people have said this actually worked out ok for them, so the result isn't always total chaos, but it could suffer from clicks or glitches or other audible artifacts. Not an issue if you're not going to use those non-I2S inputs & outputs, but mentioning it anyway...

While a lesser concern than sample rate, another pesky I2S detail to consider is the ratio of BCLK to LRCLK. Some I2S devices, especially MEMS microphones, have a rigid requirement for a ratio of 64. Early on, Teensy's I2S master mode used 32. It was changed some time ago to 64, at least for the stereo version, so those MEMS mics now work. I believe the quad channel version still uses 32, but someday it will likely be updated to also use 64. I'm not sure which one of the I2S slave mode is currently using. It's one of the least used parts of the audio library, and honestly I have only ever tested it with the WM8731 chip. Actually testing & documenting it at different BCLK/LRCLK ratios is on my low priority to-do list (where "low priority" means unlikely to happen anytime soon, if ever). The best I can tell you right now is the I2S slave mode does work with the WM8731 chip running in I2S master mode.
 
Thanks Paul, that clears up questions I didn't know I had. Always appreciate the detail.

When I asked if I could "also split that signal off to the SGTL5000", I meant physically connect two wires to each of the RN52's BCLK, LRCLK, and SDOUT outputs, then connect those two streams to both the I2S input on the Teensy and the 12S input on the SGTL5000. The SGTL5000 and Teensy are totally separate apart from their I2C connection. Teensy doesn't do any audio routing and has no audio output -- just does some audio analysis and SGTL5000 control over I2C.

SGTL5000 (slave) receives the exact same BCLK, LRCLK, and SDOUT signals from the RN52 (master) as the Teensy does. While using the teensy audio library to control SGTL5000 settings over I2C, am I able to send raw commands to the module to internally route its I2S input directly to its line out? I think ideally Teensy would send a one-time command on startup like (but not exactly) "I2S_IN -> DAC -> LINEOUT, HP_OUT" to just set-it-and-forget-it, and then use the audio library to control the SGTL5000 module and perform analyses on the RN52 I2S input.

I won't be using non-I2S inputs and outputs in my application, but that's good to know if others want to use this board. The ratio of BCLK to LRCLK I will look into -- so far it has not been an issue when reading the RN52's I2S output.

Apologies if I'm totally misunderstanding the data flow here... this has been a bit difficult to wrap my head around but thankfully the RN52 module seems to be directly compatible with the SGTL5000's defaults -- 44.1 or 48 kHz sample rate and a 24-bit sample depth (optionally 32-bit). I was able to plug it right in after only changing the internal audio routing to I2S.

*EDIT* Control over SGTL5000 I2S input (adding a filter, gain settings) may be of scope for this question since I don’t think it would initialized as an audio input object. I can start a new post if that ends up being an issue in the context of this project.
 
Last edited:
Cool. RN52 can only operate as master and the module can't output MCLK... but hopefully I can leave that floating for now or use a clock multiplier while I source a BT module that does output MCLK. Looks like master clock output isn't a popular feature on BT audio modules.

I know the datasheet notes "When the clocks are in slave mode, they must be synchronous to SYS_MCLK", but is providing an MCLK signal in the context of the audio routing mentioned in my first post absolutely necessary? Especially if right now I'm having no issues (as far as I can tell) reading in I2S data from the RN52 module and running an FFT on that stream. The DAC's digital to analog conversion definitely requires a master clock input though?

Even if it results in out-of-sync audio or some strange effects I'm hoping to just output something so I can confirm my I2S input is internally routed to the DAC's audio output while I hunt around for a BT module with a master clock output.

Looks like I just need to send something like modify(CHIP_SSS_CTRL, DAC_SELECT, 0x0001) to route the I2S input to the DAC analog output, but that isn't working so I'd like to iron out these MCLK questions before I dive into debugging the routing commands.

Thanks Paul!
 
The SGTL5000 chip absolutely requires MCLK. It stays in a low power reset mode until MCLK, so you can't even communicate with it over I2C until it sees pulses on MCLK.

I've never tried giving it a clock that isn't in sync with BCLK, so I don't know whether that would work.
 
Status
Not open for further replies.
Back
Top