I own a stm32f4 discovery board, for which a demonstration project can be downloaded here: http://www.st.com/web/en/catalog/tools/PF257904

This demo consists of software to use the board as a usb hid mouse, using the accelerometer to control the mouse movement. I want to change this into a gamepad, for now I'm leaving the other parts of the descriptor the same, so I only changed the usage from 0x09,0x02 (usage: mouse) to 0x09 , 0x09 (usage: gamepad). (these values can be found in the usb_hid_core file)

But after this change the computer still sees it as a mouse, but one that is not functioning correctly. What else should I change?

Any help would be greatly appreciated, I have been trying all kinds of things for weeks now, but nothing seems to work.

the usb_hid_core file can be found in this file at this location:


(i was under the impression that all that i would have to change would be this line in the descriptor to make it look as a gamepad, since the data that is send will still comply with the descriptor then, i also tried changing it to a very simply device that sends just one byte before changing it into a a gamepad, and i tried changing various other things like hid class). This is how it shows up after i change it to a gamepad (but is doens't work then): http://hmsprojects.com/USB-invoerapparaat.html


1 Answer 1


You need to change few others things to make it work as a gamepad. In usbd_hid_core.c you need to change :

 0x02,         //nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse

to the 0x00 value.

Other thing, the report descriptor has to be changed, this is mine for a 3-buttons 2-axis gamepad, (you can change it to add button or anything else with the HIDtool) :

  0x05,   0x01, // USAGE_PAGE (Generic Desktop)
  0x09,   0x05, // USAGE (Game Pad)
  0xA1,   0x01, // COLLECTION (Application)

  0xA1,   0x00, // COLLECTION (Physical)
  0x05,   0x09, // USAGE_PAGE (Button)
  0x19,   0x01, // USAGE_MINIMUM (Button 1)
  0x29,   0x03, // USAGE_MAXIMUM (Button 3)

  0x15,   0x00, // LOGICAL_MINIMUM (0)
  0x25,   0x01, // LOGICAL_MAXIMUM (1)
  0x95,   0x03, // REPORT_COUNT (3)
  0x75,   0x01, // REPORT_SIZE (1)

  0x81,   0x02, // INPUT (Data,Var,Abs)
  0x95,   0x01, // REPORT_COUNT (1)
  0x75,   0x05, // REPORT_SIZE (5)
  0x81,   0x07, // INPUT (Cnst,Var,Rel)

  0x05,   0x01, // USAGE_PAGE (Generic Desktop)
  0x09,   0x30, // USAGE (X)
  0x09,   0x31, // USAGE (Y)

  0x15,   0x81, // LOGICAL_MINIMUM (-127)
  0x25,   0x7F, // LOGICAL_MAXIMUM (127)
  0x75,   0x08, // REPORT_SIZE (8)
  0x95,   0x02, // REPORT_COUNT (2)

  0x81,   0x02, // INPUT (Data,Var,Abs)
  0xC0,   0xC0  // END_COLLECTION x2

The size of the report descriptor has changed so modify it in usbd_hid_core.c :


Now the gamepad would be recognized. You only need to send a 3 bytes report (the first for the button, et the two others for the axis). For a test you could do it by using this code in stm32xx_it.c :

static uint8_t *USBD_HID_GetPos (void)
static uint8_t HID_Buffer[3] = {0};

static int8_t val_abs_x=0;
static uint8_t sens_x=0;

HID_Buffer[1] = 0;
HID_Buffer[2] = 0;

// X move
if (val_abs_x > 120)
    sens_x = 0; // --
else if (val_abs_x < -120)
    sens_x = 1; // ++

if (sens_x == 1)
    val_abs_x = val_abs_x + 3;
    val_abs_x = val_abs_x - 3;

HID_Buffer[1] = val_abs_x;
HID_Buffer[2] = 0;

return HID_Buffer;

Anf finally change the line (in the same file) :

  USBD_HID_SendReport (&USB_OTG_dev, buf, 4);

to :

  USBD_HID_SendReport (&USB_OTG_dev, buf, 3);

This should work well on the STM32f4 discovery board. If not try change the PID by adding 1 (like 0x5711) in usbd_desc.c).

  • \$\begingroup\$ I only want to thank you for your reply, because it has been very useful for me to modify usb descriptor for gamepad on STM32F103C8T6, the key was changing the PID adding 1. thank you very much! \$\endgroup\$ Dec 27, 2016 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.