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

USB HID

Hi all,

I would like to consult a technical issue here. I am trying to develop a simple USB HID communication between PC and device board with STM32F400. On the host side (PC) I am using Visual Studio to build my application using a DLL for USB HID. The communication works fine but only for reports until 255 bytes long. When I try to set higher output report value (e.g. 1023 bytes) in uVision I can still recieve only reports 255 bytes long. I debugged this with ULINK2 and examined the "usbd_hid_set_report" function. The parameter len is still 255 even though USBD_HID_OUTREPORT_MAX_SZ is set to 1023 and the array sent from PC has 1023 bytes. I can also check this value on the PC side by reading the descriptor and the value reported by the USB device (STM32F400) is still 255 bytes even though it should be 1023 bytes. Do you have any idea where I am going wrong? Max allowed value for USBD_HID_OUTREPORT_MAX_SZ is 65535 bytes according to the documentation.

Any ideas?

Best regards,
Steven.

Parents
  • I ran this example of MDK v4.60 on my STM32F4 Discovery board.
    C:\Keil\ARM\Boards\Keil\MCBSTM32F400\RL\USB\Device\HID

    Surely, as you said, this version has revised above report descriptor problem.
    I saw the exact number on the report descriptor, same as USBD_HID_OUTREPORT_MAX_SZ, using a hardware bus analyzer.

    Also, I saw 808 bytes transfer on the interrupt OUT endpoint, when Keil's HID_Client PC application.
    C:\Keil\ARM\Utilities\HID_Client

    Debugging on this PC application has revealed,
    HidP_GetCaps() returns 809 (808 + 1: report ID) at OutputReportByteLength field, whereas the report descriptor sets it to 9000.

    HID.cpp
    
    int HID_FindDevices() {
      ...
    
        /* Get Preparsed Data */
        ok = HidD_GetPreparsedData(DevHandle, &PreparsedData);
        if (!ok) continue;
    
        /* Get Device's Capabilities */
        HidP_GetCaps(PreparsedData, &Capabilities);
    
        /* Free the PreparsedData */
        HidD_FreePreparsedData(PreparsedData);
    
        /* Remember Device Interface Detail Data for acceptable Devices */
        if ((Capabilities.UsagePage == 0xFF00) && (Capabilities.Usage == 0x0001)) {
          DevDetailData[DevCount] = DevDetail;
          DevDetailDataSz[DevCount] = Sz;
          DevInputReportSz[DevCount] = Capabilities.InputReportByteLength;
          DevOutputReportSz[DevCount] = Capabilities.OutputReportByteLength;   // <-----
    

    I have an impression that MS does nasty coding, but further investigation is required.
    Today, my free time has been expired. I'll report it later.

    Ah, for temporary workaround, hard-code USBD_HID_OUTREPORT_MAX_SZ value on the above line,
    instead of OutputReportByteLength.

    DevOutputReportSz[DevCount] = 9000; // Capabilities.OutputReportByteLength;

    Tsuneo

Reply
  • I ran this example of MDK v4.60 on my STM32F4 Discovery board.
    C:\Keil\ARM\Boards\Keil\MCBSTM32F400\RL\USB\Device\HID

    Surely, as you said, this version has revised above report descriptor problem.
    I saw the exact number on the report descriptor, same as USBD_HID_OUTREPORT_MAX_SZ, using a hardware bus analyzer.

    Also, I saw 808 bytes transfer on the interrupt OUT endpoint, when Keil's HID_Client PC application.
    C:\Keil\ARM\Utilities\HID_Client

    Debugging on this PC application has revealed,
    HidP_GetCaps() returns 809 (808 + 1: report ID) at OutputReportByteLength field, whereas the report descriptor sets it to 9000.

    HID.cpp
    
    int HID_FindDevices() {
      ...
    
        /* Get Preparsed Data */
        ok = HidD_GetPreparsedData(DevHandle, &PreparsedData);
        if (!ok) continue;
    
        /* Get Device's Capabilities */
        HidP_GetCaps(PreparsedData, &Capabilities);
    
        /* Free the PreparsedData */
        HidD_FreePreparsedData(PreparsedData);
    
        /* Remember Device Interface Detail Data for acceptable Devices */
        if ((Capabilities.UsagePage == 0xFF00) && (Capabilities.Usage == 0x0001)) {
          DevDetailData[DevCount] = DevDetail;
          DevDetailDataSz[DevCount] = Sz;
          DevInputReportSz[DevCount] = Capabilities.InputReportByteLength;
          DevOutputReportSz[DevCount] = Capabilities.OutputReportByteLength;   // <-----
    

    I have an impression that MS does nasty coding, but further investigation is required.
    Today, my free time has been expired. I'll report it later.

    Ah, for temporary workaround, hard-code USBD_HID_OUTREPORT_MAX_SZ value on the above line,
    instead of OutputReportByteLength.

    DevOutputReportSz[DevCount] = 9000; // Capabilities.OutputReportByteLength;

    Tsuneo

Children
  • If it is MS related then it is an issue. I tried the hardcoding approach and it works only to a certain extent. I am using an USB HID component for Visual Studio available here: www.codeproject.com/.../usb_hid.zip. I can do changes in the source files and recompile the DLL. So I did what you suggested and this way I could influence the output report length on the PC side. However when I try having this value larger than 8192 and send data to the evaluation board the code does not jump to the interrupt routine, i.e. data is not recieved. For values below 8192 everything works fine, interrupt routine is invoked and data recieved.

    Steven.

  • The HID stock driver of XP has this 8K bytes report size limitation.
    Maybe it's "feature" of MS HID implementation.

    I don't yet test this issue on Windows 7 and 8.
    For these days, I've been working on another place, far from my lab.
    I can't reach to test resources, on this weekend, too.
    I hope I could confirm it on these OS versions at next weekend.

    Tsuneo