Page 1 of 1

1024Fs MCLK with UAC1 on XU208

Posted: Thu May 25, 2017 5:02 pm
by Silas
Distorted audio in UAC1 mode on XU208 when using 1024*MCLK with sw_usb_audio-[sw]_6.15.2rc1
The standard build 512*MCLK version works fine in both USB Audio Class 2 and Class 1.

If I instead run at 1024*MCLK audio output works fine for UAC2, but changing to UAC1 to test AUDIO_CLASS_FALLBACK the audio output is distorted.

The clocks value in buffer() seems far to high (it doesn't match the value seen when running at 512*MCLK), which is used to set both g_speed and fb_clocks. If I set the clocks value here manually for the incoming sample rate then the audio is fine, so there seems to be some issue calculating the number of MCLK ticks in the SOF period that is then used to calculate the clocks value used when sofCount == 128 in buffer().
For UAC1 I can manually put in values here for the limited sample frequency cases available for audio class fallback, but it would be nicer to have it working from the calculated value.

Any suggestions on how to fix this appreciated.

Re: 1024Fs MCLK with UAC1 on XU208

Posted: Tue May 30, 2017 10:11 am
by Silas
So, in usb_buffer.xc

Code: Select all

                    /* Reset counts based on SOF counting.  Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll
                     * We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */
                    if(sofCount == 128)
                    {
                        clockcounter += mod_from_last_time;
                        clocks = clockcounter / masterClockFreq;
                        mod_from_last_time = clockcounter % masterClockFreq;
                        clocks <<= 6;
seems to get the wrong value for clocks in FS mode at 1024*MCLK, but is ok for 512*MCLK

Until I can find why, I have fixed by making

Code: Select all

                        clocks = ((sampleFreq * 16384) / 1000) << 2;
for the specific case of 1024*MCLK and XUD_SPEED_FS.

Re: 1024Fs MCLK with UAC1 on XU208

Posted: Thu Jun 01, 2017 1:37 pm
by infiniteimprobability
Thanks for raising this... It may be a bug if section 5.12.4.2 of the USB spec is not being met.

I (and others) have had 1024x MCLK running fine but personally I have only had it under UAC2. UAC1 runs at full speed so the maths is different, including the representation of the fixed point feedback value. It's possible there is an overflow in the calculation in FS mode.

Your workaround will unfortunately will cause glitches - there is no accounting for the asynchronous relationship between clocks. So you will get an occasional under/overflow depending on your actual MCLK vs reported samples required.

There are going to be some large numbers in there at fullspeed USB and 49.152MHz clock but it uses long longs, so should be OK...

What values are you actually seeing? Is the calculation wrong for all sample rates at 1024x MCLK/ Full speed?

Re: 1024Fs MCLK with UAC1 on XU208

Posted: Thu Jun 01, 2017 3:14 pm
by infiniteimprobability
I had a thought..

Each SOF the code gets the port counter value and subtracts the value from last time around. However, the port counter is only 16bits. Clocking this at 49.152MHz for 1 millisecond (FS SOF period) could be problematic unless you are very careful about overflow and signs..

Would you be able to print out the variable *count* to see if your MCLK count is right? (should be about 49152)

Re: 1024Fs MCLK with UAC1 on XU208

Posted: Fri Jun 02, 2017 4:16 pm
by Silas
You are correct about it being the port counter.
Replacing

Code: Select all

                    int count = (int) ((short)(u_tmp - lastClock));
with

Code: Select all

                    unsigned count;
                    if (u_tmp < lastClock)
                        count = (unsigned) ((unsigned)(u_tmp + (unsigned)(0x10000 - lastClock)));
                    else
                        count = (unsigned) ((unsigned)(u_tmp - lastClock));
seems to work and fixes the clocks count so that the playback is no longer distorted.

Re: 1024Fs MCLK with UAC1 on XU208

Posted: Fri Jun 02, 2017 4:37 pm
by infiniteimprobability
seems to work and fixes the clocks count so that the playback is no longer distorted.
Nice work! I'll add a bug against the reference design with your fix. Thanks!