Page 1 of 1

Configuring a Composite HID Device

Posted: Tue Feb 15, 2022 9:23 pm
by dstevens
I'm working on a custom USB adapter for an arcade fight stick based on a STM32F411.

The fight stick has 2 joysticks, 14 buttons, 2 spinners, and a trackball.

I've split the controls into three composite HID devices. 2 joysticks (with 7 buttons and 1 spinner each) and one mouse device for the trackball.

On Windows everything works great, but I can't get it working fully in MiSTer.

When I attempt to define the second joystick (using the system settings menu) the only buttons I can define are from the first joystick. It doesn't appear MiSTer is treating each composite device as a separate device.

I'm new to this so I hope I'm using the proper terminology. Any ideas what I should try next?

Thanks

EDIT: Here is the HID descriptor I'm using...

Code: Select all

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x04,        // Usage (Joystick)
0xA1, 0x01,        // Collection (Application)
0xA1, 0x00,        //   Collection (Physical)
0x85, 0x01,        //     Report ID (1)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x08,        //     Usage Maximum (0x08)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x95, 0x10,        //     Report Count (16)
0x75, 0x01,        //     Report Size (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x37,        //     Usage (Dial)
0x15, 0x80,        //     Logical Minimum (-128)
0x25, 0x7F,        //     Logical Maximum (127)
0x95, 0x01,        //     Report Count (1)
0x75, 0x08,        //     Report Size (8)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38,        //     Usage (Wheel)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x95, 0x01,        //     Report Count (1)
0x75, 0x08,        //     Report Size (8)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x01,        //     Usage (Pointer)
0xA1, 0x00,        //     Collection (Physical)
0x09, 0x30,        //       Usage (X)
0x09, 0x31,        //       Usage (Y)
0x15, 0xFF,        //       Logical Minimum (-1)
0x25, 0x01,        //       Logical Maximum (1)
0x95, 0x02,        //       Report Count (2)
0x75, 0x08,        //       Report Size (8)
0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0xC0,              //   End Collection
0xC0,              // End Collection

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x04,        // Usage (Joystick)
0xA1, 0x01,        // Collection (Application)
0xA1, 0x00,        //   Collection (Physical)
0x85, 0x02,        //     Report ID (2)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x08,        //     Usage Maximum (0x08)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x95, 0x10,        //     Report Count (16)
0x75, 0x01,        //     Report Size (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x37,        //     Usage (Dial)
0x15, 0x80,        //     Logical Minimum (-128)
0x25, 0x7F,        //     Logical Maximum (127)
0x95, 0x01,        //     Report Count (1)
0x75, 0x08,        //     Report Size (8)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38,        //     Usage (Wheel)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x95, 0x01,        //     Report Count (1)
0x75, 0x08,        //     Report Size (8)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x01,        //     Usage (Pointer)
0xA1, 0x00,        //     Collection (Physical)
0x09, 0x30,        //       Usage (X)
0x09, 0x31,        //       Usage (Y)
0x15, 0xFF,        //       Logical Minimum (-1)
0x25, 0x01,        //       Logical Maximum (1)
0x95, 0x02,        //       Report Count (2)
0x75, 0x08,        //       Report Size (8)
0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0xC0,              //   End Collection
0xC0,              // End Collection

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x02,        // Usage (Mouse)
0xA1, 0x01,        // Collection (Application)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x85, 0x03,        //     Report ID (3)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
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, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xC0,              // End Collection

Re: Configuring a Composite HID Device

Posted: Wed Feb 16, 2022 8:18 am
by amstan
I would do `evtest` over ssh and debug in there if you see each of the 3 devices.

Re: Configuring a Composite HID Device

Posted: Thu Feb 17, 2022 10:04 pm
by dstevens
I made some progress. The joysticks / buttons / spinners all work. Mouse still doesn't work.

Apparently in Linux composite HID devices need the HID_QUIRK_MULTI_INPUT attribute set in drivers/hid/usbhid/hid-quirks.c to show up as multiple devices. I didn't want to recompile the kernel so for now I'm using the ID of a device already in the list.

