cancel
Showing results for 
Search instead for 
Did you mean: 

Issues in Firmware Package "STCubeFW_F4_V1.25.0" for USB HID Code Generation

BPaik
Senior

Using Firmware Package "STCubeFW_F4_V1.25.0" in CubeMX appears to cause various issues with generating code for USB HID mode. I was originally able to get a USB HID project working by following the USB HID Custom Device Lab tutorial (found here https://www.youtube.com/watch?v=3JGRt3BFYrM&t=325s) using firmware package 1.24.1 with the STM32F405. USB functionality was broken after migrating my project to V1.25.0, which causes my USB PC Host to report "Transfer error on interrupt endpoint: Operation timed out". In order to verify the problem was in fact part of the V1.25.0 package, I repeated the ST tutorial linked above with both versions of the firmware package and verified that the project is able to communicate with the HID_Terminal .exe application in V1.24.1 but crashes the application with the V1.25.0 version.

Some other issues I noticed using CubeMX include the following:

  • Setting the "CUSTOM_HID_FS_BINTERVAL" parameter in CubeMX does not have any effect on the code. The corresponding definition in "usbd_customhid.h" does not change regardless of what the value is set to.
  • After following the tutorial to get my baseline project working, CubeMX will revert all the changes every time I regenerate my code to configure other peripherals. This is extremely frustrating and tedious to fix, and so far I haven't found a way to prevent this from happening. I would have expected the number of bytes transmitted to be configurable in CubeMX rather than fixed at 2 bytes. At the very least the default generated code should match the tutorial - as buffer pointer and 64 byte transfers are much more usable than the "state" and "event_idx" used in the "CUSTOM_HID_OutEvent_FS" routines.
9 REPLIES 9
HLee.21
Associate III

This seems to be a regression. I'm having the exact same issue on an STM32L073CBTx with Firmware Package STM32Cube FW_L0 V1.12.1. After adapting the generated code like in the youtube video: HID_terminal.exe works two times (sends and recieves data by clicking on Send-Button) but fails after the secound time with an error "Operation timed out".

The failure is reproducible on Linux with a similar app.

@ST: After one and a half year, please recreate the issue and fix it.

BPaik
Senior

I've only tried this on the G4 so far, but here are a few things that got USB HID working after generating CubeMX code (some of this will be a repeat of information in the tutorial):

  1. Change CUSTOM_HID_EPIN_SIZE and CUSTOM_HID_EPOUT_SIZE to 0x40 in usbd_customhid.h
  2. Change the "OutEvent" function pointer in usbd_customhid.h to only have the state pointer as an input: int8_t (* OutEvent)(uint8_t *state)
  3. Update the OutEvent function calls in usbd_customhid.c to only pass the buffer pointer
  4. Make edits to the CUSTOM_HID_ReportDesc_FS in usb_hid_api.h as described in the tutorial video
  5. Update CUSTOM_HID_OutEvent_FS in usb_hid_api.h to only have the state pointer as an input
  6. Replace the contents of CUSTOM_HID_OutEvent_FS with the code below (g_usb_rx_bytes and g_usb_tx_bytes are 64 byte arrays for RX and TX data respectively).

 memcpy(g_usb_rx_bytes, state, 64);

 USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, g_usb_tx_bytes, 64);

 USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS);

 return (USBD_OK);

HLee.21
Associate III

USBD_CUSTOM_HID_ReceivePacket(&hUsbDeviceFS); <- this isn't in the tutorial, does that make the difference?

It did for me on the G4. I'm not sure if it will work for you but let me know if it does.

HLee.21
Associate III

Looks a bit odd, but I'll test it tomorrow and get back to you. Thanks for your quick input!

HLee.21
Associate III

In L0 there is no USBD_CUSTOM_HID_ReceivePacket(). Firmware Version V1.12.0 from year 2020 does work, ... so I guess I have to stick to that. But it would be nice if ST could fix the regression.

Open the file "stm32l0xx_hal_pcd.c" around line 1873 and change the if statement to the following:

    /* Manage all non bulk transaction or Bulk Single Buffer Transaction */

    if ((ep->type != EP_TYPE_BULK) ||

      ((ep->type == EP_TYPE_BULK) && ((wEPVal & USB_EP_KIND) == 0U)))

Let me know if that works.

HLee.21
Associate III
--- a/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_pcd.c
+++ b/Drivers/STM32L0xx_HAL_Driver/Src/stm32l0xx_hal_pcd.c
@@ -1851,28 +1851,6 @@ static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
         /* clear int flag */
         PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
 
-        if (ep->type != EP_TYPE_BULK)
-        {
-          ep->xfer_len = 0U;
-
-          if ((wEPVal & USB_EP_DTOG_TX) != 0U)
-          {
-            PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
-          }
-          else
-          {
-            PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 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 */
-        }
-        else
-        /* Manage Bulk Single Buffer Transaction */
         if ((ep->type != EP_TYPE_BULK) ||
                              ((ep->type == EP_TYPE_BULK) && ((wEPVal & USB_EP_KIND) == 0U)))
         {

I had to apply the above patch to get it working - but I have 0 idea why it does! - an answer from ST would be great.

HLee.21
Associate III

the ST code seems obviously wrong: They double test for ep->type != EP_TYPE_BULK:

if (a) {
...
} else if (a || b) {
 ...
}

... @ST: any comment???