How to send USB HID Reports without guessing the HAL_Delay()?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-12 1:36 AM - edited ‎2024-09-12 1:40 AM
I want to send USB HID Reports as fast as the MCU or the USB protocol allows.
In order to send an USB HID Report on an STM32F103 I'm doing something like:
USBD_HID_SendReport(&hUsbDeviceFS, (u8*)&report,sizeof(report));
HAL_Delay(some_delay);
or even:
USBD_HID_SendReport(&hUsbDeviceFS, (u8*)&report,sizeof(report));
for(volatile int k=0; k<some_other_delay; ++k) asm volatile("nop");
but it's obviously dicey and suboptimal to "guess" at the correct sleep value (which in my case changes from situation to situation, and also depending on the size of the USB HID Report).
What I really want is to do is something like:
for(int i=0; i<N; ++i) USBD_HID_SendReport(&hUsbDeviceFS, (u8*)&report,sizeof(report));
and have it just work (which it currently doesn't).
I tried modifying USBD_HID_SendReport() from the original:
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef* pdev, uint8_t* report, uint16_t len){
USBD_HID_HandleTypeDef* hhid = (USBD_HID_HandleTypeDef*)pdev->pClassData;
if(pdev->dev_state==USBD_STATE_CONFIGURED){
if(hhid->state==HID_IDLE){ // if it's not idle, then it discards!
hhid->state = HID_BUSY;
USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len);
}
}
return USBD_OK;
}
to the following:
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef* pdev, uint8_t* report, uint16_t len){
USBD_HID_HandleTypeDef* hhid = (USBD_HID_HandleTypeDef*)pdev->pClassData;
if(pdev->dev_state==USBD_STATE_CONFIGURED){
while(hhid->state!=HID_IDLE) asm volatile("nop");
hhid->state = HID_BUSY;
USBD_LL_Transmit(pdev, HID_EPIN_ADDR, report, len);
}
return USBD_OK;
}
but it's not working as intended.
So how I can achieve the desired result of sending USB HID Reports as fast as possible, without any manual wait, ie. something like:
for(int i=0; i<N; ++i) USBD_HID_SendReport(&hUsbDeviceFS, (u8*)&report,sizeof(report));
Solved! Go to Solution.
- Labels:
-
USB
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-13 7:27 AM
To clarify, we check if the size of the first bits in HID_Buffer (which indicates the size of the remaining data) is zero. If it is, we can proceed to call SendReport again.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-12 2:37 AM
False alarm; I don't know what I was doing wrong. This actually works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-12 2:40 AM - edited ‎2024-09-12 2:40 AM
But I still wonder if there's something wrong with this approach.
I may have found a situation where it's not working as intended.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-13 2:18 AM - edited ‎2024-09-13 7:21 AM
I suggest ensuring that the endpoint is ready before sending the next report.
I rephrase my answer:
>> In HID class, we need to check first item in report descriptor, the remaining size of data or query the poll time from EP descriptor using USBD_HID_GetPollingInterval()
Also, you may need to check USB traffic if you observe NAKs from device side to make sure if the device is limiting the throughput.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-13 5:36 AM - edited ‎2024-09-13 5:38 AM
Hi @FBL how can I add a callback or use a SW flag?
How can I check (on the USB device) that the transmission is complete or that the USB endpoint is ready?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-09-13 7:27 AM
To clarify, we check if the size of the first bits in HID_Buffer (which indicates the size of the remaining data) is zero. If it is, we can proceed to call SendReport again.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
