Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Custom HID hack

  1. #1
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    50

    Custom HID hack

    Hi,

    I've been digging around Teensy core to be able to do any custom HID device that can be configured in the sketch code.

    I found a way (an ugly one I think), by adding an empty new HID interface like one would do to create a new HID type (by touching usb_desc.h, usb_desc.c, etc...), except that the report descriptor has to be given by the main application.

    Here is the principle :

    Normaly in usb_desc.c I should have :

    #ifdef CUSTOM_HID_INTERFACE
    {0x2200, CUSTOM_HID_INTERFACE, custom_hid_report_desc, sizeof(custom_hid_report_desc) },
    {0x2100, CUSTOM_HID_INTERFACE, config_descriptor + CUSTOM_HID_DESC_OFFSET, 9},
    #endif

    where custom_hid_report_desc is the report descriptor of my HID device, but instead, I've put :

    #ifdef CUSTOM_HID_INTERFACE
    {0x2200,CUSTOM_HID_INTERFACE,config_descriptor + CUSTOM_HID_INTERFACE_DESC_POS,0xffff},
    {0x2100, CUSTOM_HID_INTERFACE, config_descriptor + CUSTOM_HID_DESC_OFFSET, 9},
    #endif

    and I've written a function that looks for an entry with the size == 0xffff (I told you it's ugly), and when I find it, I overwrite the device infos, and put my custom descriptor address and length instead, then I patch the interface infos and put my custom tx and rx report sizes, etc...
    I've used similar hacks to patch the vendor and product ids, bcdDevice, and device name.

    I added a hook at the beginning or usb_init(), just before usb_init_serialnumber(), so I can patch all these descriptors before the usb initialization takes place.

    It works. I've created a Custom HID and a Custom HID + Serial device (added in boards.txt)

    In the end, in the user sketch, you just have to put these few initialisations (this is an example):

    const uint8_t customHidReportDescriptor[] = {put your report descriptor here};
    const uint8_t inReportSize= your_in_report_size;
    const uint8_t outReportSize= your_out_report_size;
    const uint8_t productName[] = {14,3,'C',0,'u',0,'s',0,'t',0,'o',0,'m',0};

    void usb_init_cutomhid()
    {
    usb_set_custom_hid_report_descriptor(customHidRepo rtDescriptor, sizeof(customHidReportDescriptor), inReportSize, outReportSize);
    usb_set_product_name((struct usb_string_descriptor_struct *)&productName);
    usb_set_device_ids(0x16C0,0x748d,0x4541);
    }

    You'll find all the modified core files along with an example sketch here :
    http://www.nodeblue.org/downloads/te...om_hid_mod.zip
    I tried to avoid modifying the core as much as I can, so things might not be at the right place.

    Just copy the hardware folder to your Arduino ide (tested with Arduino 1.8.5 and TeensyDuino 1.41, I've put only the files I've changed), and use the test_custom_hid sketch to test an example with 8 buttons and 3 analog axis.

    Now I have 2 problems:

    1) The emulated serial doesn't work, when I open the serial monitor it says it's online, but nothing is received (in the example I print a number every seconds).

    I have no clue of where to search, I've using USBLyzer to look are USB traffic, but no packets seems to be sent to the PC.

    2) With the SEREMU_INTERFACE having index 0 and CUSTOM_HID_INTERFACE having index 1 (like in the zip i'm giving), the debug window in the game controller properties on windows is empty, while it is seen by other tools, like http://html5gamepad.com/. If I put SEREMU_INTERFACE index to 1 and CUSTOM_HID_INTERFACE to 0, the under windows it is seen (but then USBLyzer complains, saying that interfaces index should be increasing).

    Note that changing pid or bcdDevice to avoid Windows USB info cache problems doesn't solve anything (don't know what the hell windows is doing with USB device caching, anyone knows where to clean registry for that ?)

  2. #2
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    50
    Problems 1) and 2) solved by using the same Product ID as the standard Keyboard/Mouse/Joystick USB Type = 0x0482.
    I guess the teensy gateway fake serial expects only certain VID & PID.

    However since windows had already seen this USB device, I still had the name "Keyboard/Mouse/Joystick" in the game controllers window (joy.cpl), and the icon of a keyboard in the device/printers window instead of a game pad.
    I'm on Windows 10 by the way.
    I removed the device in the device manager, unplugged / replugged, the game pad icon came back.
    I went in windows registry, to :
    HKEY_CURRENT_USER\System\CurrentControlSet\Control \MediaProperties\PrivateProperties\Joystick\OEM

    I deleted VID_16C0&PID_0482, and then the name in the game controllers window changed to "Custom".

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,463
    Quote Originally Posted by Etienne View Post
    I guess the teensy gateway fake serial expects only certain VID & PID.
    Yup. Likewise for the new teensy_serialmon in the latest beta. They don't talk to unknown USB devices.

  4. #4
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    50
    Ok, I merged the custom hid code in the latest beta, it works well. Great improvement in compile time
    I did my own fake serial monitor in which I can choose the PID I use, so that's ok.
    However I still have a problem, the auto-upload feature of the Teensy loader seems to work the same way as the serial monitor, it doesn't work if I use an unknown PID.
    Is it possible to specify a vid/pid or a serial number to the teensy_post_compile command ? (I'm not using Arduino IDE to compile/upload).
    I've looked a teensy loader cli, but could not find any option for that neither. I mean, Is there a way to upload a .hex to a specific Teensy ? (the problem arise also when having several Teensy boards connected).

    If I use a known PID, like the one for the keyboard/mouse/joystick 0x0482, I have windows 8 that uses cached info for the device and it's not recognized as it should.
    Do you know how to really clean windows registry about hid ? I tried many things but none worked, including removing the device in the devices/printers window.
    The registry key I found in the previous post is only about the name. I found other keys but I could not delete them (in HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Enum\USB\V ID_16C0&PID_0482) the
    Last edited by Etienne; 03-23-2018 at 10:51 AM.

  5. #5
    Member Etienne's Avatar
    Join Date
    Mar 2016
    Location
    Ardeche, France
    Posts
    50
    Ok now I send a Hid feature request with the magic sequence to the seremu interface, so I can reboot the board I want
    So the only problem left seems to be windows usb caching mystery

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •