Custom i2s in with simultaneous S/PDIF & USB out

Technical questions regarding the XTC tools and programming with XMOS.
yes2i2s
Experienced Member
Posts: 73
Joined: Tue Nov 24, 2015 4:06 pm

Custom i2s in with simultaneous S/PDIF & USB out

Post by yes2i2s »

Dear XMOS community. I have an "xCORE-200 Multichannel Audio Platform" development kit and would like to achieve the following:
 
An I2s signal of up to 48k / 24bit comes in to the xmos chip on one of it's I2s inputs at BCLK=64xfs, MCLK=256xfs (I can change these timings if necessary btw)
 
I'd like that signal to be converted to an S/PDIF output (that can run without the USB being connected to the chip, maybe that's standard anyway)
 
I would also like a copy of the I2s signal to be sent out to the USB port, so that a computer can record the signal when it's plugged in. And for these two outputs to be simultaneously running.
 
How do I do this? And are all the I2s lines broken out on this dev board? From the datasheet I can only see the data lines to and from the DAC/ADC are broken out, how do I get to the WCLK/BCLK/MCLK lines?
 
Any help would be very gratefully received!
 
Kind regards
 
Tom
Read




User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Dear XMOS community. I have an "xCORE-200 Multichannel Audio Platform" development kit and would like to achieve the following:

