2010-10-10 10:06 AM
USB issue after waiting a few secs
2011-05-17 05:10 AM
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
2011-05-17 05:10 AM
2011-05-17 05:10 AM
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
2011-05-17 05:10 AM
2011-05-17 05:10 AM
> 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
2011-05-17 05:10 AM
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.2011-05-17 05:10 AM
> 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