Stream Wordclock loses Lock

Technical questions regarding the XTC tools and programming with XMOS.
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Stream Wordclock loses Lock

Post by voodoosound »

Hi *,

I am using XMOS AVB Stack 6.4.1.
I have an AVB listener and talker with 2 channels per stream.
I have a wordclock output on the talker (which is no XMOS device), that I can trace with a scope.

If I trace SYNC_OUT /CLK_IN (of the CS2300 PLL) with a scope, I observe that the wordclock and SYNC_OUT are locked, but the SYNC_OUT wanders. Minimal.
As a result, I repeatedly lose the lock on the Media Clock, as well as on the audio output port of the listener.

SYNC_OUT is ~960Hz.

I have edited the define PTP_NEIGHBOR_PROP_DELAY_THRESH_NS from 800 to 1200 and back.
With no effect on SYNC_OUT.

Can anyone give me a hint, where I should look into?

BR,
Ck
Last edited by voodoosound on Thu Mar 26, 2015 11:41 am, edited 1 time in total.


voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

The timestamps revealed that the input and output data rates to and from the threads are constant.

Is it possible, that thread A filling the Media FIFO is slower than thread B emptying it?
How could I check that?
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

I think I found the problem, now I need a solution.

Please correct me if I am wrong.

SPDIF Biphase frequency should be 48000kHz * 32 Bit = 1,536MHz.
An AVTP packet every 125us constantly, with 6 samples is verified with Wireshark.
Which is the input rate of the output FIFO.

I measure (1,663 - 1,863)MHz on the wire.
Which is the output rate of the output FIFO.

The frequency is always to high. Average 14%.

How can that be?
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

I think I found the problem, now I need a solution.
That's good. What was that in the end? I'm not sure I understand - was it to do with gPTP synchronisation or a media clock recovery?
SPDIF Biphase frequency should be 48000kHz * 32 Bit = 1,536MHz.
An AVTP packet every 125us constantly, with 6 samples is verified with Wireshark.
Maximum biphasemark rate of SPDIF = fS x 32(bits per sample) x 2 (stereo) x2 (BMC) = 6,144,000Hz for 48KHz fs. But you wouldn't see that frequency unless every data bit was a 1, which is impossible (valid preambles cannot all be 1 etc.). So, using a frequency counter, on the wire you'd see somewhere between the max and half that rate.
Which is the input rate of the output FIFO
Which FIFO?
I measure (1,663 - 1,863)MHz on the wire.

Which is the output rate of the output FIFO.

The frequency is always to high. Average 14%.
I'm getting confused here - do you have an issue connecting SPDIF (in or out?) to the AVB ref design? I've connected it as an output to the listener, but not tried as an input to the talker - that would need some sort of clock recovery so that the talker media clock is sync'd to the incoming SPDIF stream.
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

That's good. What was that in the end? I'm not sure I understand - was it to do with gPTP synchronisation or a media clock recovery?
First I thought PDelay would have influenced the media clock. But it didn't.
Now I found out, that the AVTP samples to my listener have a constant rate of 8kHz (* 6 samples).
But not on the thread emptying the output FIFO. The result are audible and debug_print-able output FIFO buffer underflows.

Audio: Ok, then crackles, then glitches, then off, and starting again.
Std Out - FIFO fill level: Has locked 17 samples, loses lock with 6 samples.

possible cause?
1. Port buffering? Has huge impact on stability of the media clock server, but seems correct.
2. Timestamping? Seems correct...
3. PLL issue? ~960Hz, seems ok...
Maximum biphasemark rate of SPDIF = fS x 32(bits per sample) x 2 (stereo) x2 (BMC) = 6,144,000Hz for 48KHz fs. But you wouldn't see that frequency unless every data bit was a 1, which is impossible (valid preambles cannot all be 1 etc.). So, using a frequency counter, on the wire you'd see somewhere between the max and half that rate.
Yes, I was not really precise... I referred to one channel not two. (min 2*1.536MHz)
I now have observed, that audio is only played if I have a frequency above 2*2MHz.
Which FIFO?

output FIFO...
I'm getting confused here - do you have an issue connecting SPDIF (in or out?) to the AVB ref design? I've connected it as an output to the listener, but not tried as an input to the talker - that would need some sort of clock recovery so that the talker media clock is sync'd to the incoming SPDIF stream.
I'm having issues with SPDIF output. AVB Listener > SPDIF Out.
To be more specific, its AES3 not SPDIF.

No it is not the reference design, but tightly derived from it. Not using I2S though, which was not the best idea...
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Now I found out, that the AVTP samples to my listener have a constant rate of 8kHz (* 6 samples).
But not on the thread emptying the output FIFO. The result are audible and debug_print-able output FIFO buffer underflows.

