data send getting interupted.

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

data send getting interupted.

Post by ulao » Fri May 26, 2017 3:42 am

I'm trying to send data to my device via the usb.dll usbSetReport function. I set up my usbFunctionWrite to watch for my report ID then a command on byte 2. I return 0 to tell the driver to expect more (bytesRemaining). This most of the time works but some times dies. When it dies it just stop and does not loop any further. I'm not sure what I need to suppress so that the driver can get all the data in one shot.

Here is an example of how I do it.

Code: Select all


uchar usbFunctionWrite(uchar *data, uchar len)
{
    char j=0; //loop
      
    if(needMoreThen8Data)
    {
      if(needMoreThen8Data==0x24)
      {
         for (unsigned char i=currentAddress;i<currentAddress+8;i++)
            {lcd_data[i] = data[j]; j++;}
         _lcdNeedsWrite = 1;             
      }
            
            

        currentAddress += len;
        bytesRemaining -= len;
        if(bytesRemaining == 0) {needMoreThen8Data=0;return 1;}//finished
        return 0;
    }

    if ( data[0] == 18)
    {                 
        if (data[1]== 0) //this means to set.
        {
         if (data[2]== 0x24)
         {     
         // lcd
            bytesRemaining = 116;//120 + this byte.
            needMoreThen8Data=0x24;//set flag
            currentAddress = 4;//can only load 4 in here.
            for (char i=0;i<4;i++) lcd_data[i] = data[i+4];
            return 0;       
         }
      }
        else //must be a get command from setreport.
        {
        }
             
    }     
}
                   

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: data send getting interupted.

Post by ulao » Tue May 30, 2017 3:52 am

I did sum sniffing and its a pid stall.

When a device receives a request that is undefined, is inappropriate given the current setting or state of the device, or uses values that are inappropriate for the particular request, then a Request Error exists. The device handles a Request Error by returning a STALL PID to the next DATA or STATUS stage, preferably at the next DATA stage transaction.


Since it's random and not every send that errors, "a request that is undefined" and "values that are inappropriate for the particular request" thus my error must be "inappropriate given the current setting or state of the device"However I'm still uncertain what "state" my device is in that causes this.

declan smith
Rank 1
Rank 1
Posts: 32
Joined: Fri Nov 02, 2012 3:26 pm

Re: data send getting interupted.

Post by declan smith » Tue Jun 13, 2017 3:01 pm

You haven't provide your device descriptor.
It's difficult to only look at your few code to give the right answer.

If you got PID Stall but not always, then your report size was incorrect or your host sofware use different report size.

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: data send getting interupted.

Post by ulao » Tue Jun 27, 2017 3:51 pm

here is the section for my send/recv.

Code: Select all

0xa1, 0x01,                    // COLLECTION (Application)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)

    0x85, 0x11,                    //   REPORT_ID (17)
    0x95, 0x79,                    //   REPORT_COUNT (127) -- the max
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)

    0x85, 0x12,                    //   REPORT_ID (18)
    0x95, 0x83,                    //   REPORT_COUNT (131) -- the max
    0x09, 0x00,                    //   USAGE (Undefined)
    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)
    0xc0,                           // END_COLLECTION



Why would the size change randomly? What I do is always use 128, in or out. For in I need to added the few bytes for address and what not (132) but its always the same. Since this is random, I must be getting a pid stall do to some of the data in the 128 bytes are getting dropped. Otherwise that could never be a mismatch.

I have since switch to another api for my feature request and it does the same thing. Guessing I need to dig deeper here to find the issue?

When I stared this I had two issue, one was memory move issues with cli/sei I since fixed with ATOMIC. Now my second issues is the random dropping of data and PID stalls. To fix this I just keep sending till its right. Do to the randomness it eventual gives in but this is a horrible fix.

declan smith
Rank 1
Rank 1
Posts: 32
Joined: Fri Nov 02, 2012 3:26 pm

Re: data send getting interupted.

Post by declan smith » Wed Jun 28, 2017 2:21 am

From your descriptor, your report size in is 128 and out is 132.

ulao wrote:What I do is always use 128, in or out


You should do 132 bytes for report out not 128.

If you want to have 2 report size sistem then use 2 interface setup not 1.
In your usbFunctionSetup you can split those 2 interface using your report ID.
It's much easier since you can do both get/set in both size.

In your API while you connect to your device, you can get the "in/out report size" value and
use it in your get/set function, do not harcoded those size.

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: data send getting interupted.

Post by ulao » Wed Jun 28, 2017 2:48 pm

You should do 132 bytes for report out not 128.


What I do is always use 128, in or out. For in I need to added the few bytes for address and what not (132) but its always the same.


