STM32 And Custom USB HID Device? Yes Please!

I (Domen) finaly managed to set up USB HID device on STM32L1 Discovery board. It is not a simple HID Keyboard. It is a composite USB HID device consisting: keyboard, system power controls, consumer device controls (multimedia buttons), application launcher/handler buttons and gamepad.

 

Base code and initialization was generated using CubeMX code generation tool and afterwards modified to suit all “hid usages” as mentioned before. We can send keys, control audio/video player, launch apps (and more) with four available buttons. Imagine the possibilities with multiple buttons, each sending custom report.
Currently, there is a setup menu managed with LCD, rotary encoder and setup button, supporting:
– shortcut mode: CTRL + ALT + DEL, (send in one command)
and
– pattern mode: WIN KEY, 1, CTRL, A,  DELETE (sending each key separate, with specified delay).

 



 

For all geeks out there:
It is USB HID device with one configuration descriptor, one interface description and one endpoint (besides EP0). All reports are merged in single report descriptor separated with ReportID() attributes. Currently STM CubeMX doesn’t support multiple interface descriptors and it is definitely not easy to implement new endpoint. But, for simple tasks like implementing keyboard, mouse or other simple hid devices, base code is satisfactory. To make your own USB HID device:

  • Generate USB HID DEVICE with CubeMX (not CUSTOM USB HID DEVICE).
  • You need to edit these files to implement your custom report descriptor:
    • “usbd_hid.c”
      • Edit: USBD_HID_CfgDesc[…] to implement specific device.
        0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
        0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/
      • Edit: HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE];
        Here is where your custom report descriptor should be.
    • “usbd_hid.h”
      • Change: HID_MOUSE_REPORT_DESC_SIZE
      • Change endpint IN size according to your report size: HID_EPIN_SIZE
    • “main.c”
      • Include “usbd_hid.h”
      • Set up report arrays according to the report descriptor in “usbd_hid.c”
      • Send reports using: USBD_HID_SendReport(&hUsbDeviceFS, …, …);

I know, this “guide” is quite useless for complete beginners. It is hard to start programming USB without at least basic knowledge, so here is a couple of things you can read in advance. You should really know at least something about general USB structure, configuration, interface, device class and report descriptors, USB HID transfer protocol (bulk, interrupt, …), …

 

Comments are closed