How can I transfer USB data faster?

20 Jun 2012

I'm currently using the USBHID library to turn my mbed into an HID device. I've got code that looks like this:

void transfer_USB(){ if(hid.readNB(&recv_report)){ read the report do stuff } }

Ticker usb_timing;

void main(int){ usb_timing.attach(&transfer_USB, 0.5); while(1){ do stuff } }

I'm using usb_timing to check every 0.5s whether anything has been sent from the host. I've noticed that if I try to check more frequently (say every 0.3s), the computer will no longer recognize the mbed as a USB device. According to the USBHID.cpp file, bInterval = 10ms in the configuration descriptor so I wouldn't think that 300ms would be much of a problem.

My questions are: 1. Using my current method, is there a way to get the transfer rate down to under 100ms? 2. If not, is there any way I can handle the USB receive interrupt on my own in a way that either complements or supercedes the current implementation? 3. In the USBHID.cpp file, I see "callback" methods that are described as being "called in ISR context". What are these for? Can I use them to implement my own interrupt handling?

Thanks

20 Jun 2012

I am fairly sure that 50ms rate should be possible. I will try tomorrow when I get back.

one question! how are you reviving data in P.C.

I use Delphi my self and have found it to be able to handle enormous accounts of data.

hope this helps

Ceri

20 Jun 2012

I'm using pywinusb, receiving and sending data the way as shown here:

http://mbed.org/cookbook/USBHID-bindings-

The problem occurs even before I interact with it in python. After flashing the chip, and connecting the USB cable to the mbed board, windows does not recognize it as a USB device if I set the parameter of attach() to less than 0.5s.

21 Jun 2012

Hello Greg, maybe this can help You. I had similiar problem before Christmass and got help from Samuel.

Samuel Mokrani wrote:

Hi little,

I will investigate the problem concerning the device not enumerated. But I think that the problem is:

  • before enumeration, at the beginning "send" in the ticker handler is called.
  • "send" is blocking (in particular, this function waits that the device is ready. If the device is ready, it also waits that the message has been effectively sent. All of these mechanisms are working with interrupts), so you are blocked in an interrupt handler.
  • usb interrupts to perform the enumeration are not received
  • the device is not enumerated.

I think that I will introduce a non blocking "send" function. In the meantime, you can try to use the method configured() from USBDevice to check when the device is configured before launching your ticker. You can try something like:

int main(void) {
    while(!hid.configured());
    ticker.attach(handler, time);
    ...
}

Sam

And this helped me a lot. As Samuel wrote ticker was calling handler to send report before device got enumerated. So it seems that Ticker tries to receive report before device is enumerated by host.

Try to add while(!hid.configured()); before calling ticker.attach();

void transfer_USB(){

      if(hid.readNB(&recv_report)){
         read the report do stuff 
   } 
}


Ticker usb_timing;

void main(int){

       while(!hid.configured());

       usb_timing.attach(&transfer_USB, 0.5);

while(1){

 // do anything 

   } 
}

I hope this will help You.

-llu

21 Jun 2012

this code sends out 1024 18 Byte messages, as fast as possable, then pauses for 2 seconds, so you can review last data packet.

there is a 'HIT' counter, which increments with each sucsesfull HID TX

#include "mbed.h"
#include "USBHID.h"
/*
DigitalOut myled1(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
*/
BusOut leds(LED1,LED2,LED3,LED4);
AnalogIn PortA (p20);
AnalogIn PortB (p19);
AnalogIn PortC (p18);
AnalogIn PortD (p17);

int a, x, t, k;
int An_a, An_b, An_c, An_d;

int HITs;

#define HID_MessageSize 18

//This report will contain data to be sent
HID_REPORT send_report;
HID_REPORT recv;

//We declare a USBHID device
USBHID hid_A (HID_MessageSize, HID_MessageSize,0xcbc,0x123,5);     // In Length, Out Length, VID, PID, Release

// Strings are in "USBDevice.cpp"


//BusOut leds(LED1,LED2,LED3,LED4);

int main(void) 
{

    //Fill the report
    for (int i = 0; i < HID_MessageSize; i++)
        send_report.data[i] = i;
    send_report.length = HID_MessageSize;

    leds = recv.data[0];
    send_report.data[1] = 0;
    send_report.data[0] = 0 ;


    while (1) 
    {
        // just a test to see how fast send could be ..
        HITs = 0;
        for (x=0; x<1024; x++) 
        {
            /*
            An_a = PortA.read_u16();
            An_b = PortB.read_u16();
            An_c = PortC.read_u16();
            An_d = PortD.read_u16();
            */
            send_report.data[3] = HITs & 0xff;
            send_report.data[2] = HITs >>8;

            send_report.data[5] = An_b & 0xff;
            send_report.data[4] = An_b >>8;

            send_report.data[7] = An_c & 0xff;
            send_report.data[6] = An_c >>8;

            send_report.data[9] = An_d & 0xff;
            send_report.data[8] = An_d >>8;;

            send_report.data[11] = k & 0xff;
            send_report.data[10] = k >>8;

            k++;

            send_report.data[16] = x;
            if (hid_A.send(&send_report)) HITs ++;
        }

        send_report.data[HID_MessageSize-2]++;
        hid_A.send(&send_report);
        wait(1.5);
    }

}


I am using SimpleHIDWrite to recive the HID messages,

Hope this is usefull

Ceri

21 Jun 2012

Thanks all. Checking that it's configured before attaching seems to help.