USB Audio 2.0 , custom HW + custom SW

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

USB Audio 2.0 , custom HW + custom SW

Post by lilltroll »

I'm trying to start USB Audio 2.0 on a custom hardware, with a custom audio thread interacting with the decouple thread, also using a custom main(), and not the one from the module_usb_audio.
Right now, I can make the USB device enumerate and show up in Audio Spy, but nothing more.
USBdump.png
From (custom) main()

Code: Select all

 on stdcore[CORE_A]:{
	        XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT]={ XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO};
	        XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN]={ XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO, XUD_EPTYPE_ISO};
	        par{
	            XUD_Manager(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN, c_sof, epTypeTableOut, epTypeTableIn, null, null, 1, XUD_SPEED_HS, XUD_PWR_BUS);
	            { set_thread_fast_mode_on(); Endpoint0( c_xud_out[ENDPOINT_NUMBER_IN_CONTROL], c_xud_in[ENDPOINT_NUMBER_IN_CONTROL], c_aud_ctl, null, null); }
	            {set_thread_fast_mode_on(); decouple(c_mix_out , null , c_buff_ctrl);}
	            buffer(c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO], c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK] ,  c_sof, c_aud_ctl, p_for_mclk_count ,c_buff_ctrl );
	            audio_custom(c_mix_out);
	        }
	    }
Custom audio thread

Code: Select all

unsigned static deliver( chanend c_out){
    unsigned samples=0;
    while (1)
        {
            outuint(c_out, 0);

            /* Check for sample freq change or new samples from mixer*/
            if(testct(c_out))
            {
                unsigned command = inct(c_out);
                return command;
            }
            else
            {
    #ifndef MIXER // Interfaces straight to decouple()
                (void) inuint(c_out);
    #pragma loop unroll
                for(int i = 0; i < NUM_USB_CHAN_IN; i++)
                {
                    outuint(c_out, 0);
                }

    #pragma loop unroll
                for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
                {
                    (void) inuint(c_out);
                }
    #else
    #pragma loop unroll
                for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
                {
                    (void) inuint(c_out);
                }

    #pragma loop unroll
                for(int i = 0; i < NUM_USB_CHAN_IN; i++)
                {
                    outuint(c_out, 0);
                }
    #endif
            }
            samples++;
            if(samples!=0)
                printchar('s');
        }
        return 0;
    }

void audio_custom(chanend c_out){
    unsigned command , curSamFreq=44100;
    unsigned firstRun = 1;
    unsigned numBits = 64;
    unsigned mClk , divide ,dsdMode ,curSamRes_DAC;
    //printstrln("Starting USB audio");

    while(1){
        mClk = MCLK_441;
        if(!firstRun){
            if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU) && command)
                outct(c_out, XS1_CT_END);
        }
        firstRun=0;

        command = deliver(c_out);

        if(command == SET_SAMPLE_FREQ)
                curSamFreq = inuint(c_out);
            else if(command == SET_STREAM_FORMAT_OUT){
                /* Off = 0 , DOP = 1 Native = 2*/
                dsdMode = inuint(c_out);
                curSamRes_DAC = inuint(c_out);
            }
            if (curSamFreq == AUDIO_STOP_FOR_DFU){
                outct(c_out, XS1_CT_END);
                printstr("DFU");
            }
    }
}
Where do I start to debug from here?
(This is my first deeper dive into the USB Audio code, not using the module USB audio as it is)
The bug/bugs may be simple or more complicated.
Maybe someone here that already made a deeper dive into the USB audio code? ;)
You do not have the required permissions to view the files attached to this post.


User avatar
Ross
XCore Expert
Posts: 820
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Do you have a USB analyser?

Could you post the output from xrun --dumpstate <your_binary>.xe at the point of being locked up?
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

I made some progress by deleting all modules in the workspace that also existed in the USB audio zip file and "re-imported" them to ensure that all modules were from the same release of the USB audio code.
After that, the USB device enumerated in the Spy tool with all info.

But I can't stream USB audio data yet to the device.

To be cont...
User avatar
infiniteimprobability
XCore Legend
Posts: 1124
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

First place I check when making fairly major modifications is to see that I2S is running (scope on LR/BCLK etc.) - if this is blocked, it will cause everything else to freeze.. this is because decouple (which services audio) handshakes back to EP0 so a stream/sample rate change request will cause the whole device to become unresponsive, even if it has previously enumerated OK..
When doing custom audio stuff, it can be quite easy to get the channel protocol wrong, and this may result in the above effect.

As per normal, stop the debugger when running and check to see if it is blocked on an in/out across the channel. Most of the time audio will be blocked on a port output and decouple in the background task or ISR.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Think's to both of you for your response.
I have been out of office some days here.

I will try and run the audio-core as unmodified as possible to start with in my design.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Using the original main() etc. from the usb audio module solved the problem.
I also found the
USER_MAIN_DECLARATIONS
USER_MAIN_CORES
declarations

Just one thing
I think that the row 314 in main() should be changed to !?

Code: Select all

#if(AUDIO_IO_TILE != XUD_TILE)
In my case the
AUDIO_IO_TILE =3
XUD_TILE = 3

meaning that XUD_TILE == XUD_TILE != 0
User avatar
Ross
XCore Expert
Posts: 820
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

I have the following around near that line:

Code: Select all

#if(AUDIO_IO_TILE != XUD_TILE)
            set_clock_src(clk_audio_mclk2, p_mclk_in2);
            set_port_clock(p_for_mclk_count, clk_audio_mclk2);
            start_clock(clk_audio_mclk2);
#else
is that what you mean?
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Yes

I downloaded the USB-Audio-2.0-Device-Software(6.11.3).zip

and it shows around line 314

Code: Select all

#if(AUDIO_IO_TILE != 0)
            set_clock_src(clk_audio_mclk2, p_mclk_in2);
            set_port_clock(p_for_mclk_count, clk_audio_mclk2);
            start_clock(clk_audio_mclk2);
#else
            /* Uses same clock-block as I2S */
            asm("ldw %0, dp[clk_audio_mclk]":"=r"(x));
            asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x));
#endif
User avatar
Ross
XCore Expert
Posts: 820
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Thanks, I must have caught that one already as its fixed in a later release (mostly likely spotted it as the xCORE-200 Audio MC board has USB running on tile[1] and audio h/w connected to tile[0]..)
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

What is the intended way to use the

USER_MAIN_DECLARATIONS
USER_MAIN_CORES

external to the usb_audio_module ?

My first approach was to add the USB audio to the existing main(), but that was a little bit tricky.
Now I want to add my code from my old main() to the USB audio main() without changing the code in the usb_audio_module? (So I can upgrade it without Copy & Paste later on )

I guess I need some multiline #define and some include , but how do you do it the best way without getting an angry pre-processor ?

I tried something like this:

#include "user.?"
--------------------------
#ifndef USER_MAIN_DECLARATIONS
#define USER_MAIN_DECLARATIONS
CODE
#endif