The online racing simulator
Perfect, that's exactly what I need... in case you wonder, the constant-force effect command is exactly the same like the one for DFP.

@slim.one: If you have a Windows box available, could you do the same for G25? (Even virtualboxed windows can do the job)
Do you guys need results of Driving Force GT, or patch already supports it fine?
DFGT is currently completely unknown to the kernel, so any piece of info you can give us would be much appreciated...
Here you go

After pressing one button (which was L3), I waited approx. 15-20 seconds and pressed R3, but, 2 seconds after that, USBLyzer stopped capture cause capture buffer got full. I hope that's not a big problem.
Nice, thanks a bunch. Judging by the log I assume you have the centering spring enabled and set to quite high strength (about 120 %), is that right?

The autocentering is what looks most troubling at the moment. Every wheel we tested so far seems to use a bit different command format. If you can waste another 5 minutes of your existence doing another sniff, here how:
- Launch USBLyzer and select your wheel as you did before
- Open the Logitech control panel, open the configuration window and enable "Centering spring"
- Set the strength to 0 %, close the config window, and open in again (driver sends data to the wheel only after the config window is closed)
- Increase strength by 25 % and repeat the opening/closing until you reach the maximum.
When you upload the logs, please export them as HTML so I don't have to launch windows every time I want to read them

@E. R.:
I suppose that DFGT is just a younger sister of a DFP, right? DFP needs to be sent a special command which enables 900 deg rotation and stuff and I somewhat doubt that DFGT will accept the DFP command. You can sniff that too, just select the USB port you'll connect your wheel to, start capturing and plug the wheel in (AC power should be connected).
Another thing that is worth investigating is the range limiting. These commands can be captured just like centering spring ones, but please don't mix 40 - 200 and 210 - 900 ranges in the same log

Anyway, thanks a lot guys, you've helped a lot already...
Hmm, nope, centering spring is disabled here.

I did a capture with centering spring - when I start capture its disabled, then I just enable it (being set to default of 100%), then I zero it and manually increment by 25% - here it is: http://localhostr.com/files/rrBI3hu/Centering%20spring.html

And here are logs of connecting DFGT: http://localhostr.com/files/5I ... %20Host%20Controller.html
Last second is flooded by me moving the mouse to Stop Capture button, sorry for that.

Also, DFGT's only differences from DFP (external ones :P ) are more buttons and better FFB. Pedals, shifter, rotation angle etc are just about same.

Edit: two more uploads, filenames speak for themselves:
http://localhostr.com/download ... -720-540-450-360-270.html
http://localhostr.com/files/sN ... tion%2040-90-180-200.html
Awesome, except for the centering spring log which for some reason doesn't contain any commands that'd look like autocentering ones the logs were very helpful.

Here's a quick patch for LTWC (link to git in the first post) that adds full support for DFGT. "sudo ./ltwheelconf -w DFGT -n" should switch the wheel to native mode (you should see it reconnect with 0x29A PID in dmesg).
You can try changing the wheel's range (sudo ./ltwheelconf -w DFGT -r XXX) and fooling around with autocentering (sudo ./ltwheelconf -w DFGT -a [0-255] -r [0-15]). There'll be no FF 'cause of missing support in the lgff driver. Does DFGT report separate brake and throttle axes when it's in native mode?
Attached files
0001-Add-full-support-for-DFGT.patch.txt - 1.7 KB - 444 views
Quote from MadCatX :There'll be no FF 'cause of missing support in the lgff driver. Does DFGT report separate brake and throttle axes when it's in native mode?