EDIT: Scratch that. I get multiple devices now (using evtest on a raspberry pi) but in MiSTer joystick 1 and 2 seem to map to the same input. In other words pressing right with either joystick 1 or joystick 2 registers as a joystick 1 press.

Re: Configuring a Composite HID Device

Posted: Thu Feb 17, 2022 10:52 pm
by aberu
MiSTer support for dual joystick as "Player 1" and "Player 2" on one USB device is I think non-existent unless Sorg updated that the last time I looked into it. Pretty sure Player 1 gets bound to one ID and player 2 gets bound to another ID. The X-Arcade dual stick that people got working before worked because it showed up as two USB devices I think.

Re: Configuring a Composite HID Device

Posted: Fri Feb 18, 2022 4:04 am
by dstevens
Mentioning the X-Arcade dual stick was the hint needed. I was able to search how people got it working.

By setting no_merge_vid and no_merge_pid in MiSTer.ini to your composite device's vid/pid it will prevent the merging of input devices. So the joysticks are working now.

Now for the trackball...

Re: Configuring a Composite HID Device

Posted: Sat Feb 19, 2022 12:50 am
by bankshot
Hi dstevens,

Let me know if you have any luck with the trackball as a separate HID. My 2-player arcade stick w/ trackball unit has just the trackball as its own separate HID/USB device from the stick and all the buttons. Because of this, the trackball is useless because it has no buttons associated with it. MiSTer does not let you combine controls from multiple HIDs within the same core at the same time. Because of this, my only choice is to replace the brain of the entire arcade stick to one that I can somehow integrate with the rest of the controls on the same HID. The trackball will need to be hacked and I'm having trouble finding good info on how to do this.

Re: Configuring a Composite HID Device

Posted: Sat Feb 19, 2022 6:26 am
by dstevens
bankshot wrote: Sat Feb 19, 2022 12:50 am Let me know if you have any luck with the trackball as a separate HID. My 2-player arcade stick w/ trackball unit has just the trackball as its own separate HID/USB device from the stick and all the buttons. Because of this, the trackball is useless because it has no buttons associated with it. MiSTer does not let you combine controls from multiple HIDs within the same core at the same time. Because of this, my only choice is to replace the brain of the entire arcade stick to one that I can somehow integrate with the rest of the controls on the same HID. The trackball will need to be hacked and I'm having trouble finding good info on how to do this.
I had the same issue, and I wanted to add a couple of spinners for the Atari 7800/2600 core. I also like the idea of one controller for everything.

I'm using a Micro Center Atari Fight Stick. The included trackball had it's own embedded controller. I replaced the 2.5" trackball with a SuzoHapp 3" trackball (no embedded controller). It is almost a perfect fit. The bolt pattern is identical, but I had to widen the ball opening by maybe a millimeter.

I did get the mouse working. Under Linux (not Mac or Windows) the Mouse HID descriptor appears to require some buttons defined otherwise it doesn't work without a custom driver.

Unfortunately I'm not happy with the performance. I think I'm flooding the USB buffer with too much data. Before adding mouse and spinners the latency seemed great. With spinners and the trackball all moving at the same time I see slowdowns.

I'm likely doing some dumb things so there is still hope.

EDIT: Yeah dumb things confirmed. I had the pulses per revolution for the spinners set to 20 instead of 1200 so I was sending way more data than necessary.

Re: Configuring a Composite HID Device

Posted: Sun Feb 20, 2022 3:17 am
by bankshot
Ok now it makes sense, I have the same Micro Center arcade stick as you. I ended up purchasing a Teensy 3.5 board from Micro Center as well to replace the Xinmo board and was going to wire the trackball to that, if I could figure out how to remove the embedded controller from the stock trackball. Theoretically, I could get all needed controls on the same HID.

Where did you end up installing your spinners?

Re: Configuring a Composite HID Device

Posted: Sun Feb 20, 2022 4:01 am
by dstevens
I replaced one of the white buttons on each side of the trackball for the spinners. It's not ideal, but about the best I could do with the existing layout.

