TDM frame based master

If you have a simple question and just want an answer.
Post Reply
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

TDM frame based master

Post by akp »

Hello

I have been using the lib_i2s tdm master for a while and it works great up to 48kHz or even 96kHz with the AVB reference software. However, I get some weird behaviour at 192kHz -- it seems to work OK, but some of the AVB code stops working (specifically the device loses PTP sync for some reason and goes back to PTP master from PTP slave). I am using 192kHz and a single 4 slot TDM lane. I don't get this behaviour with the I2S frame based master, even with 8 channels. Therefore I wonder if the more efficient implementation of the I2S frame based master might be the reason why.

Is there a plan to implement a TDM frame based master like the I2S one in lib_i2s? It seems like it shouldn't be too difficult for people familiar with the code. My knowledge of XMOS ins and outs is still pretty miserable so it's probably not a straightforward.

cheers
Adam


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

Post by infiniteimprobability »

Hi,
I would not be surprised if TDM master (lib_i2s) does not achieve 192kHz. It is only specified up to 48kHz / 16ch and uses a callback per channel. The reason we introduced i2s_frame was to increase performance (i2s_frame works up to 768kHz comfortably) by reducing the number of callbacks, which each have an overhead. It took a fair bit of work to write these because you have to understand the low level port buffering very well and carefully schedule each operation, so that you get maximum tolerance to slow call backs (which block the server until they hit the break; in the server/handler). While someone with the right knowledge may only take a few days to write a tdm_frame implementation, getting that properly tested (HW and simulator), adding a regression, example and documentation (+ review) and publishing takes much more time. I am not aware of a plan to do this in the short term.

One thing you could consider is to:

- use set_core_high_priority_on() before call tdm master to give it 1/5 of the tile MHz
- reduce the callback cases down to an absolute minimum to reduce pressure of the TDM loop timing..
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

Thanks, I tried your suggestions and not surprisingly I couldn't achieve reliable 4 ch/frame TDM @ 192kHz. Well, to be fair, the TDM is reliable but all the callbacks ruin something in the AVB/TSN code causing PTP sync lock (stops receiving PTP responses and reverts to PTP role Master after some time, maybe an hour with really lightweight callbacks).

Fortunately, I was able to hack the i2s_frame to basically get what I need out of it (128 BCLK/LRCLK ratio rather than 64 BCLK/LRCLK). It's not pretty and it only works as input not output, but that's OK for me at present.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Fortunately, I was able to hack the i2s_frame to basically get what I need out of it
Good work! Starting with i2s_frame and then basically adding more slots makes sense..
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

It turns out my loss of PTP problem wasn't with the old TDM master. With the existing TDM master I can support 1 x 8ch AVB stream comprised of 2 TDM lanes of 4ch each @ 192kHz (inputs only -- I haven't tested outputs). I found recording corruption on the Mac when I tried to use 2 x 4ch AVB streams and that went away when I reduced to a single 8ch stream.

The loss of PTP I referred to earlier occurs due to another software mod I made which -- I think -- caused the media clock "wordlen" to be too small of a value for the code to work correctly for some reason (I suppose it makes some internal software function operate too fast?) Anyway I needed to compute the MCLK/BCLK divider in the configure_clock_src_divide(clk_tdm_bclk, p_tdm_mclk, ...) rather than keeping it fixed at 1 (i.e. divide by 2). So for TDM4 @ 192kHz and 24.576MHz MCLK the MCLK/BCLK divider is set to 0 (i.e. divide by 1).

With what I know now I probably should have used a fixed 24.576MHz MEMs on my board rather than the CS2100CP then I wouldn't have to worry about the PLL drive on it for a talker only application. But at least with the CS2100CP I can use input stream derived clock in the future if I wish.
Post Reply