cancel
Showing results for 
Search instead for 
Did you mean: 

USB issue after waiting a few secs

Kuikui
Associate III
Posted on October 10, 2010 at 19:06

USB issue after waiting a few secs

7 REPLIES 7
tsuneo
Senior
Posted on May 17, 2011 at 14:10

Surely, the third transfer (URB) for the endpoint 0x81 results in STATUS_UNSUCCESSFUL.

But the first two transfers for the endpoint return STATUS_NOT_SUPPORTED. This is not the expected result, too. The problem has already occurred here.

a) Report descriptor format

In the report descriptor on the firmware, do you define the 64 bytes input report correctly? Post your report descriptor.

b) Endpoint size

On the endpoint descriptor for the interrupt IN endpoint for HID (address 0x81), what is the wMaxPacketSize?

Is it set to 64 bytes?

Tsuneo

Kuikui
Associate III
Posted on May 17, 2011 at 14:10

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6Zb&d=%2Fa%2F0X0000000bqy%2FDu0aqY5Ga8OwMO832IHcF4k_fsFyQNCo3N9hfBL_Scc&asPdf=false
tsuneo
Senior
Posted on May 17, 2011 at 14:10

Your descriptors are fine.

In above post, I said STATUS_NOT_SUPPORTED on the trace is also a problem.

But I found that STATUS_NOT_SUPPORTED is not a particular result just for this sniffer (USBTrace), though it is far from the common sense of device driver programming. Anyway, I don't like this sniffer, because its display is very confusing in many other points, too. For example, I/O field (usually Up/Down, instead of IN/OUT), unpaired URBs, etc.

OK, looking into the sniffer trace, again,

Just before the error (STATUS_UNSUCCESSFUL), the OUT transfer to 0x01 endpoint completes without any error. Up to this point, the USB engine on the chip still works fine, regardless of the long interval.

The engine gets into trouble about 200 ms after the above OUT transfer.

Maybe, your firmware accidentally destroys critical resource(s) of the USB engine, such as USB registers or the buffer descriptor table. Wrong pointer operation?

Tsuneo

Kuikui
Associate III
Posted on May 17, 2011 at 14:10

Hi,

Well, it is really hard to debug the USB, since Windows considers the device malfunctioned as you stop the STM32 for debugging.

But if I'm not wrong, I just copied the CustomHID example, changed the config to transmit 64 bytes, and transmit a 64-byte buffer when the PC sends a command.

I'm a bit lost .. dunno what I could debug or something ...

Thanks for your help.

tsuneo
Senior
Posted on May 17, 2011 at 14:10

> Well, it is really hard to debug the USB, since Windows considers the device malfunctioned as you stop the STM32 for debugging.

Surely, while enumeration is going on, PC device driver puts USB requests with timeout to the device. Therefore, we can't stop MCU execution without disturbing enumeration. But once enumeration finishes, no timeout is applied to HID interrupt IN/OUT transfers. Then, you can put break points or step execution at this point.

Put a couple of break points into the processes after the process of the HID OUT transfer. And run the code on the sniffer.

Which one is the last break point, before the sniffer reports the error?

Move the break point and narrow down suspicious code range.

Watch dog also disturbs the USB engine.

Disable watchdog temporarily, if enabled.

Tsuneo

Kuikui
Associate III
Posted on May 17, 2011 at 14:10

Problem is solved.

The issue was that I was sending data ''too fast'' ... I mean there was two following USB_SIL_Write() function calls, and it seems the second function call disturbed the USB stack or something ...

Thanks for your help Tsuneo.

tsuneo
Senior
Posted on May 17, 2011 at 14:10

> I mean there was two following USB_SIL_Write() function calls, and it seems the second function call disturbed the USB stack or something ...

Umm.. I'm not aware that overwrite to the IN endpoint makes the endpoint disabled..

Before filling the endpoint buffer using USB_SIL_Write(), check the endpoint status by GetEPTxStatus(),

if ( GetEPTxStatus( HID_IN_EP ) == EP_TX_NAK ) {  // Is the endpoint empty?

    USB_SIL_Write( ... );

}

When you put two input reports contiguously, the second report is put in the endpoint ISR (callback). The endpoint callback is called at the timing when the last transfer completes. And then, you don't need to wait for the end of the first report transfer in a wait loop.

int hid_tx_report_num = 0;

if ( GetEPTxStatus( HID_IN_EP ) == EP_TX_NAK ) {  // Is the endpoint empty?

    USB_SIL_Write( ... );                         // put the first report to the endpoint

    hid_tx_report_num = 1;                        // there is one another report after this one

}

usb_conf.h

/* CTR service routines */

/* associated to defined endpoints */

// #define  EP1_IN_Callback   NOP_Process   // <------ comment this line

usb_endpoint.c

void EP1_IN_Callback( void )

{

    if ( hid_tx_report_num ) {                    // any other report to send?

        USB_SIL_Write( ... );                     // put the next report to the endpoint

        --hid_tx_report_num;

    }

}

The variables and flags assigned by your code, like above hid_tx_report_num, are initialized in the Set_Configuration handler.

usb_prop.c

void CustomHID_SetConfiguration(void)

{

  if (pInformation->Current_Configuration != 0)

  {

    /* Device configured */

    bDeviceState = CONFIGURED;

    

    hid_tx_report_num = 0;                        // initialize variables for USB communication

  }

}

To speed up communication over USB, reduce the bInterval value into 0x01 on both of the endpoint descriptors,

/* USB Configuration Descriptor */

/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */

const uint8_t CustomHID_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] =

  {

    ...

    ...

    /******************** Descriptor of Custom HID endpoints ******************/

    ...

    0x20,          /* bInterval: Polling Interval (32 ms) */    // <------- 0x01,

    ...

    ...

    0x20,    /* bInterval: Polling Interval (20 ms) */          // <------- 0x01,

    /* 41 */

  }

Tsuneo