Skip to main content
SPfis.1
Associate II
June 24, 2021
Question

What is the issue with the USB Custom HID Low Level Driver?

  • June 24, 2021
  • 10 replies
  • 4863 views

For a STM32L433CB I generated the Custom HID code using CubeMX version 6.2.1 and the Cube FW_L4 V1.17.0

The CUSTOM_HID_FS_BINTERVAL   is set to 5ms and I placed a Custom HID Descriptor. Also I adjusted USBD_CUSTOMHID_OUTREPORT_BUF_SIZE and USBD_CUSTOM_HID_REPORT_DESC_SIZE  so it fits to my descriptor. After the first Message is transmitted, using the function "USBD_CUSTOM_HID_SendReport" I can see in a USB analyzer an endless stream of URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER frames with the expected size. Roughly every 5ms there is a new message.

After searching through the Cube generated HAL code I found that in the file "stm32l4xx_hal_pcd.c" quit at the bottom of the function "PCD_EP_ISR_Handler" the function HAL_PCD_EP_DB_Transmit is called all the time. This function handles Endpoints of the type "interrupt" but is in my opinion designed to handle endpoints which are using doublebuffering. But our HID Endpoint is singlebuffered as we can see in the file "usdb_conf.c".

After I wrote my custom handler for USB_EP_CTR_TX Interrupts I got it to work.

For now I think I fixed the issue.

Did anyone had the same issue? Maybe I can help to fix it...

EDIT:

Since my code works after some tests I post the patch here. Keep in mind that I use it to always transmit 64byte "single" frames and I have a transmission timeout mechanism in my application.

So in the file stm32l4xx_hal_pcd.c in the function " HAL_StatusTypeDef PCD_EP_ISR_Handler" at line number 2500 right after:

 else
 {
 /* Transfer is not yet Done */
 ep->xfer_buff += TxByteNbre;
 ep->xfer_count += TxByteNbre;
 (void)USB_EPStartXfer(hpcd->Instance, ep);
 }
 }

I inserted the following code:

 else if((ep->type == EP_TYPE_INTR) && ep->doublebuffer == 0) {
 /* multi-packet on the NON control IN endpoint */
 TxByteNbre = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
 if (ep->xfer_len > TxByteNbre)
 {
 ep->xfer_len -= TxByteNbre;
 }
 else
 {
 ep->xfer_len = 0U;
 }
 
 /* Zero Length Packet? */
 if (ep->xfer_len == 0U)
 {
 /* TX COMPLETE */
 #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
 hpcd->DataInStageCallback(hpcd, ep->num);
 #else
 HAL_PCD_DataInStageCallback(hpcd, ep->num);
 #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
 }
 }

Here again as an applicable patch:

diff --git a/stm32l4xx_hal_pcd.c b/stm32l4xx_hal_pcd.c
index 3a3d967342b9560ad96b0c19c829dc800c8ee527..68fd199979281a75b840ae095286093895fa01f0 100644
--- a/stm32l4xx_hal_pcd.c
+++ b/stm32l4xx_hal_pcd.c
@@ -2497,6 +2497,29 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
 (void)USB_EPStartXfer(hpcd->Instance, ep);
 }
 }
+ else if((ep->type == EP_TYPE_INTR) && ep->doublebuffer == 0) {
+ /* multi-packet on the NON control IN endpoint */
+ TxByteNbre = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
+ if (ep->xfer_len > TxByteNbre)
+ {
+ ep->xfer_len -= TxByteNbre;
+ }
+ else
+ {
+ ep->xfer_len = 0U;
+ }
+
+ /* Zero Length Packet? */
+ if (ep->xfer_len == 0U)
+ {
+ /* TX COMPLETE */
+ #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
+ hpcd->DataInStageCallback(hpcd, ep->num);
+ #else
+ HAL_PCD_DataInStageCallback(hpcd, ep->num);
+ #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
+ }
+ }
 /* Double Buffer Iso/bulk IN (bulk transfer Len > Ep_Mps) */
 else
 {

This topic has been closed for replies.

10 replies

June 25, 2021

I have exactly the same problem. I have implement a Custom Hid project, just like yours, and I'm able to send my message only once.

I don't have the knowledge to analyze the usb stack, so I have stalled the project.

I would like to mention that the same project was working correctly with a previous version of the stack (I don't remember the version).

SPfis.1
SPfis.1Author
Associate II
June 25, 2021

Yes, it was the same for me. With an older Cube Package version it worked. Now a day later and after some more testing, my patch in the low level driver still works fine.

June 25, 2021

Can you share your patch?​

SPfis.1
SPfis.1Author
Associate II
June 25, 2021

done. see above.

June 25, 2021

I will try it on Monday and I will come back with the result. Thank you very much.​

June 28, 2021

I have applied the patch and everything is working fine :grinning_face::grinning_face::grinning_face:. Thank you very much.

SPere.5
Visitor II
February 25, 2022

Hello friend,

Same problem with uC STM32F072 -> In my case the libraries generated for the F versions are quite different than for the L, I tried your patch but it did not work in my case (I guess for F versions), I tried to modify the STM library but I do not reach this level. In my case I can send DATA2 times then the function stops working a beakpoint in the callback and after 2 send reports, the STM32 does not breaks in the callback anymore. I tried your modification and I feel the problem is there, maybe you can help me!. Two weeks on this I am a bit desperate.

Greetings.

SPere.5
Visitor II
February 27, 2022

I managed to make it work, compiled the same project with previous version of STMCubeMX (now I used latest version from 5.xx release. it is 5.2.0) I generated the code for TrueStudio, the previous than used in CubeIDE and imported the project in CubeIDE, finally it is working. The problem was in the latest release of STM32CubeIDE they are not managing properly HAL libraries. Of course a STMicroelectronics mistake.

ATamb.2
Associate II
February 14, 2023

i am using nucleo stm32f67zi board. i am facing same issue and above solution is not working for me. I want to know, how you make it work in cube ide. the function PCD_GET_EP_TX_CNT is not available .

PArno.1
Visitor II
October 10, 2022

Thank you, this was a life-saver. I ran into the same issue using custom HID on STM32G491 and the above fix worked nicely.

Pavel A.
Super User
October 10, 2022

@Hana Slimi​ can you look at this please? and at this.