Here's a wireshark capture of plugging the 8bitdo controller into a Linux machine (with X held down to force XInput as to avoid noise from the autodetect process) and moving the left stick around (had to open jstest-gtk as it apparently doesn't get polled if no program is reading it).
Hmm, anything in there we aren't doing? I do see the LED set command in there, but that hangs when we do it, so one of the earlier packets must be the key. I think we also do set_configuration, soooo uhhh, idk. Those String requests? I wouldn't believe it.
Would be handy to have a USB MITM device....
(I also verfied what happens when we poll it: It just returns NAKs)
EDIT: Wait no, the OUT is supposed to go to endpoint 2???
@Wuerfel_21 said:
Here's a wireshark capture of plugging the 8bitdo controller into a Linux machine (with X held down to force XInput as to avoid noise from the autodetect process) and moving the left stick around (had to open jstest-gtk as it apparently doesn't get polled if no program is reading it).
Is there a way to save a human-readable format ? I'm a bit too lazy to install wireshark...
EDIT: Wait no, the OUT is supposed to go to endpoint 2???
Possibly, however I don't think it is currently easy to send data to the out endpoint.
@Wuerfel_21 said:
Here's a wireshark capture of plugging the 8bitdo controller into a Linux machine (with X held down to force XInput as to avoid noise from the autodetect process) and moving the left stick around (had to open jstest-gtk as it apparently doesn't get polled if no program is reading it).
Is there a way to save a human-readable format ? I'm a bit too lazy to install wireshark...
Yes, but it's pretty hard to read.... (I've cut off the hub port reset sequence at the beginning and most of the polled data at the end for ease of reading) (0014008000000000000000000000000000000000 is the report for "X button held down", if you don't recognize it)
EDIT: Wait no, the OUT is supposed to go to endpoint 2???
Possibly, however I don't think it is currently easy to send data to the out endpoint.
I tried and I think it works, because any other value other than 1<<15 causes failure, but still no data (and the LEDs don't set). Also tried sending a rumble packet, no dice.
@Wuerfel_21 said:
Yes, but it's pretty hard to read.... (I've cut off the hub port reset sequence at the beginning and most of the polled data at the end for ease of reading) (0014008000000000000000000000000000000000 is the report for "X button held down", if you don't recognize it)
Definitely the LEDs are written to the out endpoint 2.
I tried and I think it works, because any other value other than 1<<15 causes failure, but still no data (and the LEDs don't set). Also tried sending a rumble packet, no dice.
Hmmm.... hard to tell but don't think the ep_addr_pid will be correct, the add 1<<15 seems increment the endpoint number (ok), however the msb of endpoint seems still set, and for an out endpoint is must be reset (0x82 in, 0x02 out)
rdbyte hr1, ptrb[ENDP_bAddress]
testb hr1, #7 wc ' FIXME: define constant for endpoint IN/OUT bit
...
shl hr1, #8 + 7
...
mov hkbd_ep_addr, hctrl_ep_addr
and hkbd_ep_addr, ##ADDR_MASK
or hkbd_ep_addr, hr1 ' IN endpoint address
You can try to fake the calculation by manually set hr1 to 0x02.
I tried and I think it works, because any other value other than 1<<15 causes failure, but still no data (and the LEDs don't set). Also tried sending a rumble packet, no dice.
Hmmm.... hard to tell but don't think the ep_addr_pid will be correct, the add 1<<15 seems increment the endpoint number (ok), however the msb of endpoint seems still set, and for an out endpoint is must be reset (0x82 in, 0x02 out)
rdbyte hr1, ptrb[ENDP_bAddress]
testb hr1, #7 wc ' FIXME: define constant for endpoint IN/OUT bit
...
shl hr1, #8 + 7
...
mov hkbd_ep_addr, hctrl_ep_addr
and hkbd_ep_addr, ##ADDR_MASK
or hkbd_ep_addr, hr1 ' IN endpoint address
You can try to fake the calculation by manually set hr1 to 0x02.
But the endpoint field in ep_addr_pid is only 4 bits. I don't think that applies here?
So I've been messing about with the gamepad init code and just happened to plug in the StrikeFX dongle and IT WORKS NOW. Traced back my steps and it seems the trick is to skip trying to read a HID descriptor for XInput devices. I tried to avoid it initially but I guess I did something wrong then. Anyways now it works, cool.
(And yes, StrikeFX in HID mode is still broken for some reason, lol)
(Yep, the axes center at +128 instead of zero. Amazing. Analog triggers work nicely though.)
Also interesting: It doesn't seem to respond to the LED/rumble commands, so I think that I may still be doing that wrong.
@Wuerfel_21 said:
So I guess it is to be concluded that the LED write is not what causes the pad to give up the goods.
I see that there are a number of packets between the led message submit and the completion (get descriptor for example), I don't know the low level details of USB, but maybe it is an asynchronous message ? I don't know if the driver can send and forget... or has queue of some kind...
So I've been messing about with the gamepad init code and just happened to plug in the StrikeFX dongle and IT WORKS NOW. Traced back my steps and it seems the trick is to skip trying to read a HID descriptor for XInput devices. I tried to avoid it initially but I guess I did something wrong then. Anyways now it works, cool.
Good. I was wondering if read the report descriptor for Xinput is really necessary, so the check can be moved before reading the descriptor ?
@Wuerfel_21 said:
So I guess it is to be concluded that the LED write is not what causes the pad to give up the goods.
I see that there are a number of packets between the led message submit and the completion (get descriptor for example), I don't know the low level details of USB, but maybe it is an asynchronous message ? I don't know if the driver can send and forget... or has queue of some kind...
Yeah. But it goes through, so I guess it just waits until the response. Since the StrikeFX is supposed to respond to LED and rumble messages and doesn't to mine, I can tell I'm still doing something wrong (I've also tried reloading the code with it still plugged in to rule out the possibility of the initial message getting dropped because the controller isn't connected to the dongle yet)
So I've been messing about with the gamepad init code and just happened to plug in the StrikeFX dongle and IT WORKS NOW. Traced back my steps and it seems the trick is to skip trying to read a HID descriptor for XInput devices. I tried to avoid it initially but I guess I did something wrong then. Anyways now it works, cool.
Good. I was wondering if read the report descriptor for Xinput is really necessary, so the check can be moved before reading the descriptor ?
@Wuerfel_21 said:
Well, believe it or not, I got the XInput OUT messages to finally work. Turns out to be a DATA0/DATA1 issue. Lmao.
Very good!
This can set LEDs and trigger rumble on the StrikeFX and also the SN30Pro, but the latter still isn't polling any data.
Ok, I think we need some way to set these things from the application, some CMD_* to use with execCmd. AFAIK, it doesn't allow parameters, for LEDs should not be a problem to have CMD_SETLED1, CMD_SETLED2, ecc., for rumble however it needs something more detailed.
@Wuerfel_21 said:
Well, believe it or not, I got the XInput OUT messages to finally work. Turns out to be a DATA0/DATA1 issue. Lmao.
Very good!
This can set LEDs and trigger rumble on the StrikeFX and also the SN30Pro, but the latter still isn't polling any data.
Ok, I think we need some way to set these things from the application, some CMD_* to use with execCmd. AFAIK, it doesn't allow parameters, for LEDs should not be a problem to have CMD_SETLED1, CMD_SETLED2, ecc., for rumble however it needs something more detailed.
Rumble is a bit complex, ye. Though the XInput LEDs technically are, too, it seems that the pads I have on hand really only support the four regular indicator states ($02 through $05)
I found some information online regarding PS3 rumble controller commands....someone did a ESP32 bluetooth interface but I think the command bits would potentially be the same over USB. It also showed how to setup LED status bits too and get accelerometer/gyro readings.
By the way the different buttons on the PS3 controller can report analog pressure as well (separately to normal digital press) via more axis data in the report.
I also have this old Logitech force feedback USB steering wheel controller for a PC. When I get a chance later today I'll try to hook it up and see if it reports anything in this code. Would be rather cool if they work too.
If I did everything right, today's update includes:
Axis value normalization to -32768 / 32767 (word signed integer)
PS3 and XInput LEDs message fix
Console output changed to display the axis name and normalized value
About the LEDs, seems that the PS3 mode needs the led command before the enable command, so this information must be set on startup. XInput LEDs on the other end, seems to have a number of funny modes so it deserves a dedicated command from the application.
@rogloh said:
By the way the different buttons on the PS3 controller can report analog pressure as well (separately to normal digital press) via more axis data in the report.
Ah, yes, I remembered that the controller had this feature!
I think that PS3 needs a dedicated decoder like XInput.
XInput axes got busted. Needs to be like this (*_AXIS are bits, so need to be encod-ed. Also changed the Y inversion to ones complement so it stays in 16 bit range):
axis[encod X_AXIS] := word[data+ 6] signx 15 ' Left stick X
axis[encod Y_AXIS] := (!word[data+ 8]) signx 15 ' Left stick Y (inverted)
axis[encod Z_AXIS] := word[data+10] signx 15 ' Right stick X
axis[encod RZ_AXIS] := (!word[data+12]) signx 15 ' Right stick Y (inverted)
axis[encod RX_AXIS] := byte[data+4] ' left analog trigger
axis[encod RY_AXIS] := byte[data+5] ' right analog trigger
@Wuerfel_21 said:
XInput axes got busted. Needs to be like this (*_AXIS are bits, so need to be encod-ed. Also changed the Y inversion to ones complement so it stays in 16 bit range):
Ahhhhh... no, those constants should be index numbers not bits, too much copy and paste... *_AXIS is the element index, HAS_*_AXIS is the bit!
Package updated.
@rogloh said:
I also have this old Logitech force feedback USB steering wheel controller for a PC. When I get a chance later today I'll try to hook it up and see if it reports anything in this code. Would be rather cool if they work too.
Just hooked up this Logitech MOMO steering wheel controller to the P2 and it worked!
Once USB is connected it lights the power LED on the steering wheel and actively resists turning the wheel. The amount of force feedback resisting turning the wheel seems very strong indeed by default but it still worked and lets me press all the 6 buttons on the front of the steering wheel, two paddle buttons, two gear change buttons. The steering wheel controls the X axis and the brake/accel pedals change the Y axis (each pedal pushed offsets from the center in a different axis direction).
It would be nice to be able to control/reduce the amount of force feedback at some point and be able to light the other LED (which I think was meant to indicate force feedback is on) but I have no idea what controls that. The only scant information I found so far in a brief hunt was this...and whether it even applies to this particular wheel is unknown. https://www.microchip.com/forums/m573610.aspx
Here's the data it reported with the latest version of this gamepad driver.
The XInput analog triggers are still going 0 to 255. The GC adapter (only HID device I can find that does analog triggers) ones are going -32k to +32k now. I don't think the descriptor declares them any different from the stick axes, so uhhhhhh. IDK what to do about all this.
@rogloh said:
Just hooked up this Logitech MOMO steering wheel controller to the P2 and it worked!
Very good!
It would be nice to be able to control/reduce the amount of force feedback at some point and be able to light the other LED (which I think was meant to indicate force feedback is on) but I have no idea what controls that. The only scant information I found so far in a brief hunt was this...and whether it even applies to this particular wheel is unknown. https://www.microchip.com/forums/m573610.aspx
This kind of settings are controller-specific and needs specialized methods for software applications. Currently the driver doesn't allow to send arbitrary messages from the application, see also the LED settings, it needs to implement some commands to allow that.
@Wuerfel_21 said:
Huh, RE: Axis normalization.
The XInput analog triggers are still going 0 to 255. The GC adapter (only HID device I can find that does analog triggers) ones are going -32k to +32k now. I don't think the descriptor declares them any different from the stick axes, so uhhhhhh. IDK what to do about all this.
Probably because I forgot to normalize them
Package updated...
(I'll purchase an XInput controller... it is already on the Amazon cart...)
It allows to play with a keyboard or a game controller. Driver support should be nearly at the level of the Spin driver, so includes XInput, PS3 and generic HID controllers, with some experimental modifications.
Keyboard controls are LEFT/RIGHT arrows, SPACE to fire and ENTER to play.
Gamepad controls are LEFT/RIGHT dpad, if present as hat, or LEFT stick (or whatever it is defined as X axis), A/B buttons (or equivalent) as fire, and START (or equivalent) to play.
Beware that the controls are directed to the same pins used as buttons (4, 5, 6 and 7), since they are driven by the propeller I think is better to not have anything connected to them.
So, what about making the second port work? The driver seems to be written to really only work with one, so I guess some major rewriting would have to occur.
Comments
Will this work with Xbox one wired controller?
Any chance of getting headphones/mic working?
I actually have no idea. Would have to plug one in and see what it does.
In theory yes, but in practice, "Why?".
Here's a wireshark capture of plugging the 8bitdo controller into a Linux machine (with X held down to force XInput as to avoid noise from the autodetect process) and moving the left stick around (had to open jstest-gtk as it apparently doesn't get polled if no program is reading it).
Hmm, anything in there we aren't doing? I do see the LED set command in there, but that hangs when we do it, so one of the earlier packets must be the key. I think we also do set_configuration, soooo uhhh, idk. Those String requests? I wouldn't believe it.
Would be handy to have a USB MITM device....
(I also verfied what happens when we poll it: It just returns NAKs)
EDIT: Wait no, the OUT is supposed to go to endpoint 2???
Is there a way to save a human-readable format ? I'm a bit too lazy to install wireshark...
Possibly, however I don't think it is currently easy to send data to the out endpoint.
Yes, but it's pretty hard to read.... (I've cut off the hub port reset sequence at the beginning and most of the polled data at the end for ease of reading) (
0014008000000000000000000000000000000000
is the report for "X button held down", if you don't recognize it)I tried and I think it works, because any other value other than
1<<15
causes failure, but still no data (and the LEDs don't set). Also tried sending a rumble packet, no dice.Definitely the LEDs are written to the out endpoint 2.
Hmmm.... hard to tell but don't think the ep_addr_pid will be correct, the add 1<<15 seems increment the endpoint number (ok), however the msb of endpoint seems still set, and for an out endpoint is must be reset (0x82 in, 0x02 out)
You can try to fake the calculation by manually set hr1 to 0x02.
But the endpoint field in
ep_addr_pid
is only 4 bits. I don't think that applies here?Ah, yes, your are right, calc_crc5 clears it, I did a quick test and the two ends with only the endpoint value different.
So I guess it is to be concluded that the LED write is not what causes the pad to give up the goods.
So I've been messing about with the gamepad init code and just happened to plug in the StrikeFX dongle and IT WORKS NOW. Traced back my steps and it seems the trick is to skip trying to read a HID descriptor for XInput devices. I tried to avoid it initially but I guess I did something wrong then. Anyways now it works, cool.
(And yes, StrikeFX in HID mode is still broken for some reason, lol)
(Yep, the axes center at +128 instead of zero. Amazing. Analog triggers work nicely though.)
Also interesting: It doesn't seem to respond to the LED/rumble commands, so I think that I may still be doing that wrong.
I see that there are a number of packets between the led message submit and the completion (get descriptor for example), I don't know the low level details of USB, but maybe it is an asynchronous message ? I don't know if the driver can send and forget... or has queue of some kind...
Good. I was wondering if read the report descriptor for Xinput is really necessary, so the check can be moved before reading the descriptor ?
Yeah. But it goes through, so I guess it just waits until the response. Since the StrikeFX is supposed to respond to LED and rumble messages and doesn't to mine, I can tell I'm still doing something wrong (I've also tried reloading the code with it still plugged in to rule out the possibility of the initial message getting dropped because the controller isn't connected to the dongle yet)
Yep, that's what I did.
Well, believe it or not, I got the XInput OUT messages to finally work. Turns out to be a DATA0/DATA1 issue. Lmao.
This can set LEDs and trigger rumble on the StrikeFX and also the SN30Pro, but the latter still isn't polling any data.
Very good!
Ok, I think we need some way to set these things from the application, some CMD_* to use with execCmd. AFAIK, it doesn't allow parameters, for LEDs should not be a problem to have CMD_SETLED1, CMD_SETLED2, ecc., for rumble however it needs something more detailed.
Rumble is a bit complex, ye. Though the XInput LEDs technically are, too, it seems that the pads I have on hand really only support the four regular indicator states ($02 through $05)
I found some information online regarding PS3 rumble controller commands....someone did a ESP32 bluetooth interface but I think the command bits would potentially be the same over USB. It also showed how to setup LED status bits too and get accelerometer/gyro readings.
https://github.com/jvpernis/esp32-ps3/tree/master/src
By the way the different buttons on the PS3 controller can report analog pressure as well (separately to normal digital press) via more axis data in the report.
I also have this old Logitech force feedback USB steering wheel controller for a PC. When I get a chance later today I'll try to hook it up and see if it reports anything in this code. Would be rather cool if they work too.
If I did everything right, today's update includes:
About the LEDs, seems that the PS3 mode needs the led command before the enable command, so this information must be set on startup. XInput LEDs on the other end, seems to have a number of funny modes so it deserves a dedicated command from the application.
Ah, yes, I remembered that the controller had this feature!
I think that PS3 needs a dedicated decoder like XInput.
XInput axes got busted. Needs to be like this (*_AXIS are bits, so need to be encod-ed. Also changed the Y inversion to ones complement so it stays in 16 bit range):
Ahhhhh... no, those constants should be index numbers not bits, too much copy and paste...
*_AXIS
is the element index,HAS_*_AXIS
is the bit!Package updated.
Just hooked up this Logitech MOMO steering wheel controller to the P2 and it worked!
Once USB is connected it lights the power LED on the steering wheel and actively resists turning the wheel. The amount of force feedback resisting turning the wheel seems very strong indeed by default but it still worked and lets me press all the 6 buttons on the front of the steering wheel, two paddle buttons, two gear change buttons. The steering wheel controls the X axis and the brake/accel pedals change the Y axis (each pedal pushed offsets from the center in a different axis direction).
It would be nice to be able to control/reduce the amount of force feedback at some point and be able to light the other LED (which I think was meant to indicate force feedback is on) but I have no idea what controls that. The only scant information I found so far in a brief hunt was this...and whether it even applies to this particular wheel is unknown.
https://www.microchip.com/forums/m573610.aspx
Here's the data it reported with the latest version of this gamepad driver.
Huh, RE: Axis normalization.
The XInput analog triggers are still going 0 to 255. The GC adapter (only HID device I can find that does analog triggers) ones are going -32k to +32k now. I don't think the descriptor declares them any different from the stick axes, so uhhhhhh. IDK what to do about all this.
Very good!
This kind of settings are controller-specific and needs specialized methods for software applications. Currently the driver doesn't allow to send arbitrary messages from the application, see also the LED settings, it needs to implement some commands to allow that.
Probably because I forgot to normalize them
Package updated...
(I'll purchase an XInput controller... it is already on the Amazon cart...)
Ready for a real world application ?
Here is the Space Invaders arcade emulation from https://forums.parallax.com/discussion/172813/p2-space-invaders-8080-emulation with pasm-only USB support.
It allows to play with a keyboard or a game controller. Driver support should be nearly at the level of the Spin driver, so includes XInput, PS3 and generic HID controllers, with some experimental modifications.
Keyboard controls are LEFT/RIGHT arrows, SPACE to fire and ENTER to play.
Gamepad controls are LEFT/RIGHT dpad, if present as hat, or LEFT stick (or whatever it is defined as X axis), A/B buttons (or equivalent) as fire, and START (or equivalent) to play.
Beware that the controls are directed to the same pins used as buttons (4, 5, 6 and 7), since they are driven by the propeller I think is better to not have anything connected to them.
Enjoy!
Haven't examined the code yet, but did plug in a bunch of stuff...
Otherwise works fine.
Try now, XInput should work, not sure about the Gamecube adapter.
That should work... will check.
It is to simplify things.
Yep, XInput fixed.
Gamecube should work now, wrong action with the multiple reports id...
Nah, still doesn't. There's some issue with how the buttons are decoded, it seems. It only really picks up the hat control.
So, what about making the second port work? The driver seems to be written to really only work with one, so I guess some major rewriting would have to occur.