That's what I said, you just cut off the part of my text that said 132 ;)

In your API while you connect to your device, you can get the "in/out report size" value and
use it in your get/set function, do not harcoded those size.
- I can certainly do that, just didn't see the need. Do you think that is the issue in some way. I will still need a 128 byte payload to work so the concentration of my problem is to that. I need to somehow figure out how to reliably get 128 bytes transferred. Although I do see where your points come in, I fail to see how they are causing my issue. The example report descriptor came from v-usb, its not my design. By interface do you mean pipes, or collections?

here is my pipe set up

Code: Select all

char usbDescriptorConfiguration[] = { 0 }; // dummy 
static char my_usbDescriptorConfiguration[] = {    /* USB configuration descriptor */
     9,          /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
    USBDESCR_CONFIG,    /* descriptor type */
    18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + /*7 * USB_CFG_HAVE_INTRIN_ENDPOINT3*/ + 7 + 9, 0,
                /* total length of data returned (including inlined descriptors) */
    1,          /* number of interfaces in this configuration */
    1,          /* index of this configuration */
    0,          /* configuration name string index */
    USB_CFG_IS_SELF_POWERED,  /* attributes */

    USB_CFG_MAX_BUS_POWER/2,            /* max USB current in 2mA units */
/* interface descriptor follows inline: */
    9,          /* sizeof(usbDescrInterface): length of descriptor in bytes */
    USBDESCR_INTERFACE, /* descriptor type */
    0,          /* index of this interface */
    0,          /* alternate setting for this interface */
    1 + USB_CFG_HAVE_INTRIN_ENDPOINT ,//+ USB_CFG_HAVE_INTRIN_ENDPOINT3,   /* endpoints excl 0: number of endpoint descriptors to follow */
    USB_CFG_INTERFACE_CLASS,
    USB_CFG_INTERFACE_SUBCLASS,
    USB_CFG_INTERFACE_PROTOCOL,
    0,          /* string index for interface */

    9,          /* sizeof(usbDescrHID): length of descriptor in bytes */
    USBDESCR_HID,   /* descriptor type: HID */
    0x10, 0x01, /* BCD representation of HID version */
    0x00,       /* target country code */
    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */
    0x22,       /* descriptor type: report */
    USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 5,  /* total length of report descriptor *///

    7,          /* sizeof(usbDescrEndpoint) */
    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */
    0x81,       // bulk IN endpoint number 1
    0x03,       /* attrib: Interrupt endpoint */
    8, 0,       /* maximum packet size */
    0x08, /* in ms*/

//the output.

    7,          // sizeof(usbDescrEndpoint)
    5,  // descriptor type = endpoint
    0x01,        // out endpoint number 2
    0x03,       // attrib: Interrupt endpoint
    8, 0,       // maximum packet size
    0x08, // in ms
     
};

declan smith
Rank 1
Rank 1
Posts: 32
Joined: Fri Nov 02, 2012 3:26 pm

Re: data send getting interupted.

Post by declan smith » Wed Jun 28, 2017 3:46 pm

ulao wrote:For in I need to added the few bytes for address and what not (132) but its always the same.

That's what made me wrote the statement.

ulao wrote:By interface do you mean pipes, or collections?

Collections

ulao wrote:I can certainly do that, just didn't see the need.

When you do that, you don't have to worry about changing report size in your device as your API will always match your device report size.
But you know what best for you.

ulao wrote:I will still need a 128 byte payload to work so the concentration of my problem is to that.

Set your in/out the same payload size 128 and don't forget 128 bytes payload means 129 report size.
And see if your problem still exist.

declan smith
Rank 1
Rank 1
Posts: 32
Joined: Fri Nov 02, 2012 3:26 pm

Re: data send getting interupted.

Post by declan smith » Wed Jun 28, 2017 3:54 pm

For more certain answer, use VUSB example and test your API.
If no problem exist then you should remake your code.

You noted that you do something about USB interrupt, who knows that involved.

ulao
Rank 4
Rank 4
Posts: 481
Joined: Mon Aug 25, 2008 8:45 pm

Re: data send getting interupted.

Post by ulao » Fri Jul 21, 2017 4:12 pm

All of my issues were related to the global int flag. and this https://forums.obdev.at/viewtopic.php?f=8&t=10981I was using a combination of atomic and cli to control int's. Now I just start and stop my INT0 directly and only, this allows use of interrupts to work fine for my code that needs it. I just make sure to stay within the usb timing window for v-usb.

So my original thinning was that I had to make the USB deal with the interruptions, correctly. This still should have worked but fixing the source of the problem did a much better job.

Post Reply