STM32 USB Custom HID only 1 byte per transaction

1.5k views Asked by At

I know that maximum speed of USB HID device is 64 kbps, but on oscilloscope I get transactions every 1 ms, which contain only ONE byte. My HID report descriptor listed below. What i must change to achieve 64Kbps? Currently my bInterval = 0x01 (1 ms polling for interrupt endpoint), but actual speed is 65 bytes/s, because it add reportID byte to my 64-byte data. I think, USB should not divide single 64+1 packet to 65 singlebyte packets. For experiment I use reportID=1 (from STM32 to PC). From PC side I use hidapi.dll to interact.

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
    USAGE_PAGE(USAGE_PAGE_UNDEFINED)
    USAGE(USAGE_UNDEFINED)
    COLLECTION(APPLICATION)         
        REPORT_ID(1)
            USAGE(1)
            LOGICAL_MIN(0)          
            LOGICAL_MAX(255)        
            REPORT_SIZE(8)          
            REPORT_COUNT(64)        
            INPUT(DATA | VARIABLE | ABSOLUTE)
        REPORT_ID(2)
            USAGE(2)
            LOGICAL_MIN(0)          
            LOGICAL_MAX(255)        
            REPORT_SIZE(8)          
            REPORT_COUNT(64)        
            OUTPUT(DATA | VARIABLE | ABSOLUTE)
        REPORT_ID(3)
            USAGE(3)
            LOGICAL_MIN(0)
            LOGICAL_MAX(255)
            REPORT_SIZE(8)
            REPORT_COUNT(64)
            OUTPUT(DATA | VARIABLE | ABSOLUTE)
        REPORT_ID(4)
            USAGE(4)
            LOGICAL_MIN(0)
            LOGICAL_MAX(255)
            REPORT_SIZE(8)
            REPORT_COUNT(64)
            OUTPUT(DATA | VARIABLE | ABSOLUTE)
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION              */
};
1

There are 1 answers

3
Nipo On

HID uses interrupt IN/OUT to convey reports. In USB, Interrupt transfers are polled by host every 1 ms. Every time endpoint is polled, it may yield a 64-byte report (for Low/Full speed). That's probably where you get the 64kB/s figure from. Actually, limit is 1k report / second. Also note these limits are different for High-speed and Super-speed devices.

Report descriptor is one thing. What you actually send as interrupt-IN is something else. It should match, but this is not enforced by anything. You should probably look into the code that builds the interrupt IN transfer payload.

Side note: all you seem interested in is to send arbitrary chunks of data, then HID is probably not the relevant profile. Using bulk endpoints looks more appropriate (and you'll not be limited by interrupt endpoint polling rate).