This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2378 No USB_EVT_OUT

Gent;
I'm apologize for repeating a question that appeared to be answered in thread11137. It seems Doug and Tsuneo were trouble shooting a USB interrupt out problem. I'm having the same problem. No USB_EVT_OUT.
I'm at the exact same point where Doug was on Feb 20.
I do not see a resolution to Doug's effort on this or later threads.
I am able to send 64 byte InReports with no problems.

This is a copy of my URB from the HHD snooper software.

000173: Bulk or Interrupt Transfer (DOWN), 28.03.2008 18:06:13.625 +0.0
Pipe Handle: 0x8924ed4c (Endpoint Address: 0x81)
Get 0x40 bytes from the device

000174: Bulk or Interrupt Transfer (UP), 28.03.2008 18:06:13.656 +0.031. Status: 0x00000000
Pipe Handle: 0x8924ed4c (Endpoint Address: 0x81)
Get 0x40 bytes from the device
 01 55 AA FF 00 00 00 00 00 00 00 00 00 00 00 00   .Uªÿ............
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 AF   ..............ð¯

This is repeated at the specified 32 milliseconds.
At the same time in my Host App, I have a forever loop calling WriteFile to write 8 bytes. I do not see any out packets other than the control packets to request an InReport.
Using the original Keil example, I can see Up/Down packets but the Down packets appear to be Control Transfers.

This code is a stripped version from John Hyde's BALVC code from his book.

unsigned long BytesWritten, BytesRead;
UCHAR OutReport[8] = {2,3,5,4};
case 'l':
   printf("\nValue to be written to Dig_Out: ");
   while(1){   // For test only - Remove!!!!!!!
     for(i=0; i<10000; i++);  // just a delay
     Result =  (WriteFile(Handle, OutReport,
          sizeof(OutReport),&BytesWritten, NULL));
     if (Result == FALSE)
         printf("\nError writing to I/O device\n");
   }
   break;
case 'e':

I'm using VS 2005. Setting a breakpoint at the line if(Results.....
I can look at OutReport buffer and the hard coded values appear correct. BytesWritten is 0. The Handle value is the same as the Handle value for the ReadFile operation which works fine. Results == FALSE.
The descriptor configs look correct to me but I include them also. They were captured via USBView.
I edited the VendorID and ProductID. NDA and all that stuff.

I guess I'm asking how to proceed from this point to determine if the problem is in the Host app which is stripped to a bare minimum or in the device program which works fine with InReports in interrupt transfers and OutReports in Control transfers but not interrupt transfers.

Yes, one other thing. My manufacterID, etc., strings appear in the String buffer transmitted as Unicode.
Is this the defalut for USB? Is there a software switch to enable/disable? Can this be part of my problem?

My Keil Software is MDK full Version 3.20. My JTAG is Ulink2.

Device Descriptor:
bcdUSB:             0x0110
bDeviceClass:         0x00
bDeviceSubClass:      0x00
bDeviceProtocol:      0x00
bMaxPacketSize0:      0x40 (64)
idVendor:           0xXXXX
idProduct:          0xXXXX
bcdDevice:          0x0100
iManufacturer:        0x04
iProduct:             0x20
iSerialNumber:        0x42
bNumConfigurations:   0x01

ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed:     Full
Device Address:       0x02
Open Pipes:              2

Endpoint Descriptor:
bEndpointAddress:     0x81  IN
Transfer Type:   Interrupt
wMaxPacketSize:     0x0040 (64)
bInterval:            0x00

Endpoint Descriptor:
bEndpointAddress:     0x01  OUT
Transfer Type:   Interrupt
wMaxPacketSize:     0x0040 (64)
bInterval:            0x20

Parents
  • Thank-you again Tuneo for your time and detailed reply - it is very much appreciated.

    Let me try to address some of the points you make :-

    Our wMaxPacketSize is typically only 8 or 16, the same size as our maximum HID report, so we have no need to split reports into multiple frames.

    Our host app calls ReadFile() something like the following :-

    ReadFile(handle, buffer, sizeof(buffer), &numBytes, pHIDOverlapped);
    Result = WaitForSingleObject(pHIDOverlapped, 100);
    if (Result == WAIT_OBJECT_O)
    {
      GetOverlappedResult(hande, pHIDOverlapped,, &numBytes, FALSE);
    }
    else
    {
      CancelIo(handle);
    }
    

    buffer size is currently (65 * 8).

    Our firmware only sends reports when it actually has something new to report (unlike, as you say, the Keil example). However, the nature of those reports is asynchronous and sometimes it has to send multiple reports in a short period of time.

    To determine if reports were being lost, we modified the firmware so that, on demand, it sent 20 x 8-byte reports in a short time, each containing an incrementing value. When the host app reads these reports it only ever gets a maximum of 64 bytes (the last 8 frames) with older ones having been thrown away.

    Regarding your four options :-

    We already do (a) and (b). We could do (c) but this would obviously increase the latency of the device, which is not desirable. (d) is the option I referred to in my last post, but Windows is notoriously unpredictable when it come to trying to do something very quickly very regularly - it's not exactly designed for real-time.

    Your suggestion to pad reports to the defined maximum size is exactly what we currently do. However, because of the problem with Windows apparently dropping reports under load, we are interested in being able to send smaller reports where possible.

    ...breaking news...

    Our host app programmer has just reported that your suggestion of increasing the number of buffers using HidD_SetNumInputBuffers() is working. Thank-you very much for this.
    Without this call however, we still see a limit of 64 bytes, not 32 reports as per the documentation link that you provided !

    Are you aware of any difference (other than the maximum number of buffers) under Windows 2000 ?

    Thnaks again for all your assistance.