Re: Configuring a Composite HID Device

Posted: Thu Feb 24, 2022 1:29 pm
by dstevens
bankshot wrote: Sun Feb 20, 2022 3:17 am I ended up purchasing a Teensy 3.5 board from Micro Center as well to replace the Xinmo board and was going to wire the trackball to that, if I could figure out how to remove the embedded controller from the stock trackball. Theoretically, I could get all needed controls on the same HID.
After more testing I'm not sure composite HID devices is they way to go. While I can get everything to play nicely with MiSTer by splitting the controls into three HID devices I noticed the mouse movement would slow down if the spinners were moving. Correcting the spinner's PPR helped, but didn't solve it completely.

The issue is you can't send multiple HID reports in a single USB update they must be sent serially. If there are changes for all three devices the best case latency goes from 1ms to 3ms.

Combining all the controls into a single HID device solves the latency issue, but I couldn't map the controls from a single device into both "Player 1" and "Player 2". The mouse was separated out though.

I think the only way to accomplish what I want is to combine everything into a single HID device and write a custom driver that splits everything into 2 gamepads and a mouse.

Re: Configuring a Composite HID Device

Posted: Thu Feb 24, 2022 5:52 pm
by bankshot
Thanks a bunch for reporting your findings! Did you happen to try mapping all of the controls to the standard MAME keyboard input commands? Others have reported success in doing this on their custom controllers and I wonder if it would make an improvement to your situation. It's the route I was going to take when I get around to uploading the code on my Teensy 3.5.

Re: Configuring a Composite HID Device

Posted: Thu Feb 24, 2022 8:06 pm
by thorr
You guys are farther along than I am, so I appreciate the information above as I am sure I will refer to it. I have been busy with life, but need to get back to finishing my arcade cabinet.

Using the keyboard could/should work in at least some or many situations with arcade cores as long as they support the Mame keyboard layout. You can test this by using a keyboard and see if you can get it to move both the players around. I know it works with Mario Bros. so start there and then try other things. Then once tested, you can program the Teensy/Arduino to send keyboard keys instead of being a joystick. The limitation is this is only for arcade games. If you want to use two players with a console, I don't think the keyboard trick works.

I want ultimate flexibility so I have been thinking of ways to work around the MiSTer's input limitations. One of my goals is to be able to use both joysticks as one controller so I can play SNES Super Smash TV with two joysticks (acting as direction pad and ABXY buttons). I am thinking about different scenarios for how I will hook things up, but I have come to this plan so far:
- Have different Arduinos / USB connections for each control (each joystick, spinner, etc.). This is what the MiSTer wants, so it should make it happy most of the time. I will have to plug in multiple USB cables, but oh well.
- I may use a switch or a button combination to change the behavior of a single arduino for each joystick so it would either send keyboard strokes or joystick directions. If both act as a keyboard, that is ok coming from different devices. With both joysticks acting as a keyboard, that will solve my Super Smash TV problem by mapping the controls to the keyboard inputs before playing the game.
- I am building multiple control panels for the various games, so I probably will not need all this flexibility in most cases.

I am curious what games use two spinners. I had no plans for this. Atari paddle games makes sense though if that is the reason.

I wish the MiSTer's input system could care less about devices, and each control (Player 1 - Up, Player 2 - Up, etc.) could be mapped from anything, anywhere. Like how Mame does it. It would solve so many problems for people trying to build custom controllers for all these systems/cores.

Re: Configuring a Composite HID Device

Posted: Thu Feb 24, 2022 8:54 pm
by dstevens
The spinners and trackball are definitely the complicating factors. If those aren't a concern mapping to a keyboard seems like a great approach.

I'm probably trying to talk myself in doing it, but I think using a custom driver gives you the greatest flexibility.

You get the latency benefits of a single HID update then you can split it to any control combination that makes sense on the linux side. You could even write it so you could change devices schemes on the fly. I'm getting ahead of myself. Let's see if I can write a simple device driver first.

