The online racing simulator
#1 - MikeB
LTWheelConf - Setup Logitech DFP/G25/G27 on linux
This is for anybody who wants to use his Logitech wheel to its full potential on Linux. For example running LFS through wine

Based on discussion and code in this thread and some more info in the vdrift forums i created a tool to configure the wheels correctly on linux.

From the Readme:
Quote :This tool allows you to change various settings of the Logitech racing wheels
-> Driving Force Pro (DFP)
-> G25
-> G27

Available options:
-> set wheel to "native" mode (support separate axes and clutch pedal, full 900 degree rotation)
-> Set wheel rotation range
-> Set autocenter force and rampspeed
-> Set ForceFeedback gain

Credits:
Based on:
- Original "G25manage" as part of the vdrift driving simulator (http://vdrift.net)
- Modified "G25manage" posted by slim.one on the lfsforum (http://www.lfsforum.net/showthread.php?p=1564187#post1564187)
- Various Information & research from vdrift forum: http://vdrift.net/Forum/viewto ... tdays=0&postorder=asc

The code is GPL'ed and hosted on github:
https://github.com/TripleSpeeder/LTWheelConf
Currently there are no binaries provided, but it is really easy to build. Just download & extract the sources and type "make"

With this tool and the latest kernel 2.6.39 LFS runs perfectly with all features also on Linux (through wine)

Edit:
-> Developed & tested on Arch linux x86_64
-> I only have a G25, so i could not test if it really works with DFP/G27
Good work, I like the autocenter and gain settings. Might I suggest increasing the delay when attempting to set the wheel to the native mode? 1 second is definitely not enough for my DFP (I used at least 3 when I was toying around with this)

EDIT:
I just realized that I saw this on VDrift forums. Can you test it with your G25, because neither this nor your code set the range properly on my DFP.

int16_t range = 900 // 16-bit integer representing degrees to set range to
command = [0xf8, 0x81, range & 0x00ff, range & 0xff00, 0, 0, 0]

#3 - MikeB
Quote from MadCatX :Good work, I like the autocenter and gain settings. Might I suggest increasing the delay when attempting to set the wheel to the native mode? 1 second is definitely not enough for my DFP (I used at least 3 when I was toying around with this)

Thanks for the feedback In the next version I'll increase the waiting time to 3 seconds after sending the wheel into native mode.

Quote from MadCatX :EDIT:
I just realized that I saw this on VDrift forums. Can you test it with your G25, because neither this nor your code set the range properly on my DFP.

int16_t range = 900 // 16-bit integer representing degrees to set range to
command = [0xf8, 0x81, range & 0x00ff, range & 0xff00, 0, 0, 0]


Not working here, without the bitshift the maximum rotation is around 250 degrees - Probably an overflow problem.
#4 - MikeB
*Bump*
There is now a "native" implementation of autocenter settings which does not rely on kernel 2.6.39 anymore and as a bonus allows finer control of behaviour by also providing a setting for the rampspeed.

MadCatX: I am very curious if this also works on your DFP, as i only have a G25 here. Could you give a try to the latest version if the autocenter and rampspeed settings work on your side?

In case it is not working the old implementation is still available through parameter "--altautocenter".
Hi, nice work. The G27 needs a different initialization, i just managed to get it to reconnect with the right USB ID (046d:029b). But since the G27 isn't listed in the kernel, it isn't reported correctly by the kernel and thus gets not recognized as a wheel/joystick by wine (i wonder how the G25 should work without a patched kernel, because the wheel shouldn't have FF support, but if it works... i'll just shut up ). I'll try to get the G27 integrated into the kernel as well, no idea in which version it'll be included tho.

As for LTWheelConf, the initialization bytearray(s) for the G27 are:
0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
and
0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00
They have to be sent in this order instead of only one bytearray for the DFP/G25.
Interesting, do you have any idea what's the second command for?

I tried the kernel-oblivious autocenter adjustment and it works, nice I suppose you haven't noticed any change regarding the "parse failed" and "probe failed with -110 error"? That is really a showstopper for me...
Quote from MadCatX :Interesting, do you have any idea what's the second command for?

nope, but it works, i got the commands from an USB-dump. As i see it, the logitech driver under windows first reads some data and after that sends proper command(s). It should be interesting to compare the different dumps... i used USBlyzer (http://www.usblyzer.com/), it has a 33day trial-period and generates handy html-reports (http://team-infinity.ath.cx/slim/usbdump_g27.html)

As for LTWheelConf, i found an error in the Makefile which prevented it from building here; instead of
gcc -Wall -lusb -g3 -o ltwheelconf ltwheelconf.c
it has to be
gcc -Wall -lusb-1.0 -g3 -o ltwheelconf ltwheelconf.c
for my gcc to work.
#8 - MikeB
Quote from slim.one :Hi, nice work. The G27 needs a different initialization, i just managed to get it to reconnect with the right USB ID (046d:029b). But since the G27 isn't listed in the kernel, it isn't reported correctly by the kernel and thus gets not recognized as a wheel/joystick by wine (i wonder how the G25 should work without a patched kernel, because the wheel shouldn't have FF support, but if it works... i'll just shut up ). I'll try to get the G27 integrated into the kernel as well, no idea in which version it'll be included tho.

As for LTWheelConf, the initialization bytearray(s) for the G27 are:
0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
and
0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00
They have to be sent in this order instead of only one bytearray for the DFP/G25.

Nice find i will integrate this into LTWheelConf asap.

Quote from MadCatX :I tried the kernel-oblivious autocenter adjustment and it works, nice I suppose you haven't noticed any change regarding the "parse failed" and "probe failed with -110 error"? That is really a showstopper for me...

Nice to hear the autocenter works on DFP also, thanks for testing

Quote from MadCatX :I suppose you haven't noticed any change regarding the "parse failed" and "probe failed with -110 error"? That is really a showstopper for me...

Are you referring to the problems with setting wheel range on DFP? With some luck I'll have a DFP available here for testing within the next week. I am confident to get it running when i can have a detailed look at the usb traffic

Quote from slim.one :As for LTWheelConf, i found an error in the Makefile which prevented it from building here; instead of
gcc -Wall -lusb -g3 -o ltwheelconf ltwheelconf.c
it has to be
gcc -Wall -lusb-1.0 -g3 -o ltwheelconf ltwheelconf.c
for my gcc to work.

Hmm, looks like i should go check the autoconf tools and have a proper ./configure command to prevent trouble like this. I hate it
Quote from MikeB :
Are you referring to the problems with setting wheel range on DFP? With some luck I'll have a DFP available here for testing within the next week. I am confident to get it running when i can have a detailed look at the usb traffic

Yes and no. The problem occurs when I attempt to set range, but it's not the only case. Actually any command I send after the "set to native mode" command triggers the error. I can provide you with dmesg log if you'd like. If you get your hands on a DFP, let me know if I can be of any help. What tools are you planning to use to check the USB traffic? Perhaps I can get some useful data for you...
Okay, i just pushed new version 0.2.2 to github containing the new command to set G27 into "real" native mode.

Also new:
  • Command --list to get an overview of found/supported devices
  • Mandatory parameter --wheel where you have to specify which wheel you have connected
  • Prepared to support (theoretically, but not tested) the following wheels:
    • Driving Force
    • Momo Force
    • Driving Force Pro
    • G25
    • G27
    • Driving Force GT
As always I am curious about your feedback
I did a brief test and it works just like it did before. Good idea using the mandatory wheel model parameter, it's much better than the previous hit & miss searching.

I have a small suggestion regarding autocenter though, I find it rather superfluous to specify ramp speed when centering force is set to 0 - you want to disable autocenter. Perhaps something like would work?


if (centerforce == 0) {
set_autocenter(wheelIndex, centerforce, 0);
else if (rampspeed == -1) {
printf("Please provide '--rampspeed' parameter\n");
} else {
set_autocenter(wheelIndex, centerforce, rampspeed);
wait_for_udev = 1;
}

hm, maybe for udev there should be an option to append the usb bus- and device-number ltwheelconf should use - this way one udev-rule would suffice for all Logitech wheels, since they all connect with the same id. Or we screw udev completely and make a nice GUI for ltwheelconf

(edit: since --list successfully recognizes my G27, specifying bus and device should enable ltwheelconf to use the right commands for each wheel)
A GUI frontend like Logitech Control Panel would be nice. I might pull something off when MikeB's LTWheelConf get some stable CLI...
Quote from MadCatX :I have a small suggestion regarding autocenter though, I find it rather superfluous to specify ramp speed when centering force is set to 0 - you want to disable autocenter. Perhaps something like would work?
(code snipped)

Definitely good idea, will do this in the next update

Quote from slim.one :hm, maybe for udev there should be an option to append the usb bus- and device-number ltwheelconf should use - this way one udev-rule would suffice for all Logitech wheels, since they all connect with the same id. Or we screw udev completely and make a nice GUI for ltwheelconf

(edit: since --list successfully recognizes my G27, specifying bus and device should enable ltwheelconf to use the right commands for each wheel)

Problem is i do not know (yet) how the Logitech driver recognizes that a connected wheel is in reality not a DF but a G27 in restricted mode. It must query some other parameter besides PID and VID (and i assume/hope it does NOT rely just on the name string reported by the device... ). With this knowledge the --wheel parameter could be obsolete again and the whole process could be very well automated.
...Or maybe i did not fully understand your point


Quote from MadCatX :Yes and no. The problem occurs when I attempt to set range, but it's not the only case. Actually any command I send after the "set to native mode" command triggers the error. I can provide you with dmesg log if you'd like. If you get your hands on a DFP, let me know if I can be of any help. What tools are you planning to use to check the USB traffic? Perhaps I can get some useful data for you...

dmesg output would be welcome And if you have the possibility to create a USB traffic log when the device is plugged in on Windows and e.g. wheelrange is set to different values it would be even better. Regarding USB analyzer tool i do not yet have an opinion - Most tools i saw sofar are quite expensive but offer some trial mode.
I will do this myself when i get hands on a DFP but it is not confirmed yet if/when i get it

Quote from MadCatX :A GUI frontend like Logitech Control Panel would be nice. I might pull something off when MikeB's LTWheelConf get some stable CLI...

This would be awesome But i think it will take some more time untill the CLI is kind of stable...
Quote from MikeB :Problem is i do not know (yet) how the Logitech driver recognizes that a connected wheel is in reality not a DF but a G27 in restricted mode. It must query some other parameter besides PID and VID (and i assume/hope it does NOT rely just on the name string reported by the device... ). With this knowledge the --wheel parameter could be obsolete again and the whole process could be very well automated.
...Or maybe i did not fully understand your point

that's what i meant (more or less). I don't know how the driver identifies the wheels either, but don't see why using the name strings should be problematic (since we don't know if it is the logitech driver reading data from the wheels before reinitialization after all...)

Btw., i'm trying to get a USB-dump from a MOMO Force the next few days - that should give the commands for initialization. Having different dumps from 2 wheels the same type should be interesting, too.
I did some testing to get some debugging info for you, so here it goes. This is the full dmesg output I get when I plug my DFP in up to the point where it disappears from /dev/input.

Wheel plugged in

ehci_hcd 0000:00:1d.7: BAR 0: set to [mem 0xf2504c00-0xf2504fff] (PCI address [0xf2504c00-0xf2504fff])
ehci_hcd 0000:00:1d.7: restoring config space at offset 0xf (was 0x100, writing 0x10a)
ehci_hcd 0000:00:1d.7: restoring config space at offset 0x1 (was 0x2900000, writing 0x2900002)
ehci_hcd 0000:00:1d.7: PME# disabled
ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
ehci_hcd 0000:00:1d.7: setting latency timer to 64
ehci_hcd 0000:00:1a.7: BAR 0: set to [mem 0xf2504800-0xf2504bff] (PCI address [0xf2504800-0xf2504bff])
ehci_hcd 0000:00:1a.7: restoring config space at offset 0xf (was 0x300, writing 0x30a)
ehci_hcd 0000:00:1a.7: restoring config space at offset 0x1 (was 0x2900000, writing 0x2900002)
ehci_hcd 0000:00:1a.7: PME# disabled
ehci_hcd 0000:00:1a.7: PCI INT C -> GSI 19 (level, low) -> IRQ 19
ehci_hcd 0000:00:1a.7: setting latency timer to 64
ehci_hcd 0000:00:1a.7: PCI INT C disabled
ehci_hcd 0000:00:1a.7: PME# enabled
uhci_hcd 0000:00:1d.0: PCI INT A -> GSI 23 (level, low) -> IRQ 23
uhci_hcd 0000:00:1d.0: setting latency timer to 64
usb 6-1: new low speed USB device using uhci_hcd and address 2
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
input: Logitech Logitech Driving Force as /devices/pci0000:00/0000:00:1d.0/usb6/6-1/6-1:1.0/input/input9
logitech 0003:046D:C294.0001: input,hidraw0: USB HID v1.00 Joystick [Logitech Logitech Driving Force] on usb-0000:00:1d.0-1/input0
hid_logitech: Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>
ehci_hcd 0000:00:1d.7: PCI INT A disabled
ehci_hcd 0000:00:1d.7: PME# enabled

Set to native command sent

usb 6-1: USB disconnect, address 2
logitech 0003:046D:C294.0002: parse failed
ehci_hcd 0000:00:1d.7: BAR 0: set to [mem 0xf2504c00-0xf2504fff] (PCI address [0xf2504c00-0xf2504fff])
ehci_hcd 0000:00:1d.7: restoring config space at offset 0xf (was 0x100, writing 0x10a)
ehci_hcd 0000:00:1d.7: restoring config space at offset 0x1 (was 0x2900000, writing 0x2900002)
ehci_hcd 0000:00:1d.7: PME# disabled
ehci_hcd 0000:00:1d.7: PCI INT A -> GSI 23 (level, low) -> IRQ 23
ehci_hcd 0000:00:1d.7: setting latency timer to 64
ehci_hcd 0000:00:1a.7: BAR 0: set to [mem 0xf2504800-0xf2504bff] (PCI address [0xf2504800-0xf2504bff])
ehci_hcd 0000:00:1a.7: restoring config space at offset 0xf (was 0x300, writing 0x30a)
ehci_hcd 0000:00:1a.7: restoring config space at offset 0x1 (was 0x2900000, writing 0x2900002)
ehci_hcd 0000:00:1a.7: PME# disabled
ehci_hcd 0000:00:1a.7: PCI INT C -> GSI 19 (level, low) -> IRQ 19
ehci_hcd 0000:00:1a.7: setting latency timer to 64
ehci_hcd 0000:00:1a.7: PCI INT C disabled
ehci_hcd 0000:00:1a.7: PME# enabled
usb 6-1: new low speed USB device using uhci_hcd and address 3
ehci_hcd 0000:00:1d.7: PCI INT A disabled
ehci_hcd 0000:00:1d.7: PME# enabled
logitech 0003:046D:C298.0003: timeout initializing reports
input: Logitech Logitech Driving Force Pro as /devices/pci0000:00/0000:00:1d.0/usb6/6-1/6-1:1.0/input/input10
logitech 0003:046D:C298.0003: input,hidraw0: USB HID v1.00 Joystick [Logitech Logitech Driving Force Pro] on usb-0000:00:1d.0-1/input0
hid_logitech: Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>
ehci_hcd 0000:00:1d.7: PCI INT A disabled
ehci_hcd 0000:00:1d.7: PME# enabled

Another command sent (disabling autocenter in this case, but it doesn't matter which)

logitech 0003:046D:C298.0004: parse failed
logitech: probe of 0003:046D:C298.0004 failed with error -110

Now the device is gone from /dev/input and even rmmoding the USB drivers doesn't make it reappear. I attached a simple communication log I got with USBLyzer, the log should contain all important commands. The OS I captured it on was Win7 x64. There is a lot of junk (sorry) because I tried to move the wheel to see how it reports position of its axes. If you read it carfefully, I'll see why the separate pedals cannot work without some modification of the drivers or a userspace hack. (you'll have to change the extension to .html to read it)

I did another test which makes me think there is a bug in linux USB HID layer. I installed Logitech drivers for my DFP to a virtualboxed Win7 x86 and tried to initialize the wheel from there. Windows drivers successfully send the commands, the wheel switches to the native mode and then I virtualbox gives an error message similar to the one in dmesg. This makes me believe that LTWC does everything right, but DFP behaves somewhat weird during reconnecting and confuses the linux USB HID layer....
Attached files
dfp_init.txt - 45.2 KB - 521 views
Thanks for the info MadCatX
Indeed this looks like a kernel issue. Which kernel are you running? Are the patches from slim.one for G25/DFP support already included?
If yes we probably need to get engaged in kernel hacking. Maybe some of the "quirks"-flags from lg-ff.c need to be set...

@slim.one: As you are probably already more into kernel hacking Any idea?
Interesting thing from the usb log of the DFP:

At timestamp 7:43:38.335 driver issues this command:
F8 03 00 00 00 00 00

This is the prefix to set wheel range, but with all other bytes zero'ed instead of range value.

Immediately afterwards another command is sent:
81 0B 19 E6 FF 4A FF

I have no idea what this command is for, but as previous command does not include any reference to rotation degrees this might be encoded here?
I'm on 2.6.38.5 with a custom patch that adds necessary device ID's to make force feedback working when the DFP switches to the native mode. I can post the diff here but I think it's the same thing slim.one submitted upstream. However, with this patch or not the behavior is the same. I used usbmon module and Wireshark to capture the USB traffic in linux. The capture begins when I connect the wheel to a USB port, then I send the "set to native command" and some time later I set the wheel's range to 900 deg. I took some time to look at the traffic so there was quite some delay between the commands. Perhaps you could take a look at it can capture a traffic you get with a G25/7? It'd be interesting to check if there are any differences that might give us a clue...

Attached ZIP contains the captured traffic in plain text and wireshark native format.
Attached files
dfp_lincap.zip - 9.2 KB - 431 views
Quote from MikeB :Interesting thing from the usb log of the DFP:

At timestamp 7:43:38.335 driver issues this command:
F8 03 00 00 00 00 00

This is the prefix to set wheel range, but with all other bytes zero'ed instead of range value.

Immediately afterwards another command is sent:
81 0B 19 E6 FF 4A FF

I have no idea what this command is for, but as previous command does not include any reference to rotation degrees this might be encoded here?

I did some testing and I found out that DFP really behaves differently to G25/27. The F8 03 command tells DFP to enable ranges greater than 200 deg. The subsequent 81 0B command then sets the requested range, in this case 720 degrees.
I actually investigated this before, but because I had no fix to disable autocentering, I couldn't tell if I hit the range limiter or if it was just the autocentering force getting stronger
In any case, it appears that we need to figure out the formula for DPF range setting commands, changing just the prefix doesn't seem to work...
Quote from MadCatX :In any case, it appears that we need to figure out the formula for DPF range setting commands, changing just the prefix doesn't seem to work...

MadCatX, maybe you could log the USB traffic when setting different wheel ranges from the Logitech control panel? I am sure we can find the correct formula when we have a few more samples.
I would do that myself, but still have no access to DFP wheel here (still working on it - with some luck next week...)
Small *bump* - Beginning of next week i should finally have a (slightly broken) DFP in my hands (thanks to Ebay :tilt. So there is hope i can probably sort out the problems reported by MadCatX...
I'll be sorta buys with exams and stuff for the next month or so, so I won't have much time do to some horribly extensive investigation of my own. But should you need help with something specific (testing, checking, some USB sniffing), let me know and I'll certainly find some time in my schedule
I got the DFP yesterday, only had time for a quick check - I can fully reproduce the trouble reported by MadCatX. Now i am trying to understand how the hid-drivers in kernel work :-)

Edit: By the way i am surprised that the DFP has a kind of hardware rotation limitation? It seems there is a mechanical limit at 200 degrees that you can clearly hear when being (de)activated. Is this true?
Quote from MikeB :Edit: By the way i am surprised that the DFP has a kind of hardware rotation limitation? It seems there is a mechanical limit at 200 degrees that you can clearly hear when being (de)activated. Is this true?

Yes, it is its way of change rotantion in PlayStation2, and before Logitech released the PC driver you had to know the key combination to toggle 200º/900º

FGED GREDG RDFGDR GSFDG