Reply
  • Thank-you again Tuneo for your time and detailed reply - it is very much appreciated.

    Let me try to address some of the points you make :-

    Our wMaxPacketSize is typically only 8 or 16, the same size as our maximum HID report, so we have no need to split reports into multiple frames.

    Our host app calls ReadFile() something like the following :-

    ReadFile(handle, buffer, sizeof(buffer), &numBytes, pHIDOverlapped);
    Result = WaitForSingleObject(pHIDOverlapped, 100);
    if (Result == WAIT_OBJECT_O)
    {
      GetOverlappedResult(hande, pHIDOverlapped,, &numBytes, FALSE);
    }
    else
    {
      CancelIo(handle);
    }
    

    buffer size is currently (65 * 8).

    Our firmware only sends reports when it actually has something new to report (unlike, as you say, the Keil example). However, the nature of those reports is asynchronous and sometimes it has to send multiple reports in a short period of time.

    To determine if reports were being lost, we modified the firmware so that, on demand, it sent 20 x 8-byte reports in a short time, each containing an incrementing value. When the host app reads these reports it only ever gets a maximum of 64 bytes (the last 8 frames) with older ones having been thrown away.

    Regarding your four options :-

    We already do (a) and (b). We could do (c) but this would obviously increase the latency of the device, which is not desirable. (d) is the option I referred to in my last post, but Windows is notoriously unpredictable when it come to trying to do something very quickly very regularly - it's not exactly designed for real-time.

    Your suggestion to pad reports to the defined maximum size is exactly what we currently do. However, because of the problem with Windows apparently dropping reports under load, we are interested in being able to send smaller reports where possible.

    ...breaking news...

    Our host app programmer has just reported that your suggestion of increasing the number of buffers using HidD_SetNumInputBuffers() is working. Thank-you very much for this.
    Without this call however, we still see a limit of 64 bytes, not 32 reports as per the documentation link that you provided !

    Are you aware of any difference (other than the maximum number of buffers) under Windows 2000 ?

    Thnaks again for all your assistance.

Children
  • A quick follow-up...

    It was my mistake regarding Windows XP; my colleague was actually using Windows 2000.

    A quick check with HidD_GetNumInputBuffers() shows that under Windows 2000, the default is 8 reports while under Windows XP, the default is 32.

    The microsoft documentation at msdn2.microsoft.com/.../ms790946.aspx is wrong (or at least inaccurate) as it appears to suggest that the default is 32 on both.

    Thanks Tsuneo for all your help.

  • "Our wMaxPacketSize is typically only 8 or 16, the same size as our maximum HID report, so we have no need to split reports into multiple frames."

    I don't recommend you to set wMaxPacketSize to other number than 64 for full-speed interrupt and bulk EPs. Surely, the USB spec allows any number (<= 64) for interrupt EPs, and 8, 16, 32, 64 for bulk ones. However, 64 is the de-fact standard; most of devices apply this number, and the host USB stack may not test fully for other numbers.


    "Our host app calls ReadFile() something like the following"

    Check the return value of ReadFile, first.
    OVERLAPPED ReadFile returns TRUE, when it immediately completes the request. This occurs when the input-report buffer already holds enough number of reports for the request.
    When it returns FALSE, confirm that GetLastError returns ERROR_IO_PENDING. Now you can safely apply WaitForSingleObject.


    "Are you aware of any difference (other than the maximum number of buffers) under Windows 2000 ?"

    I've once seen that the MS KB refers briefly to Win2k bug on reading out multiple reports using ReadFile. It was just a comment on an example file of the MS KB. But I cannot find it again...

    Tsuneo

  • See this MS KB article for the details of OVERLAPPED ReadFile handling.

    "Asynchronous Disk I/O Appears as Synchronous on Windows NT, Windows 2000, and Windows XP"
    support.microsoft.com/.../en-us

    When OVERLAPPED ReadFile completes synchronously and returns TRUE, the event object in the OVERLAPPED structure is not signaled. WaitForSingleObject results timeout in this case, though the readout actually succeeds. I think this is the cause of the data drop.

    Tsuneo