Audio: Ok, then crackles, then glitches, then off, and starting again.
Std Out - FIFO fill level: Has locked 17 samples, loses lock with 6 samples.

possible cause?
1. Port buffering? Has huge impact on stability of the media clock server, but seems correct.
2. Timestamping? Seems correct...
3. PLL issue? ~960Hz, seems ok...
That makes sense - 8000 * 6 = 48000 for the talker. The listener should be media clock locked to the talker (assuming INPUT_STREAM_DERIVED - please confirm this is the case). That means the mclk that is generated by the listener will be in synch, and therefore the I2S rate (ie the rate at which it pulls samples out of the FIFO) is also in synch. So you shouldn't be pulling samples out at a faster rate if all is well... What does it look like if you monitor at the LR clocks from both talker listener on a scope? They should be locked..
I'm having issues with SPDIF output. AVB Listener > SPDIF Out.
To be more specific, its AES3 not SPDIF.

No it is not the reference design, but tightly derived from it. Not using I2S though, which was not the best idea.
OK - I patched SPDIF output right in the inner loop of I2S (audio_i2s.h) which worked, and doing this ensured the presentation time was preserved too because that's all handled by I2S/Media FIFO and media clock modules. I expect it's possible to make an SPDIF (or AES) module with the same interface as I2S (ie. pulls from output media FIFO) and that will behave the same. I did something similar for USB audio (so SPDIF replaced I2S). However, if you are not short of logical cores, it'd be easier to keep a dummy I2S in place and just tack in AES something like this..

Code: Select all

        if (k < num_out>>1) {
          unsigned int sample_out;
          sample_out = media_output_fifo_pull_sample(output_fifos[j+k*2],
                                                     timestamp);
          sample_out = sample_out << 8;

#if SPDIF_OUT
          if (k == 0) outuint(c_spdif_tx, sample_out);
          sample_out = sample_out >> 1;
#endif
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

infiniteimprobability wrote:What does it look like if you monitor at the LR clocks from both talker listener on a scope? They should be locked..
The listener stream clock, which is INPUT_STREAM_DERIVED, wanders slighty in relation to the talker wordclock.

The code is even quite simple. Pseudo code:

Code: Select all

start_port(p_dout)
clear_buf(p_dout)
lrck_tmr :> lrck_time

while(1){
      masterclock :> timestamp

      for( i=0;i<2;i++){
            sample_out = output_fifo_pull_sample(fifo[i], timestamp) // preambel code, vucp-data included

            set_preambel_vucp(sample_out)
            sample_out <<= 4

            lrck_time += LRCK_COUNTER_STEP;
            lrck_tmr when timerafter(lrck_time):> void;

            xor = biphase(xor, sample_out, p_dout)
      }
}
I just added the LRCK timer, and it makes it more stable, but it loses lock anyway.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Initial (and quick) thought - the rate at which this loop is throttled needs to be synchronous to the recovered media clock for it all to work.

Ideally, that would be backpressure/blocking from the sample output to your biphase function that would not execute until it had emptied it's buffer, which should be synchronous to the recovered clock - ie. biphase should be clocked by mclk.

It is clearly running quicker than that, and adding the wait in there helps slow it to closer to the media clock speed, but the timer wait is running from the asynchronous 100MHz clock, so I would expect either underflow or overflow after some time.

Have you connected the biphasemark buffered port to the mclk? (See SPDIF TX or ADAT TX transmit code to see how to do this)...
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

Yes,

p_dout is clocked by clock mclk / port ref_mclk, coming from the PLL...
voodoosound
Active Member
Posts: 63
Joined: Sat Oct 15, 2011 8:53 pm

Post by voodoosound »

I have:

Code: Select all

 #define MASTER_TO_WORDCLOCK_RATIO 512 
which results in a MCLK of 24,576MHz. For 48kHz this is too high. It should be 12,288MHz. (Please correct me if I am wrong)
It should be:

Code: Select all

 #define MASTER_TO_WORDCLOCK_RATIO 256 
If I set 256 I constantly have FIFO Overflows.
But I suppose here lies the root to my problem.

The media clock becomes more stable, when I use a virtual LRCK, which makes perfect sence here.
On an LRCK edge, it outputs on port d_out with 24,576MHz. Which is too fast and emptying the buffer more than it is filled.
Without waiting for a LRCK edge, the FIFO is empty faster, because the port output runs continuous.

I already tried to increase to FIFO buffer size, without effect.

What is the reason for the FIFO to overflow with:

Code: Select all

 #define MASTER_TO_WORDCLOCK_RATIO 256