I was thinking about adding all ids listed in the logitech drivers inf anyway (but i guess it's better to test things first). E.Reiljans, can/are you willing to compile a kernel?
Quote from slim.one :E.Reiljans, can/are you willing to compile a kernel?

I don't think that's necessary right now, unless he wants to get FF working; DFGT id is missing from hid-ids.h and hid-lg.c anyway. There's been an idea to move all FF handling of wheels from lgff.c to lg4ff.c. Lgff.c is pretty much joystick-oriented and modifying it for wheels could possibly break functionality with joysticks.
The plan is to get as much info about the commands as possible so we can decide how many device-specific quirks we need and how to implement them.
Quote from slim.one :E.Reiljans, can/are you willing to compile a kernel?

Sure, I can do that tomorrow. But where to get latest version of kernel patch for Logitech wheels? Most likely will do 3.0-rc3 if there's PKGBUILD for it somewhere in AUR.
Quote from MadCatX :I don't think that's necessary right now, unless he wants to get FF working;

I do want to get FF working, there's no point playing without it :P
Right now there isn't anything like a really working patch 'cause there are few things that have to be changed and tested. To get a quick and dirty FF for DFGT, following lines have to be added

drivers/hid/hid-ids.h

#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 0xc29A

anywhere, but there's a Logitech devices section in the file

drivers/hid/hid-lg.c

{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
.driver_data = LG_FF },

to lg_devices[] array

drivers/hid/hid-lgff.c

{ 0x046d, 0xc29a, ff_wheel },

to devices[] array.

I've been using attached PKGBUILD and kernel26.install for ages to build my custom kernels. Adjust the files accordingly to the kernel version you're building, copy both files to a directory with unpacked kernel source and run makepkg. I uncommented the mkinitcpio calls in kernel26.install for you, but as I've removed initrd support from my kernel I dunno if it still works correctly - you might want to check that.
Attached files
kernel26-my.zip - 1.4 KB - 406 views
Ok, I'll try that tomorrow
Quote from MadCatX :Right now there isn't anything like a really working patch 'cause there are few things that have to be changed and tested.

can you elaborate this a bit? Feel free to add me as CC: to your conversation with Simon
I'm just about to get away for the weekend so I can't get into much details, but the basic idea is kinda like this:

Lgff driver accounts for both X and Y forces in constant-force effect. That's not something you'd want to do for a wheel 'cause it doesn't have any Y axis you could apply force on. Force on Y axis has to be always 0x80 = no force. We've also found out that apparently all LG wheels support FF_FRICTION and FF_INERTIA effect so we'd like to implement that too. Problem is that there seem to be slight differences between command formats, some wheels accept multiple commands without a hiccup, some accept the command but behave differently etc etc, guess you get the idea.
What's most troubling is the FF_AUTOCENTER as EVERY wheel we have a chance to check needs it's specific quirks. The plan is to get all wheel FF handling to lg4ff and make that driver wheel-only.
I'll CC you any following mails we'll exchange, we sure can use any help we can get
Quote from MadCatX :The autocentering is what looks most troubling at the moment. Every wheel we tested so far seems to use a bit different command format. If you can waste another 5 minutes of your existence doing another sniff, here how:
- Launch USBLyzer and select your wheel as you did before
- Open the Logitech control panel, open the configuration window and enable "Centering spring"
- Set the strength to 0 %, close the config window, and open in again (driver sends data to the wheel only after the config window is closed)
- Increase strength by 25 % and repeat the opening/closing until you reach the maximum.
When you upload the logs, please export them as HTML so I don't have to launch windows every time I want to read them

MadCatX - should i do that too with my Formula EX or you already have the data you want?
As of now it doesn't. We use a userspace tool where user must specify the type of the wheel and the tool then sends the proper command. It's possible the use USB revision number to tell the wheels apart, we just haven't gotten around to update the tool yet.

As for the FF_INERTIA, I'm actually not sure how to call the effect we observe. It's kind of opposite to FF_FRICTION, when the wheel is turned, it generates force which "assists" the turning, it feels a bit like electric power steering.

Simon Wood wrote a Python script which sends few commands to the wheel. Can you guys give it a try and report how does your wheel respond to them? To run the script you need pyusb, old libusb 0.1 (the pre-1.0 one, sometimes called libusb-compat) and Python2 (some distros use Python3 as default - script doesn't work with it). The script has to be run as root.
Before you run the script, change the productId on line 14 to match your wheel. If you get "usb.USBError: Input/output error", change the OUT port from 0x02 accordingly (run lsusb -vv to find out correct OUT port).
Attached files
check_pyusb.txt - 3.4 KB - 455 views
Quote from wolfshark :MadCatX - should i do that too with my Formula EX or you already have the data you want?

If you have the time it'd be great.
I opened the config utility and then started capturing to eliminate unneeded junk. I started from 100%, then 75%, 50%, 25%, 0%

Edit: repacked the archive again - forgot to export to html
Attached files
FormulaEX_CenterSpring.zip - 13.9 KB - 428 views
MadCatX, how to make wine work on x64 arch? :/
I've been %&*#ing with it whole yesterday's evening and haven't got it to launch LFS yet. Guess I'll have to side-by-side install 32-bit arch :|
Do you have multilib repo enabled? There's WINE package there that works like a dream... it installs a bit of 32bit crap, so try not to grind your teeth to much while it installs
Hmm, I'd rather not fill my 2nd OS with 32-bit crap. Guess I'm forced to do side-by-side 32-bit install then.
I felt the same about it, but then I figured that triple-booting 32 Arch/64 Arch/Win or messing around with chrooting is just not worth it. If anything the situation is much better than in Windows. Right now I have about 40 packages of 32bit garbage installed (most of it because of WINE) and I don't really care. Except for having to install 32bit libs for the graphics driver I barely know about it. The pros clearly beat the cons for me... whatever you decide to do, I'm looking forward to seeing how the DFGT will work for you...
It's kinda necessary to clean up the mess, so there goes another tool whose purpose is to check if at least some commands are supported by all LG wheels. The tool tells you what effect is expected to be generated. It can also send a fully custom command when run like "-c AABBCCDDEEFFGGHH".


#include <getopt.h>
#include <libusb-1.0/libusb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VID_LOGITECH 0x046D
#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])

typedef struct {
unsigned char cmd[8];
char desc[64];
} ff_cmd;

static const unsigned int device_ids[] = {0xC294, /* DF */
0xC298, /* DFP */
0xC299, /* G25 */
0xC29A, /* DFGT */
0xC29B /* G27 */
};

static struct option long_options[] = {
{"custom", required_argument, 0, 'c'},
{0, 0, 0, 0}
};

/* Standard commands that should be accepted by all
* Logitech wheels */
static ff_cmd std_commands[] = {
//Test autocentering
{ {0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Reset effects"},
{ {0xFE, 0x0D, 0x07, 0x07, 0xFF, 0x00, 0x00, 0x00}, "Full autocentering"},
{ {0xFE, 0x0D, 0x03, 0x03, 0x80, 0x00, 0x00, 0x00}, "Medium autocentering"},
{ {0xFE, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "No autocentering"},

//Test constant force
{ {0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Reset effects"},
{ {0x11, 0x08, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00}, "Full left constant force"},
{ {0x11, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00}, "Full right constant force"},
{ {0x11, 0x08, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00}, "No constant force"},

//Remove autocentering and constant force
{ {0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Reset effects"},
{ {0xFE, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "No autocentering"},

//Test friction
{ {0x21, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00}, "Clockwise resistance"},
{ {0x21, 0x02, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}, "Counter-clockwise resistance"},
{ {0x21, 0x02, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00}, "Resistance both ways"},
{ {0x21, 0x02, 0x0F, 0x01, 0x0F, 0x01, 0x00, 0x00}, "'Assistance' both ways"},
{ {0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "Reset friction"}
};

/* Autocentering commands for Formula EX */
static ff_cmd fex_ac_commands[] = {
//Test autocentering
{ {0xFE, 0x03, 0x07, 0x07, 0xFF, 0x00, 0x00, 0x00}, "Full autocentering"},
{ {0xFE, 0x03, 0x03, 0x03, 0x80, 0x00, 0x00, 0x00}, "Medium autocentering"},
{ {0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, "No autocentering"},
};


libusb_device_handle* find_wheel()
{
libusb_device_handle* hDev = NULL;

for(int i = 0; i < ARRAY_SIZE(device_ids); i++) {
hDev = libusb_open_device_with_vid_pid(NULL, VID_LOGITECH, device_ids[i]);
if(hDev != 0) {
printf("%s %X\n", "Found wheel - PID ", device_ids[i]);
break;
}
}

return hDev;
}

int send_custom_command(unsigned char* cmd, libusb_device_handle* hDev)
{
//Get access to the wheel
int stat;
stat = libusb_detach_kernel_driver(hDev, 0);
if (stat < 0) {
fprintf(stderr, "Cannot detach kernel driver\n");
return -1;
}

stat = libusb_claim_interface(hDev, 0);
if (stat < 0) {
fprintf(stderr, "Cannot claim interface\n");
return -1;
}

//Send command
int transferred = 0;

stat = libusb_interrupt_transfer(hDev, 1, cmd, sizeof(cmd),
&transferred, 3000);

printf("Bytes sent: %d\n", transferred);

if (stat < 0) {
fprintf(stderr, "Error sending USB command");
return -1;
}

//Release interface and hand control over to kernel
stat = libusb_release_interface(hDev, 0);
if (stat < 0) {
fprintf(stderr, "Cannot release interface\n");
return -1;
}

stat = libusb_attach_kernel_driver(hDev, 0);
if (stat < 0) {
fprintf(stderr, "Cannot reattach kernel driver\n");
return -1;
}

return 0;
}

int send_command(unsigned char* cmd, libusb_device_handle* hDev)
{
int transferred = 0;

int stat = libusb_interrupt_transfer(hDev, 1, cmd, sizeof(cmd),
&transferred, 3000);

if (stat < 0) {
fprintf(stderr, "Error sending USB command");
return -1;
}

return 0;
}

int main(int argc, char** argv)
{
char* custom_cmd_s = NULL;

libusb_init(NULL);

libusb_device_handle* hDev = find_wheel();
if(hDev == NULL) {
printf("No wheel found\n");
libusb_exit(NULL);
return -1;
}

while(optind < argc) {
int idx = -1;
int result = getopt_long(argc, argv, "c:",
long_options, &idx);
switch(result) {
case 'c':
custom_cmd_s = calloc(sizeof(char), 16);
strcpy(custom_cmd_s, optarg);

//Create command
char temp[3];
unsigned char byte;
unsigned char custom_cmd[8];

memset(custom_cmd, 0, sizeof(custom_cmd));
temp[2] = '\0';
int i = 0;
while(i < 8) {
memcpy(temp, custom_cmd_s+(i*2), 2);
if(strcmp(temp, "") == 0)
break;

sscanf(temp, "%X", &byte);
custom_cmd[i++] = byte;
}

for(int j = 0; j < 8; j++) {
printf("%02X ", custom_cmd[j]);
}

printf("\nPress ENTER to send command\n");
getchar();
send_custom_command(custom_cmd, hDev);

free(custom_cmd_s);
libusb_exit(NULL);

return 0;
}
}

//Get access to the wheel
int stat;
stat = libusb_detach_kernel_driver(hDev, 0);
if (stat < 0)
fprintf(stderr, "Cannot detach kernel driver\n");

stat = libusb_claim_interface(hDev, 0);
if (stat < 0)
fprintf(stderr, "Cannot claim interface\n");

//Send standard commands
for(int i = 0; i < ARRAY_SIZE(std_commands); i++) {
send_command(std_commands[i].cmd, hDev);
printf("%s\n%s", std_commands[i].desc, "Press ENTER to continue\n");
getchar();
}

printf("Test autocentering for Formula EX? (Y/N)\n");
char c = getchar();
if(c == 'y' || c == 'Y') {
//Send Formula EX AC commands
for(int i = 0; i < ARRAY_SIZE(fex_ac_commands); i++) {
send_command(std_commands[i].cmd, hDev);
printf("%s\n%s", fex_ac_commands[i].desc, "Press ENTER to continue\n");
getchar();
}
}

//Release interface and hand control over to kernel
stat = libusb_release_interface(hDev, 0);
if (stat < 0)
fprintf(stderr, "Cannot release interface\n");

stat = libusb_attach_kernel_driver(hDev, 0);
if (stat < 0)
fprintf(stderr, "Cannot reattach kernel driver\n");

libusb_exit(NULL);
return 0;
}

I'm posting from my iPod which won't allow me to attach anything (sorry guys). Source can be compiled like this "gcc -std=gnu99 -lusb-1.0 src.c -o check_cmds"
Quote from MadCatX :It's kinda necessary to clean up the mess, so there goes another tool whose purpose is to check if at least some commands are supported by all LG wheels. The tool tells you what effect is expected to be generated. It can also send a fully custom command when run like "-c AABBCCDDEEFFGGHH".

G27 supports all commands. Assistance is very funny
Wow, 2 weeks vacation and some good progress here
@MadCatx: I'll check your tool with the Momo racing, for DFP and G25 you have everything already, right?

FGED GREDG RDFGDR GSFDG