> 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.
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.
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?
> 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 */
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.