Re: Configuring a Composite HID Device

Posted: Thu Feb 24, 2022 9:01 pm
by thorr
If you can somehow make all this work well with one USB connection, that would be amazing and greatly appreciated by many. Good luck!

Re: Configuring a Composite HID Device

Posted: Fri Feb 25, 2022 12:05 am
by bankshot
Well thorr I can tell you that Super Smash TV is my wife's favorite SNES game and we play it almost daily. She's happy playing it with the default SNES layout on a PS4 controller, but I cannot stand it. So right now I am using the PS4 analog sticks for movement and firing when we play. I'll let you know what I come up with on the arcade stick front.

Re: Configuring a Composite HID Device

Posted: Fri Feb 25, 2022 12:21 am
by thorr
I had it working at one point on my custom arcade control panel and it was amazing. It is worth the effort just for this one game!

Re: Configuring a Composite HID Device

Posted: Mon Mar 07, 2022 2:48 pm
by sonik
dstevens wrote: Tue Feb 15, 2022 9:23 pm I'm working on a custom USB adapter for an arcade fight stick based on a STM32F411.

The fight stick has 2 joysticks, 14 buttons, 2 spinners, and a trackball.

I've split the controls into three composite HID devices. 2 joysticks (with 7 buttons and 1 spinner each) and one mouse device for the trackball.

On Windows everything works great, but I can't get it working fully in MiSTer.

Hi!

Did you found a fix for it?
Mister stopped working with my "single interface with composite HID" adapter too.
It works with mister and kernel up to 20210711. Later versions have this problem of only supporting the first device.

Re: Configuring a Composite HID Device

Posted: Mon Mar 07, 2022 5:13 pm
by dstevens
sonik wrote: Mon Mar 07, 2022 2:48 pm Did you found a fix for it?
Mister stopped working with my "single interface with composite HID" adapter too.
It works with mister and kernel up to 20210711. Later versions have this problem of only supporting the first device.
Check to see if no_merge_vid and no_merge_pid in MiSTer.ini is set to your composite device's vid/pid.

That is what fixed it for me.

Re: Configuring a Composite HID Device

Posted: Mon Mar 07, 2022 5:28 pm
by sonik
Your adapter is still working on lates mister version?

the no_merge is when mister treats all devices as one. my problem is that currently it only detects the first device and ignore the rest.

Re: Configuring a Composite HID Device

Posted: Mon Mar 07, 2022 7:44 pm
by dstevens
I changed my approach so I don't have an easy way to test. I'm no longer use a composite hid device, I'm sending all the data through a single raw hid device and splitting it into multiple devices in a linux driver.

That said it was working in mid February and my MiSTer was up to date so the kernel was likely newer than 20210711.

Re: Configuring a Composite HID Device

Posted: Mon Mar 07, 2022 8:45 pm
by sonik
Nice.
BTW I've got my adapter working just now. Enabled a quirk on u-boot.txt
usbhid.quirks=0x0000:0x0000:0x040

Without it, mister only responds to the first device of the composite descriptor.

Re: Configuring a Composite HID Device

Posted: Mon May 23, 2022 7:12 pm
by Kwoken
Not having much luck here. I have a Chewlix, wired into a single USB adaptor (which works fine with Windows), but I'm unable to get my Mister to see any of the 2nd player's buttons (inc. 2p start), and it sees the 2p joystick as 1p.

I've tried the nomerge commands and I've tried adding a u-boot.txt with the quirk you used (@sonik). Is it just a case of adding this text file in that Linux folder, or is there more to it?

I've tried the default codes, and switching the pid/vid codes to match the hex code I see in the controller config, on the Jamma/no merge lines, but it:
a/ didn't change anything with the 2p controls
b/ made the 1p controls act weird, e.g. my menu shortcut (btn3+1p start) would trigger auto fire mode.

I'm quite new to this level of jiggery pokery to get things working, but I hope I've just overlooked something. Would really appreciate any help (my wife really misses 2p Bubble Bobble).

Cheers!