USB Bulk OUT transfer problem

Technical questions regarding the XTC tools and programming with XMOS.
mkassner
Member
Posts: 12
Joined: Mon Feb 13, 2012 10:54 pm

USB Bulk OUT transfer problem

Post by mkassner »

Hi,

I m currently working on a hi-bandwidth CMOS camera sensor application and I m having trouble getting the USB module to work properly. IN-transfers work fine but if I send something to my OUT EP it works once and then stalls the XUS/USB module. Neither read or write request are then answered by the xmos controller.

This is my simple tester for the OUT endpoint:

Code: Select all

void usb_control_out(chanend chan_ep1){ //chanend c_usb_control
	  XUD_ep c_ep1 = XUD_Init_Ep(chan_ep1);
	    char mybuffer[518];
	    timer t;
	    unsigned s;
	    int len;
	    printf("DATA OUT listening \n");
	    t :> s;
	    while(1) {
	        t when timerafter(s+100000) :> s;
	        printf("trying to recieve now! \n");
	        len = XUD_GetBuffer(c_ep1, mybuffer);
	        if (len < 0) {
	            XUD_ResetEndpoint(c_ep1, null);
	        }
	        printf("something came through\n");
	        printf("len %i, Buffer : %02x %02x %02x %02x \n",len, mybuffer[0],mybuffer[1],mybuffer[2],mybuffer[3]);
	        
	    }
	return;
}


This endpoint has the address 0x01 and is configured as bulk with a max packet size of 512byte.

Im am using lib usb to communicate and all IN/transfers work just fine. Only when I send something to the device. It come through but then stalls the device.

Interestingly, when I disconnect and reconnect the usb cable (this does not de-power or reset the device). I can do IN transfers and 1 out transfer again.

any suggestions or experience with a similar problem?

thank you very much in advance!

best,

Moritz


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

Post by Ross »

I would try removing the print statements and see if that helps. These will affect the real-time operation of your program.
mkassner
Member
Posts: 12
Joined: Mon Feb 13, 2012 10:54 pm

Post by mkassner »

Hi Ross,

that solved it! Thank you very much!

Why exactly, does a print line stall the usb functionality? If I use a timer to control the frequency at which I issue a XUD_GETBUFFER it does not do that. Does it have to do with thread performance?



Maybe it is the nature of USB or me but I find it hard to debug xmos usb applications. Having a better documentation, especially for the interrupt based usb examples would be very helpful.

For example this part I can not follow because I don't understand the syntax of:
case foo != 0 => channend :> bar

Code: Select all

       
case hostLen != MAX_BUF => vcomToHost :> char x:
            (bufToHost[hostCurrent], unsigned char[])[hostLen++] = x;
            if (hostWaiting) {
                XUD_provide_IN_buffer(c_ep_in, 0, bufToHost[hostCurrent], hostLen);
                hostCurrent = !hostCurrent;
                hostLen = 0;
                hostWaiting = 0;
            }
            break;
        case devLen[devCurrent] != 0 => vcomToDevice :> int _:
            vcomToDevice <: (bufToDevice[devCurrent], unsigned char[])[devRd++];
            devLen[devCurrent]--;
            if (devLen[devCurrent] == 0) {
                if (devWaiting) {
                    devCurrent = !devCurrent;
                    devRd = 0;
                    XUD_provide_OUT_buffer(c_ep_out, bufToDevice[!devCurrent]);                    
                    devWaiting = 0;
                }
            }
            break;

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

Post by Ross »

Glad it's sorted. The JTAG printing interrupts the whole processor not just the thread it's used in. For real-time debug you should have a look at the new "xscope" features.
User avatar
Ross
XCore Expert
Posts: 962
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

mkassner wrote:

Maybe it is the nature of USB or me but I find it hard to debug xmos usb applications. Having a better documentation, especially for the interrupt based usb examples would be very helpful.
We're working on that
mkassner wrote: For example this part I can not follow because I don't understand the syntax of:
case foo != 0 => channend :> bar

Code: Select all

       
case hostLen != MAX_BUF => vcomToHost :> char x:
            (bufToHost[hostCurrent], unsigned char[])[hostLen++] = x;
            if (hostWaiting) {
                XUD_provide_IN_buffer(c_ep_in, 0, bufToHost[hostCurrent], hostLen);
                hostCurrent = !hostCurrent;
                hostLen = 0;
                hostWaiting = 0;
            }
            break;
        case devLen[devCurrent] != 0 => vcomToDevice :> int _:
            vcomToDevice <: (bufToDevice[devCurrent], unsigned char[])[devRd++];
            devLen[devCurrent]--;
            if (devLen[devCurrent] == 0) {
                if (devWaiting) {
                    devCurrent = !devCurrent;
                    devRd = 0;
                    XUD_provide_OUT_buffer(c_ep_out, bufToDevice[!devCurrent]);                    
                    devWaiting = 0;
                }
            }
            break;

thanks!
This is whats is called a guard, the case in the select statement will not be enabled unless the guard evaluates as true.
User avatar
XMatt
XCore Addict
Posts: 147
Joined: Tue Feb 23, 2010 6:55 pm

Post by XMatt »

mkassner wrote: Maybe it is the nature of USB or me but I find it hard to debug xmos usb applications. Having a better documentation, especially for the interrupt based usb examples would be very helpful.
If your board supports the XScope link via the XSYS connector then you can use the real time printing capability of XScope which does not stop the device. This will allow you to leave prints in your USB code without breaking the application. JTAG is very intrusive due to having to stop the device at a breakpoint to do I/O.

Example is here but you need the link connected up on your board for it to work.

https://github.com/xcore/sw_xscope_exam ... edirection
DrNO
Member++
Posts: 31
Joined: Mon Feb 06, 2012 11:42 pm

Post by DrNO »

Hey mkassner, would you be willing to share your project files with your tester file? I'm interested in starting a USB project but starting with test code for bulk transfer would GREATLY help. Also what hardware are you using (what USB IC are you using)?
mkassner
Member
Posts: 12
Joined: Mon Feb 13, 2012 10:54 pm

Post by mkassner »

Hi XMatt,

this is exactly the kind of information I m looking for. I did not know that printf was so disruptive. This is very helpful information.

I will check out x-scope.

moritz
mkassner
Member
Posts: 12
Joined: Mon Feb 13, 2012 10:54 pm

Post by mkassner »

Hi DrNo,

Im using the XC-1A with an external USB PHY add-on board. This is my first Xmos project so I m learning on the way. This might be reflected in my coding. :-)

I can post schematics and code this weekend. I found the hid example to be most useful for getting started.
Its default is good for testing the hardware.
Modifying the descriptor so that it does not show up as a HID device allows you to interface it with your own driver (MacOS likes to sit on usb hardware when it knows what it is. )

USB in a Nutshell is good for getting the hang of USB.
LibUSB is what I use on the Host side. PyUSB is a convienent Python wrapper, but I found it to be to slow.

more to follow soon.

best,

Moritz
mkassner
Member
Posts: 12
Joined: Mon Feb 13, 2012 10:54 pm

Post by mkassner »

Hi Ross,

thank for the reply. Again, very helpful stuff! I look forward to good documentation!

Also the guard parts is clear now. thanks!

best,

moritz
Post Reply