cancel
Showing results for 
Search instead for 
Did you mean: 

converting STM32F4 discovery USB mouse example to gamepad

hsmeitink9
Associate II
Posted on August 28, 2013 at 23:05

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 now 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, but nothing seems to work.

I have included the file that I linked to, the usb_hid_core file can be found in this file at this location: 

stsw-stm32068\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32_USB_Device_Library\Class\hid\src

#stm32f4-hid-mouse-gamepad
8 REPLIES 8
hsmeitink9
Associate II
Posted on September 02, 2013 at 16:16

Nobody?

Posted on September 03, 2013 at 03:36

Evidently

It's also not appropriate to attach a copy of a 31 MB file to the forum, where a

http://www.st.com/st-web-ui/static/active/en/st_prod_software_internet/resource/technical/software/firmware/stsw-stm32068.zip

would be quite adequate. Your files, or a patch, would be far more effective.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
hsmeitink9
Associate II
Posted on September 03, 2013 at 17:19

Thanks for the tip.

I'm still stuck, i managed to alter the mouse descriptor, but can't get it to work as a gamepad, this is what my analyzer tells me:

http://hmsprojects.com/USB-invoerapparaat.html

infoinfo991
Associate III
Posted on September 04, 2013 at 23:16

Try this descriptor instead

    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)

    0x09, 0x05,                    // USAGE (Gamepad) // use 0x09, 0x04 for USAGE (Joystick)

    0xa1, 0x01,                    // COLLECTION (Application)

    0xa1, 0x00,                    //   COLLECTION (Physical)

    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,                          //     END_COLLECTION

    0xa1, 0x00,                    //   COLLECTION (Physical)

    0x09, 0x32,                    //     USAGE (Z) // use 0x09, 0x30 for USAGE (X) // use 0x09, 0x33 for USAGE (Rx)

    0x09, 0x35,                    //     USAGE (Rz) // use 0x09, 0x31 for USAGE (Y) // use 0x09, 0x34 for USAGE (Ry)

    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,                          //     END_COLLECTION

    0xa1, 0x00,                    //   COLLECTION (Physical)

    0x05, 0x09,                    //     USAGE_PAGE (Button)

    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)

    0x29, 0x10,                    //     USAGE_MAXIMUM (Button 16)

    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)

    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)

    0x75, 0x01,                    //     REPORT_SIZE (1)

    0x95, 0x10,                    //     REPORT_COUNT (16)

    0x81, 0x02,                    //     INPUT (Data,Var,Abs)

    0xc0,                          //     END_COLLECTION

    0xc0                           // END_COLLECTION

hsmeitink9
Associate II
Posted on September 07, 2013 at 18:19

I tried it, but is still shows as a non functional mouse. I went trough all the files, but I can't find anything, is there a common reason why just changing the usage page and nothing else might not work?

hsmeitink9
Associate II
Posted on September 22, 2013 at 14:06

Nobody?

sebastien2
Associate II
Posted on April 12, 2014 at 22:56

Maybe you need to change the PID in the descriptor, to be sure the computer didn't use the last descriptor without reading the new one?

sebastien2
Associate II
Posted on May 05, 2014 at 19:56

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) :

    __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =

    {

      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 :

    #define HID_MOUSE_REPORT_DESC_SIZE    48

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; // --

        HID_Buffer[0]=0;

    }

    else if (val_abs_x < -120)

    {

        sens_x = 1; // ++

        HID_Buffer[0]=1;

    }

    

    if (sens_x == 1)

        val_abs_x = val_abs_x + 3;

    else

        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.