An I2s signal of up to 48k / 24bit comes in to the xmos chip on one of it's I2s inputs at BCLK=64xfs, MCLK=256xfs (I can change these timings if necessary btw)
That's fine - 48KHz 24b audio with 12.288MHz Mclk.
I'd like that signal to be converted to an S/PDIF output (that can run without the USB being connected to the chip, maybe that's standard anyway)
That's OK - you just need to copy the inputted I2S signal samples into SPDIF output. This can easily be done in the I2S task in the USB Audio reference design.
I would also like a copy of the I2s signal to be sent out to the USB port, so that a computer can record the signal when it's plugged in. And for these two outputs to be simultaneously running
.
This is what the standard in the ref design does.
How do I do this? And are all the I2s lines broken out on this dev board? From the datasheet I can only see the data lines to and from the DAC/ADC are broken out, how do I get to the WCLK/BCLK/MCLK lines?
Software-wise, you get the reference design from the website (need to register first), limit the sample rates to 48000 (MIN_FREQ, MAX_FREQ), set the MCLK to 12.288MHz (#define MCLK_48 (256 * 48000) and a few changes to get SPDIF to mirror what's coming in on I2S including:

outuint(c_spd_out, samplesIn[0]); /* Forward left sample to S/PDIF Tx thread */
outuint(c_spd_out, samplesIn[1]); /* Forward right sample to S/PDIF Tx thread */

You may also need to change the CODEC_MASTER define, depending on who is the I2S master, and think about who is the source of MCLK (like in any digital audio system).
Any help would be very gratefully received!
Also, you realise for what you want, any USB audio kit will do what you need? 2 channels at 48KHz and SPDIF out is not pushing the limits! You will likely need to cut data tracks (or remove jumpers in the case of the multichannel kit) and possibly the BCLK/LRCLK lines depending on who is the master.

All sounds very achievable with any of our kits, a few minor tweaks to the standard reference design and a bit of playing around..
yes2i2s
Experienced Member
Posts: 73
Joined: Tue Nov 24, 2015 4:06 pm

Post by yes2i2s »

Thanks that's great info.

We chose the multichannel kit because the other part of our product will also use this chip but requires the following:

2+ line-ins
SPDIF in
USB in
Microcontroller
1x I2S output @ same resolution as the input
1x I2S output restricted to a mx of 48k / 24-bit

I hope the last part is achievable, i.e a truncated copy of the input signal going out simultaneously.

The above means it made sense to use this kit to do both parts of the product including the simple I2S > SPDIF/USB.

I was planning to slave the XMOS as I have an existing MCLK in the system, although on the more elaborate input PCB I may master the XMOS if it makes more sense because it will be determining the input resolutions up to 384k.

I can see LRCLK/SCLK break outs on the multi channel kit so that should help, although I'm not sure whether they're for the input or output (or are they both linked running the same rate at all times?). I also spot MCLK and data pins so I can get to those no problem.

Thanks again in advance.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

I can see LRCLK/SCLK break outs on the multi channel kit so that should help, although I'm not sure whether they're for the input or output (or are they both linked running the same rate at all times
This is simply controlled by the CODEC_SLAVE define, which makes the CODEC the I2S slave (XMOS is master) if defined. The port directions and I2S generation code changes depending on this setting.

I strongly recommend finalising your MCLK architecture. The reference design operates on a single master clock which can be external (it's asynch usb audio). However when you are receiving SPDIF (which has a clock encoded within it) the reference design uses this as the MCLK reference by recovering the clock from the stream using software and the PLL. Unless you start thinking about ASRC (asynch sample rate conversion), XMOS will need to be the MCLK master when SPDIF rx is enabled.
GRSteeves
New User
Posts: 3
Joined: Tue Dec 13, 2016 11:13 pm

Post by GRSteeves »

Hello,
I am using the xCore 200 Multichannel Audio Platform, and I am running the default app: "app_usb_aud_xk_216_mc", but I am attempting to put the XMOS as Codec Slave by setting CODEC_MASTER = 1 in devicedefines.h.
However, when I compile, I get an error that this is not currently implemented.
Am I missing another setting somewhere?
At the end of the day I want to be able to send/receive TDM audio, but with an external device driving LRCLK & SCLK.

Thanks for your support!
yes2i2s
Experienced Member
Posts: 73
Joined: Tue Nov 24, 2015 4:06 pm

Post by yes2i2s »

Thanks

In this case I have an audio module which outputs a constant 3 wire I2s signal and MCLK pulse. Ideally that will drive the XMOS. I then only want XMOS to convert and output this to SPDIF and USB. On this particular part of the product there is no audio input coming from USB or SPDIF, only out.

It's purely I2s/MCLK > XMOS > SPDIF/USB independently & simultaneously.

First thing I will try is to edit the reference design such that I can hear my incoming I2s signal on the USB connected PC. I gather to do this I need to:

-Set the expected (incoming) MCLK rate (I will measure it with my scope to be sure I'm using the correct calculation)
-Set XMOS as slave device
-Cap the sample rate to 48k (although does the XMOS chip not detect the incoming I2S rate anyway? Do you need to set an incoming limit, seems unnecessary?)
-Wire the I2s lines in (I have already soldered headers to those pins so it's ready)

Cheers again

Tom
yes2i2s
Experienced Member
Posts: 73
Joined: Tue Nov 24, 2015 4:06 pm

Post by yes2i2s »

Okay so I limited the sample rate to 48k using customdefines, this seems to be reflected in Windows driver settings, I cannot choose higher than 48k now.

I then set CODEC_MASTER to 1 in devicedefines of module_usb_audio. What I noticed is that the I2s word clock line (LRCK) jumped from 88k to 44k when I did this.

I also set MCLK to 256 x fs in customdefines, but this made no difference to MCLK which is stuck at 22MHz, whether codec or XMOS is master this stays at 22MHz

Truth is I already have an external bit clock, word clock and master clock that I want to wire into this circuit, so how do I disable them on the MC audio board so I can plug my own lines in?

I take it by setting CODEC_MASTER I have initiated I2s master on the ADC, which I do not want to do as I have an external device to use instead. Am I right in assuming there is an I2c option somewhere putting the ADC in master mode when I change the CODEC_MASTER to 1. If so how do I disable this?

One more question. Where and in what file do I do the following suggestion you made for SPDIF transmit of I2S signal?:

outuint(c_spd_out, samplesIn[0]); /* Forward left sample to S/PDIF Tx thread */
outuint(c_spd_out, samplesIn[1]); /* Forward right sample to S/PDIF Tx thread */

Thanks!
yes2i2s
Experienced Member
Posts: 73
Joined: Tue Nov 24, 2015 4:06 pm

Post by yes2i2s »

I cheeted a bit to force the codec into slave mode while also putting xmos into slave mode by doing the following in audiohw.xc

#ifdef CODEC_MASTER
/* Note, only the ADC device supports being I2S master.
* Set ADC as master and run DAC as slave */
if(samFreq < 54000)
mode = 0x03; /* Single-speed Mode Master */
else if(samFreq < 108000)
mode = 0x03; /* Double-speed Mode Master */
else if(samFreq < 216000)
mode = 0x03; /* Quad-speed Mode Master */
#else
mode = 0x03; /* Slave mode all speeds */


So now the word clock and bit clock lines are quiet, I'm nearly there. But MCLK still reigns supreme at 22MHz and I need to shut it off so I can use my existing MCLK. The module supplying the audio signal is not capable of running in slave mode so I need to use it's MCLK for the XMOS chip. I don't need the ADC and have shut that off, I don't need the MCLK so need to shut that off.

Thanks!
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Well done - yes putting CODEC_MASTER in the define switches off drive from the XMOS chip but also setups up the ADC and DAC to drive them by doing a different I2C setup. Another option is to not allow the ADC/DAC to exit from reset (see audiohw.xc)- quick and easy way to get them off the lines. You would need to comment out the I2C writes though as you would get stuck there otherwise (it wouldn't ACK).

I think you may need to cut a track to get MCLK off the line. Cut it at the input to the NC7SZ157 mux so it works as a buffer to all of the MCLK recipiants (it needs to go to both tiles on the XMOS chip)..You'll also get better signal integrity as it uses series resistors to match the impedance and reduce reflections.
yes2i2s
Experienced Member
Posts: 73
Joined: Tue Nov 24, 2015 4:06 pm

Post by yes2i2s »

So just to clarify:

1) the MCLK on this board is an independent permanent feature? There is no way to stop it using software and use an external clock, without cutting the tracks?

2) For test purposes do you deem my code edit for setting the ADC into slave mode sufficient for now? It has silenced the bit and word clock it was outputting so I figured that was good enough.

3) Can you be clear on where I need to cut a track, I seriously do not want to mess that up on this expensive test kit? Maybe an image showing the best location. Will this cause the on-board clock to sync with my external clock and feed all the chips?

4) Where do I need to put these lines of code:

outuint(c_spd_out, samplesIn[0]); /* Forward left sample to S/PDIF Tx thread */
outuint(c_spd_out, samplesIn[1]); /* Forward right sample to S/PDIF Tx thread */

Thanks very much!

Tom