cancel
Showing results for 
Search instead for 
Did you mean: 

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

SPfis.1
Associate II

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
         {

11 REPLIES 11
Pavel A.
Evangelist III

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

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 .