Kimplul / hid-tmff2

Linux kernel module for Thrustmaster T300RS, T248 and (experimental) TX, T128 and TS-XW wheels
GNU General Public License v3.0
204 stars 20 forks source link

Thrustmaster TS-PC (TS Racer) support #65

Open solarisfire opened 1 year ago

solarisfire commented 1 year ago

Any chance this wheelbase could be supported?

Should be similar to some of the other bases.

Currently just getting:

[ 308.587876] usb 3-2.3: new full-speed USB device number 10 using xhci_hcd [ 308.714187] usb 3-2.3: New USB device found, idVendor=044f, idProduct=b65d, bcdDevice= 7.00 [ 308.714189] usb 3-2.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ 308.714191] usb 3-2.3: Product: Thrustmaster FFB Wheel [ 308.714192] usb 3-2.3: Manufacturer: Thrustmaster [ 308.814269] input: Thrustmaster Thrustmaster FFB Wheel as /devices/pci0000:00/0000:00:01.2/0000:02:00.0/0000:03:08.0/0000:07:00.3/usb3/3-2/3-2.3/3-2.3:1.0/0003:044F:B65D.0013/input/input30 [ 308.814347] hid-tminit 0003:044F:B65D.0013: input,hidraw17: USB HID v1.00 Gamepad [Thrustmaster Thrustmaster FFB Wheel] on usb-0000:07:00.3-2.3/input0 [ 308.834183] hid-tminit 0003:044F:B65D.0013: Unknown wheel's model id 0x6, unable to proceed further with wheel init

Kimplul commented 1 year ago

Any chance this wheelbase could be supported?

Supported, probably yes, but how much work that would take is hard to say. Unfortunately thrustmaster wheels don't seem to really follow any consistent APIs, so two seemingly similar wheels may require wildly different implementations.

Did you already read https://github.com/Kimplul/hid-tmff2/wiki#how-to-add-in-support-for-a-new-t-series-wheel? In addition to the stuff in the wiki, it seems that the TS-PC's initialization value is unknown, so we'd need some USB packet captures of plugging the wheel in as well. The value would have to be added to the wheel table in hid-tminit.

solarisfire commented 1 year ago

I am going to try and get the USB traces for this... just struggling to find some free time to do it!

Potajito commented 11 months ago

I also have a TS-PC would love to give a hand.

Kimplul commented 11 months ago

@Potajito thanks for showing interest. As far as I'm aware, no USB packet captures have been made, so the general outline in https://github.com/Kimplul/hid-tmff2/issues/65#issuecomment-1537419377 still applies. Please read through https://github.com/Kimplul/hid-tmff2/wiki#how-to-add-in-support-for-a-new-t-series-wheel and if you feel up for, try doing some captured and seeing if you can find some patterns in the data.

solarisfire commented 11 months ago

Could do with some guidance when capturing.

It just seems to be a stream of URB_INTERRUPT and URB_CONTROL packets.

It did come back with some data on unplug/replug but not sure which bits would be the initialization value.

DEVICE DESCRIPTOR bLength: 18 bDescriptorType: 0x01 (DEVICE) bcdUSB: 0x0100 bDeviceClass: Device (0x00) bDeviceSubClass: 0 bDeviceProtocol: 0 (Use class code info from Interface Descriptors) bMaxPacketSize0: 8 idVendor: ThrustMaster, Inc. (0x044f) idProduct: Unknown (0xb65d) bcdDevice: 0x0700 iManufacturer: 1 iProduct: 2 iSerialNumber: 0 bNumConfigurations: 1

https://drive.google.com/file/d/13odXGOEfqU_Wfi7NfChZVsW5YsEGFQTp/view?usp=share_link

Not sure where I'd start trying to work out any sort of values for force feedback values. I think I need to find a tutorial for FEdit1...

Kimplul commented 11 months ago

Sure, thanks for the capture. Just to start off with, the initial wheel state is with idProduct 0xb65d, and the Windows driver then sends out a packet to restart the wheel. After the restart, the wheel reconnects with idProduct 0xb689, as can be seen at packet no. 156 in your capture. So there should be at least one URB_CONTROL out from host to 3.1.0 in the first 150 or so packets that approximately matches https://github.com/scarburato/hid-tminit/blob/9375f6c7d83af5dd6c8b8fe30351d0f36043b20a/hid-tminit.c#L140

In this case, it seems to be packet number 151, and from this we can see that the wValue used is 0x0009. This is the switch_value in struct tm_wheel_info.

Then we need to find another packet with the wheel's IDs. The wheel sends a packet to the computer, which should contain a number of bytes, two of which we're mainly interested in: one for the base model and one for the steering wheel attachment. These correspond to model and attachment in struct tm_wheel_info. This data should be found in a packet with bRequest == 73. There are actually multiple of these packets for some reason (I'm guessing the Windows driver queries different parameters from different parts of the codebase, and it doesn't cache these parameters anywhere so it just requests them multiple times).

Anycase, looking at the data in packet 68, we see that the response data is 49 00 03 04 01 00 09 06 f9 01 00 00 09 01 00 00. This more or less looks like the other captures (some examples can be seen in the README in hid-tminit). Bytes 6 and 7 should be the attachment and model, respectively, so in this case model = 0x06 and attachment = 0x09. Adding an element to tm_wheel_infos[] should get hid-tminit to initialize wheel properly, something like

[...]
{0x06, 0x09, 0x0009, "Thrustmaster TS-PC"},
[...]

With my T300, for some reason I also had to send out a number of other packets, see https://github.com/scarburato/hid-tminit/blob/9375f6c7d83af5dd6c8b8fe30351d0f36043b20a/hid-tminit.c#L26,

but other wheels don't seem to require this so I would expect that the TS-PC doesn't either.

Not sure where I'd start trying to work out any sort of values for force feedback values. I think I need to find a tutorial for FEdit1...

If you find one, let me know, not aware of any. Probably the biggest individual hurdle is the fact that you have to set the direction of the effect, the default of 'straight up' effectively translates to multiplying the force's magnitude by 0, i.e. makes the effect impossible to detect. Try dragging the direction pointer all the way to the right for example, and then go from there. Maybe go for studying just one effect at a time, i.e. press the effect button and drag it to the timeline. Note that the location on the timeline effectively adds a delay, i.e. to immediately feel an effect drag it as far left as possible.

Other than that, I guess it's worth keeping in mind that wheels typically have a couple different kinds of packets, ones that upload effects to the device and ones that modify already uploaded effects. Took me a while to figure that one out, but essentially when close the effect modification window, you should see the effect get uploaded with all possible configuration values initialized. After that, if you open up the modification window again and tweak one parameter, you should see a number of packets that each modify only the parameter you've just tweaked. If the packets you capture look like ones in https://github.com/Kimplul/hid-tmff2/blob/master/docs/FFBEFFECTS.md,

then it should be fairly straightforward to just add the wheel's USB product ID to the list of supported devices for this driver. Otherwise, you'll have to try and reverse engineer the packets yourself.

I encourage playing around with FEdit, it's ultimately not a particularly complicated program, as it more or less one-to-one maps parameters in the GUI to parameters that get sent to the wheel. The interface is just a bit daunting.

Feel free to ask questions, I'll try to help as best as I can.

svenliekens commented 8 months ago

Hi

I have recently switched to Fedora from Windows and have been trying to get my TS-PC RACER to work on Linux.

I started playing with FEdit and wireshark on a spare laptop with the wheel connected. Have managed to capture the Spring effect. It looks like it uses the same parameters as listed in the FFBEFFECTS doc. See the attached capture file (packet no. 5) spring_effect_capture2.zip

At this point I made the quick assumption that the rest of the FFB effects would be the same. I decided to try to build the kernel module.

This resulted in the following output

~/hid-tmff2$ sudo make
[sudo] password for sven: 
make -C deps/hid-tminit KDIR="/lib/modules/6.6.11-200.fc39.x86_64/build" 
make[1]: Entering directory '/home/sven/hid-tmff2/deps/hid-tminit'
make -C /lib/modules/6.6.11-200.fc39.x86_64/build M=/home/sven/hid-tmff2/deps/hid-tminit modules
make[2]: Entering directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
make[2]: Leaving directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
make[1]: Leaving directory '/home/sven/hid-tmff2/deps/hid-tminit'
make -C /lib/modules/6.6.11-200.fc39.x86_64/build M=/home/sven/hid-tmff2 modules
make[1]: Entering directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
make[1]: Leaving directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
~/hid-tmff2$ sudo make install
make -C deps/hid-tminit KDIR="/lib/modules/6.6.11-200.fc39.x86_64/build" install
make[1]: Entering directory '/home/sven/hid-tmff2/deps/hid-tminit'
make -C /lib/modules/6.6.11-200.fc39.x86_64/build M=/home/sven/hid-tmff2/deps/hid-tminit modules_install
make[2]: Entering directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
  INSTALL /lib/modules/6.6.11-200.fc39.x86_64/updates/hid-tminit.ko
  SIGN    /lib/modules/6.6.11-200.fc39.x86_64/updates/hid-tminit.ko
At main.c:167:
- SSL error:FFFFFFFF80000002:system library::No such file or directory: crypto/bio/bss_file.c:67
- SSL error:10000080:BIO routines::no such file: crypto/bio/bss_file.c:75
sign-file: ./certs/signing_key.pem
  DEPMOD  /lib/modules/6.6.11-200.fc39.x86_64
make[2]: Leaving directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
make[1]: Leaving directory '/home/sven/hid-tmff2/deps/hid-tminit'
make -C /lib/modules/6.6.11-200.fc39.x86_64/build M=/home/sven/hid-tmff2 modules_install
make[1]: Entering directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
  INSTALL /lib/modules/6.6.11-200.fc39.x86_64/updates/hid-tmff-new.ko
  SIGN    /lib/modules/6.6.11-200.fc39.x86_64/updates/hid-tmff-new.ko
At main.c:167:
- SSL error:FFFFFFFF80000002:system library::No such file or directory: crypto/bio/bss_file.c:67
- SSL error:10000080:BIO routines::no such file: crypto/bio/bss_file.c:75
sign-file: ./certs/signing_key.pem
  DEPMOD  /lib/modules/6.6.11-200.fc39.x86_64
make[1]: Leaving directory '/usr/src/kernels/6.6.11-200.fc39.x86_64'
depmod -A

I think something went wrong at the SIGN step, so I'm not sure if the build succeeded or not...

~/hid-tmff2$ lsmod | grep thrust
hid_thrustmaster       16384  0

It seems like the kernel module is loaded.

When I start Assetto Corsa (via proton-ge) my wheel is not recognised.

How should I proceed? I will test some more of the FFB effects in the mean time and compare them to the FFBEFFECTS doc.

Kimplul commented 8 months ago

I think something went wrong at the SIGN step, so I'm not sure if the build succeeded or not...

Signing the module is an optional step that has to be done by whoever builds the module. The error messages are pretty scary but generally don't stop the module from functioning. There's a separate kernel configuration parameter that can disable loading unsigned modules, but it tends to not be enabled on major distros. There's a short note about it in the README.

It seems like the kernel module is loaded.

The naming is a bit messy here, hid-thrustmaster is the in-kernel counterpart of hid-tminit which is a separate module just to initialize different Thrustmaster wheels. For whatever reason Thrustmaster wheels have to be reminded which model they are, and only after that is done can FFB be used, which is what this module handles. This (hid-tmff2) module would actually show up as hid-tmff-new in lsmod because of some name handling limitations in Kbuild.

Anycase, once the wheel is told which model it is, it restarts itself and reconnects under a new USB id, which you will have to add to https://github.com/Kimplul/hid-tmff2/blob/9f79c8ede052227a32ac0e63cab4e2afe8c01a1e/src/hid-tmff2.c#L721

and https://github.com/Kimplul/hid-tmff2/blob/9f79c8ede052227a32ac0e63cab4e2afe8c01a1e/src/hid-tmff2.c#L618

It's possible that the TS-PC differs in some subtle ways from other wheels supported (different wheel range, init commands, rdesc, whatever), so you might have to add a new subdir in src. Just copy one of the existing ones and tweak values found therein. Remember to point src/Kbuild to the new dir. Unfortunately I can't really help much in figuring out which bits (if any) might have to be flipped, it was a lot of trial and error when I went through it with the T300. Mostly I just tried to get the USB traffic to resemble the captures as close as possible.

Check out sudo dmesg -w when you plug the wheel in, should show the USB product ID and (typically) helpful error messages.

svenliekens commented 8 months ago

The changes I have made to hid-tminit

~/hid-tmff2/deps/hid-tminit$ git diff
diff --git a/hid-tminit.c b/hid-tminit.c
index 266086e..05e35c3 100644
--- a/hid-tminit.c
+++ b/hid-tminit.c
@@ -70,11 +70,12 @@ static const struct tm_wheel_info tm_wheels_infos[] = {
        ...
        {0x02, 0x04, 0x0005, "Thrustmaster T300 Ferrari Alcantara Edition"},
        {0x02, 0x06, 0x0005, "Thrustmaster T300RS"},
        {0x02, 0x09, 0x0005, "Thrustmaster T300RS (Open Wheel Attachment)"},
-       {0x03, 0x06, 0x0006, "Thrustmaster T150RS"}
+       {0x03, 0x06, 0x0006, "Thrustmaster T150RS"},
+       {0x06, 0x09, 0x0009, "Thrustmaster TS-PC"},
        //{0x04, 0x07, 0x0001, "Thrustmaster TMX"}
 };

-static const uint8_t tm_wheels_infos_length = 7;
+static const uint8_t tm_wheels_infos_length = 8;

The changes I have made to hid-tmff2

~/hid-tmff2$ git diff
--- a/src/hid-tmff2.c
+++ b/src/hid-tmff2.c
@@ -616,6 +616,7 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id)
        hid_set_drvdata(tmff2->hdev, tmff2);

        switch (tmff2->hdev->product) {
+               case TMTS_PC_RACER_ID: 
                case TMT300RS_PS3_NORM_ID:
                case TMT300RS_PS3_ADV_ID:
                case TMT300RS_PS4_NORM_ID:
@@ -727,7 +728,8 @@ static const struct hid_device_id tmff2_devices[] = {
        {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMT248_PC_ID)},
        /* tx */
        {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TX_ACTIVE)},
-
+       /* TS-PC RACER */
+       {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMTS_PC_RACER_ID)},
        {}
 };
 MODULE_DEVICE_TABLE(hid, tmff2_devices);
diff --git a/src/hid-tmff2.h b/src/hid-tmff2.h
index 1eb3546..822a598 100644
--- a/src/hid-tmff2.h
+++ b/src/hid-tmff2.h
@@ -111,6 +111,8 @@ int tx_populate_api(struct tmff2_device_entry *tmff2);

 #define TX_ACTIVE               0xb669

+#define TMTS_PC_RACER_ID 0xb689
+

After sudo make && sudo make install I plug in the wheel and get the following output in dmesg. I tried some things but I'm not sure how to fix this :grimacing:

[21716.528256] usb 3-3.1: new full-speed USB device number 6 using xhci_hcd
[21716.642259] usb 3-3.1: New USB device found, idVendor=044f, idProduct=b65d, bcdDevice= 7.00
[21716.642264] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[21716.642267] usb 3-3.1: Product: Thrustmaster FFB Wheel
[21716.642269] usb 3-3.1: Manufacturer: Thrustmaster
[21716.725411] input: Thrustmaster Thrustmaster FFB Wheel as /devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3/3-3/3-3.1/3-3.1:1.0/0003:044F:B65D.000B/input/input20
[21716.725549] hid-thrustmaster 0003:044F:B65D.000B: input,hidraw9: USB HID v1.00 Gamepad [Thrustmaster Thrustmaster FFB Wheel] on usb-0000:09:00.3-3.1/input0
[21716.745230] hid-thrustmaster 0003:044F:B65D.000B: Unknown wheel's model id 0x609, unable to proceed further with wheel init
[21716.759400] Error: Driver 'hid-thrustmaster' is already registered, aborting...

Seems like the wheel connects as id 0xb65d, but it doesn't get to the part where it restarts and uses new ID 0xb689.

I'm not even sure where wheel's model id 0x609 is coming from.

I have confirmed in my USB captures that on the Windows driver it uses the above IDs (0xb65d -> 0xb689, as you already figured out in a previous comment)

Kimplul commented 8 months ago

After sudo make && sudo make install I plug in the wheel and get the following output in dmesg. I tried some things but I'm not sure how to fix this 😬

Oh right, you'll have to blacklist the in-kernel module:

echo 'blacklist hid_thrustmaster' > /etc/modprobe.d/hid_thrustmaster.conf

There's some weird name clash that happens otherwise, meaning the changes you've made haven't actually been run yet.

I'm not even sure where wheel's model id 0x609 is coming from.

Here: https://elixir.bootlin.com/linux/latest/source/drivers/hid/hid-thrustmaster.c#L240 Essentially, the wheel sends a response to a init driver query, and the 'actual' wheel ID is in that response. You'd think the USB id was the main ID but nah, that would be too easy. Anyway, you've already added it to the driver as 0x6, 0x9, it just gets printed differently in the in-kernel module.

svenliekens commented 8 months ago
[  100.396525] usb 3-3.1: new full-speed USB device number 5 using xhci_hcd
[  100.510157] usb 3-3.1: New USB device found, idVendor=044f, idProduct=b65d, bcdDevice= 7.00
[  100.510165] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  100.510169] usb 3-3.1: Product: Thrustmaster FFB Wheel
[  100.510171] usb 3-3.1: Manufacturer: Thrustmaster
[  100.595651] input: Thrustmaster Thrustmaster FFB Wheel as /devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3/3-3/3-3.1/3-3.1:1.0/0003:044F:B65D.000A/input/input18
[  100.595787] hid-thrustmaster 0003:044F:B65D.000A: input,hidraw9: USB HID v1.00 Gamepad [Thrustmaster Thrustmaster FFB Wheel] on usb-0000:09:00.3-3.1/input0
[  100.616128] hid-thrustmaster 0003:044F:B65D.000A: Wheel with (model, attachment) = (0x6, 0x9) is a Thrustmaster TS-PC. attachment_found=1
[  100.618320] hid-thrustmaster 0003:044F:B65D.000A: Success?! The wheel should have been initialized!
[  100.711616] usb 3-3.1: USB disconnect, device number 5
[  101.419230] usb 3-3.1: new full-speed USB device number 6 using xhci_hcd
[  101.536158] usb 3-3.1: New USB device found, idVendor=044f, idProduct=b689, bcdDevice= 7.00
[  101.536167] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  101.536170] usb 3-3.1: Product: Thrustmaster TS-PC Racer
[  101.536173] usb 3-3.1: Manufacturer: Thrustmaster
[  101.612400] input: Thrustmaster Thrustmaster TS-PC Racer as /devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3/3-3/3-3.1/3-3.1:1.0/0003:044F:B689.000B/input/input19
[  101.612579] hid-generic 0003:044F:B689.000B: input,hidraw9: USB HID v1.11 Joystick [Thrustmaster Thrustmaster TS-PC Racer] on usb-0000:09:00.3-3.1/input0
[  101.647434] input: Thrustmaster Thrustmaster TS-PC Racer as /devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3/3-3/3-3.1/3-3.1:1.0/0003:044F:B689.000B/input/input20
[  101.647577] tmff2 0003:044F:B689.000B: input,hidraw9: USB HID v1.11 Joystick [Thrustmaster Thrustmaster TS-PC Racer] on usb-0000:09:00.3-3.1/input0
[  101.649134] tmff2 0003:044F:B689.000B: firmware version 13 is too old, please update.
[  101.649137] tmff2 0003:044F:B689.000B: note: this has to be done through Windows.
[  101.649139] tmff2 0003:044F:B689.000B: failed initializing T300RS
[  101.649140] tmff2 0003:044F:B689.000B: init failed
[  101.668285] tmff2: probe of 0003:044F:B689.000B failed with error -22

We are making progress! Looks like the restart (init) is working and we're getting into tmff2 territory.

It is now complaining about the firmware version being too old. But I have the newest TS PC firmware...

I assume this is where I make a subdir for the TS-PC racer, as you mentioned before (start with a copy of the T300RS?)

It's possible that the TS-PC differs in some subtle ways from other wheels supported (different wheel range, init commands, rdesc, whatever), so you might have to add a new subdir in src. Just copy one of the existing ones and tweak values found therein. Remember to point src/Kbuild to the new dir. Unfortunately I can't really help much in figuring out which bits (if any) might have to be flipped, it was a lot of trial and error when I went through it with the T300. Mostly I just tried to get the USB traffic to resemble the captures as close as possible.

Kimplul commented 8 months ago

We are making progress! Looks like the restart (init) is working and we're getting into tmff2 territory.

Excellent!

I assume this is where I make a subdir for the TS-PC racer, as you mentioned before (start with a copy of the T300RS?)

Yep, looks appropriate. Try maybe copying tmt248 instead, T300 is the 'base' for the other wheels and they use functions defined in tmt300rs, and the less you have to copy the better. Eventually I might refactor things to be a bit more clear, but as this was originally a T300 driver everything sort of evolved to be built on top of that wheel.

The T248 also doesn't currently have a firmware version check, so less changes to be made.

svenliekens commented 8 months ago
[ 2129.709212] usb 3-3.1: new full-speed USB device number 11 using xhci_hcd
[ 2129.826621] usb 3-3.1: New USB device found, idVendor=044f, idProduct=b65d, bcdDevice= 7.00
[ 2129.826629] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2129.826633] usb 3-3.1: Product: Thrustmaster FFB Wheel
[ 2129.826635] usb 3-3.1: Manufacturer: Thrustmaster
[ 2129.902793] input: Thrustmaster Thrustmaster FFB Wheel as /devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3/3-3/3-3.1/3-3.1:1.0/0003:044F:B65D.0010/input/input26
[ 2129.902972] hid-thrustmaster 0003:044F:B65D.0010: input,hidraw9: USB HID v1.00 Gamepad [Thrustmaster Thrustmaster FFB Wheel] on usb-0000:09:00.3-3.1/input0
[ 2129.922592] hid-thrustmaster 0003:044F:B65D.0010: Wheel with (model, attachment) = (0x6, 0x9) is a Thrustmaster TS-PC. attachment_found=1
[ 2129.924784] hid-thrustmaster 0003:044F:B65D.0010: Success?! The wheel should have been initialized!
[ 2130.026081] usb 3-3.1: USB disconnect, device number 11
[ 2130.730854] usb 3-3.1: new full-speed USB device number 12 using xhci_hcd
[ 2130.846596] usb 3-3.1: New USB device found, idVendor=044f, idProduct=b689, bcdDevice= 7.00
[ 2130.846602] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2130.846605] usb 3-3.1: Product: Thrustmaster TS-PC Racer
[ 2130.846607] usb 3-3.1: Manufacturer: Thrustmaster
[ 2130.926887] input: Thrustmaster Thrustmaster TS-PC Racer as /devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3/3-3/3-3.1/3-3.1:1.0/0003:044F:B689.0011/input/input27
[ 2130.927082] tmff2 0003:044F:B689.0011: input,hidraw9: USB HID v1.11 Joystick [Thrustmaster Thrustmaster TS-PC Racer] on usb-0000:09:00.3-3.1/input0
[ 2130.933832] tmff2 0003:044F:B689.0011: force feedback for tspc

I now have the wheel showing up on https://hardwaretester.com/gamepad The steering axis is working perfectly. I have played BeamNG with it. Force feedback seems to be doing nothing even though I have it enabled in the game.

So we're going in the right direction here, but I'm not sure on how to proceed... :grimacing:

Kimplul commented 8 months ago

So we're going in the right direction here, but I'm not sure on how to proceed... 😬

Right, here are a couple things to try, off the top of my head

1) Try capturing some packets from the driver, do they match the ones you captured earlier? 0x60 0x01 ...?

If they don't, the packet format changes slightly depending on some values in the rdesc, and it might be that the TS-PC rdesc differs from the one the T248 uses. For example, I captured the T248 rdesc from the wheel and had to change these two lines: https://github.com/Kimplul/hid-tmff2/blob/9f79c8ede052227a32ac0e63cab4e2afe8c01a1e/src/tmt248/hid-tmt248.c#L115 https://github.com/Kimplul/hid-tmff2/blob/9f79c8ede052227a32ac0e63cab4e2afe8c01a1e/src/tmt248/hid-tmt248.c#L113

2) The wheel might require some extra initialization packets. The T248, for whatever reason, needs these packets to be sent out before anything else happens:

https://github.com/Kimplul/hid-tmff2/blob/9f79c8ede052227a32ac0e63cab4e2afe8c01a1e/src/tmt248/hid-tmt248.c#L9

The T300 didn't need them, so this might be something that changes from wheel to wheel. Maybe try checking if you can see anything similar in your Windows captures.

3) The wheel only processes FFB after it gets sent some enable packets. The driver sends these packets when something opens the wheel:

https://github.com/Kimplul/hid-tmff2/blob/9f79c8ede052227a32ac0e63cab4e2afe8c01a1e/src/tmt300rs/hid-tmt300rs.c#L1421

The T248 needs an extra packet here as well that the T300 didn't need, so the TS-PC might also differ in this regard. Check if you can see any extra packets being sent in Windows when you open a program that connects to the wheel.

Good luck, you've just stumbled on the tedious part of reverse engineering :)

Potajito commented 5 months ago

I gave up basically at the same point that @svenliekens did, but, shouldn't this https://github.com/Kimplul/hid-tmff2/pull/94 bring also compat to ts-pc, as ts-xw is basically the same wheel base? :thinking:

Kimplul commented 5 months ago

@Potajito certainly possible, but you'd have to try it out for yourself. I don't really know what the differences between the TS-PC and TS-XW are, the bases definitely look similar but that hasn't always been a reliable indicator of compatibility. They don't seem to share the same USB PID at least, but you could start out by doing something like

case TSPC_ACTIVE:
case TSXW_ACTIVE:
                     if ((ret = tsxw_populate_api(tmff2)))
...
BDave95 commented 2 months ago

Hello, first of all thank you very much for this project, if we had to wait for Thrustmaster do do anything for us ... well After following all steps in this thread to modify all needed files my TS-PS F458 edition is detected, and FFB seems to work, tested only with ETS2 for now but installing AC now to test with it, and pedals connected to it works also.

So this is a very good start but there's still some issues to fix :

The problem is my programming skills are limited to following tutos, and using existing files as templates to guess changes to do, so i will need help/direction to follow to investigate more.

The only thing i can think of for now is i added a directory for the tspc in /src but i have copied the T248 one as a base, maybe it would have been smarter to start from tsxw as it's almost the same wheel than the tspc

edit : just added support for TS_PC to Oversteer and it shows me a perfect steering axis without any unwanted deadzone so this one must be game related Buttons problem however remains so this one must be driver related, maybe wrong assignation or something like that, have to investigate on this one

Kimplul commented 2 months ago

@BDave95 Certainly sounds like some good process, well done!

just added support for TS_PC to Oversteer and it shows me a perfect steering axis without any unwanted deadzone so this one must be game related

It might also be possible that ETS2 uses joydev, whereas Oversteer uses evdev, but I'm not sure. Both have their own way to set deadzones. There's some previous discussion on it over in #42.

Buttons problem however remains so this one must be driver related, maybe wrong assignation or something like that, have to investigate on this one

Sounds like you might want to capture the device's rdesc and compare it to the one you're currently using, apparently t248_pc_rdesc_fixed. The wheel itself has a copy of the rdesc that gets sent over via USB when the wheel is connected to a PC, but for whatever reason they tend to not be accurate and need to be 'fixed', hence the t248_pc_rdesc_fixed etc. I would recommend doing a USB packet capture, the rdesc is among the first few USB packets sent from the wheel upon connecting. There's a short overview of what this involves over in https://github.com/Kimplul/hid-tmff2/wiki#how-to-capture-what-usb-packets-the-driver-sends-to-the-device

I don't know if the TS-PC supports attachments, but if it does, make sure it's installed properly. Apparently at least the T300 can sort of half-function with a poor connection: #89

BDave95 commented 2 months ago

Deadzone problem solved in all Steam games i've tested by creating a udev rule, thanks for the link, shame on me as it was mentioned on the front page

/etc/udev/rules.d/99-joydev.rules

SUBSYSTEM=="input", ATTRS{idVendor}=="044f", ATTRS{idProduct}=="b689", RUN+="/usr/bin/evdev-joystick --evdev %E{DEVNAME} --axis 0 --deadzone 0"

For the buttons problem can't be an attachment problem as it works perfectly in Windows i tried to start from hid-tmtsxw.c instead of hid-tmt248.c and i gain access to most of my wheel buttons but not all and not with the right mapping so definitely have to do the rdesc thing but this will take more time that i have on evenings coming back from work so this will have to wait for the weekend.

Anyway for now the wheel is already usable in acceptable conditions and this is more than i hoped just a week ago so thank you again for starting this project and of course to all previous contributors to this thread.

Potajito commented 2 months ago

Hello, first of all thank you very much for this project, if we had to wait for Thrustmaster do do anything for us ... well After following all steps in this thread to modify all needed files my TS-PS F458 edition is detected, and FFB seems to work, tested only with ETS2 for now but installing AC now to test with it, and pedals connected to it works also.

So this is a very good start but there's still some issues to fix :

* in ETS2 i have a huge deadzone in the middle of steering axis and can't find any way to remove it

* axis wheel + pedals are working fine (except deadzone in steering) but no buttons detected in ETS2 (that's why i'm installing AC to check if it's wheel or game related)

* the wheel only works in standard mode and i would like to use it in advanced mode like in windows (more buttons to map)

The problem is my programming skills are limited to following tutos, and using existing files as templates to guess changes to do, so i will need help/direction to follow to investigate more.

The only thing i can think of for now is i added a directory for the tspc in /src but i have copied the T248 one as a base, maybe it would have been smarter to start from tsxw as it's almost the same wheel than the tspc

edit : just added support for TS_PC to Oversteer and it shows me a perfect steering axis without any unwanted deadzone so this one must be game related Buttons problem however remains so this one must be driver related, maybe wrong assignation or something like that, have to investigate on this one

Hi! Could you share what you did to get FFB working? Maybe point to a fork of this repo? What I did was change the usb id for the tsxw to 0xb65d , blacklist hid_thrustmaster and manually install dkms module. I get the wheel to show up on gamepad testers, and I also forked Oversteer and added ts_pc support, so the wheel also shows up there, but no FFB so far. I think I'm missing something, I read about hid-tminit but I'm not really sure what to do with that. Cheers! Feels like this is almost there!

BDave95 commented 2 months ago

Hi! Could you share what you did to get FFB working? Maybe point to a fork of this repo? What I did was change the usb id for the tsxw to 0xb65d , blacklist hid_thrustmaster and manually install dkms module. I get the wheel to show up on gamepad testers, and I also forked Oversteer and added ts_pc support, so the wheel also shows up there, but no FFB so far. I think I'm missing something, I read about hid-tminit but I'm not really sure what to do with that. Cheers! Feels like this is almost there!

The correct USB ID for the TS-PC is b689 not b65d so normal to not have FFB If i understood correctly b65d is some sort of generic initialization ID common to all Thrustmaster wheel and the job of hid-tminit is to do the final initialization to get the right ID The modifications i made to hid-tminit are only those indicated in svenliekens post above

Of course i will share my files, the goal is not to keep it for me but contributing to the driver for anyone, i'll see this weekend to make the diffs and publish them

Potajito commented 2 months ago

Thanks! I finally made it work, here is what I did, in case it can help someone else:

BDave95 commented 2 months ago

Good that you made it working too. I investigated more about my buttons mapping problem and in fact it was obvious : this driver initialize the wheel in standard mode not in advanced mode like i use in Windows, checking in Windows the 2 modes have different PID :

I tried to capture packets from connecting the wheel to it's final initialization with Wireshark to figure how to initialize the wheel in advanced mod but to be honest i don't really understand anything in all this Just figured the wheel change it's device address between it's initial start and it's final initialization, following what's published before also figure base + attachment ID are the same than those of Solarisfire, and find correct buttons mapping description but nothing about what to send to the wheel to initialize it in advanced mode, if someone more competent than me can have a look tspc-init.zip

BDave95 commented 2 months ago

Here are my diffs for all files i modified

 --- org/hid-tmff2/Kbuild
+++ hid-tmff2/Kbuild
@@ -1,2 +1,2 @@
 obj-m := hid-tmff-new.o
-hid-tmff-new-y := src/hid-tmff2.o src/tmt300rs/hid-tmt300rs.o src/tmt248/hid-tmt248.o src/tmtx/hid-tmtx.o src/tmtsxw/hid-tmtsxw.o
+hid-tmff-new-y := src/hid-tmff2.o src/tmt300rs/hid-tmt300rs.o src/tmt248/hid-tmt248.o src/tmtx/hid-tmtx.o src/tmtsxw/hid-tmtsxw.o src/tmtspc/hid-tmtspc.o
--- org/hid-tmff2/deps/hid-tminit/hid-tminit.c
+++ hid-tmff2/deps/hid-tminit/hid-tminit.c
@@ -70,11 +70,12 @@
    {0x02, 0x04, 0x0005, "Thrustmaster T300 Ferrari Alcantara Edition"},
    {0x02, 0x06, 0x0005, "Thrustmaster T300RS"},
    {0x02, 0x09, 0x0005, "Thrustmaster T300RS (Open Wheel Attachment)"},
-   {0x03, 0x06, 0x0006, "Thrustmaster T150RS"}
+   {0x03, 0x06, 0x0006, "Thrustmaster T150RS"},
+   {0x06, 0x09, 0x0009, "Thrustmaster TS-PC"},
    //{0x04, 0x07, 0x0001, "Thrustmaster TMX"}
 };

-static const uint8_t tm_wheels_infos_length = 7;
+static const uint8_t tm_wheels_infos_length = 8;

 /*
  * This structs contains (in little endian) the response data
--- org/hid-tmff2/src/hid-tmff2.c
+++ hid-tmff2/src/hid-tmff2.c
@@ -678,6 +678,10 @@
            if ((ret = tsxw_populate_api(tmff2)))
                goto wheel_err;
            break;
+           case TMTS_PC_RACER_ID:
+           if ((ret = tspc_populate_api(tmff2)))
+               goto wheel_err;
+           break;
        default:
            ret = -ENODEV;
            goto wheel_err;
@@ -772,6 +776,8 @@
    {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMT248_PC_ID)},
    /* tx */
    {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TX_ACTIVE)},
+   /* TS-PC RACER */
+   {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TMTS_PC_RACER_ID)},
    /* tsxw */
    {HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, TSXW_ACTIVE)},
--- org/hid-tmff2/src/hid-tmff2.h
+++ hid-tmff2/src/hid-tmff2.h
@@ -103,6 +103,7 @@
 int t248_populate_api(struct tmff2_device_entry *tmff2);
 int tx_populate_api(struct tmff2_device_entry *tmff2);
 int tsxw_populate_api(struct tmff2_device_entry *tmff2);
+int tspc_populate_api(struct tmff2_device_entry *tmff2);

 #define TMT300RS_PS3_NORM_ID   0xb66e
 #define TMT300RS_PS3_ADV_ID    0xb66f
@@ -113,6 +114,8 @@
 #define TX_ACTIVE               0xb669

 #define TSXW_ACTIVE        0xb692
+
+#define TMTS_PC_RACER_ID   0xb689

 /* APIs to different wheel families */
 /* T248 and TX at least uses the T300RS api, not sure if there are other wheels

This one is just a draft and need will need further modifis

--- org/hid-tmff2/src/tmtsxw/hid-tmtsxw.c
+++ hid-tmff2/src/tmtspc/hid-tmtspc.c
@@ -3,8 +3,8 @@
 #include <linux/hid.h>
 #include "../hid-tmff2.h"

-#define TMTSXW_MAX_EFFECTS 16
-#define TMTSXW_BUFFER_LENGTH 63
+#define TMTSPC_MAX_EFFECTS 16
+#define TMTSPC_BUFFER_LENGTH 63

 static const u8 setup_0[64] = { 0x42, 0x01 };
 static const u8 setup_1[64] = { 0x0a, 0x04, 0x90, 0x03 };
@@ -24,7 +24,7 @@
    ARRAY_SIZE(setup_6)
 };

-static const unsigned long tsxw_params =
+static const unsigned long tspc_params =
    PARAM_SPRING_LEVEL
    | PARAM_DAMPER_LEVEL
    | PARAM_FRICTION_LEVEL
@@ -32,7 +32,7 @@
    | PARAM_GAIN
    ;

-static const signed short tsxw_effects[] = {
+static const signed short tspc_effects[] = {
    FF_CONSTANT,
    FF_RAMP,
    FF_SPRING,
@@ -51,7 +51,7 @@
 };

 /* TODO: sort through this stuff */
-static u8 tsxw_pc_rdesc_fixed[] = {
+static u8 tspc_pc_rdesc_fixed[] = {
    0x05, 0x01, /* Usage page (Generic Desktop) */
    0x09, 0x04, /* Usage (Joystick) */
    0xa1, 0x01, /* Collection (Application) */
@@ -116,15 +116,15 @@
    0xc0, /* End collection */
 };

-static int tsxw_interrupts(struct t300rs_device_entry *tsxw)
+static int tspc_interrupts(struct t300rs_device_entry *tspc)
 {
    u8 *send_buf = kmalloc(256, GFP_KERNEL);
-   struct usb_interface *usbif = to_usb_interface(tsxw->hdev->dev.parent);
+   struct usb_interface *usbif = to_usb_interface(tspc->hdev->dev.parent);
    struct usb_host_endpoint *ep;
    int ret, trans, b_ep, i;

    if (!send_buf) {
-       hid_err(tsxw->hdev, "failed allocating send buffer\n");
+       hid_err(tspc->hdev, "failed allocating send buffer\n");
        return -ENOMEM;
    }

@@ -134,14 +134,14 @@
    for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
        memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);

-       ret = usb_interrupt_msg(tsxw->usbdev,
-               usb_sndintpipe(tsxw->usbdev, b_ep),
+       ret = usb_interrupt_msg(tspc->usbdev,
+               usb_sndintpipe(tspc->usbdev, b_ep),
                send_buf, setup_arr_sizes[i],
                &trans,
                USB_CTRL_SET_TIMEOUT);

        if (ret) {
-           hid_err(tsxw->hdev, "setup data couldn't be sent\n");
+           hid_err(tspc->hdev, "setup data couldn't be sent\n");
            goto err;
        }
    }
@@ -151,7 +151,7 @@
    return ret;
 }

-int tsxw_wheel_destroy(void *data)
+int tspc_wheel_destroy(void *data)
 {
    struct t300rs_device_entry *t300rs = data;

@@ -163,144 +163,144 @@
    return 0;
 }

-int tsxw_set_range(void *data, uint16_t value)
-{
-   struct t300rs_device_entry *tsxw = data;
+int tspc_set_range(void *data, uint16_t value)
+{
+   struct t300rs_device_entry *tspc = data;

    if (value < 140) {
-       hid_info(tsxw->hdev, "value %i too small, clamping to 140\n", value);
+       hid_info(tspc->hdev, "value %i too small, clamping to 140\n", value);
        value = 140;
    }

    if (value > 1080) {
-       hid_info(tsxw->hdev, "value %i too large, clamping to 1080\n", value);
+       hid_info(tspc->hdev, "value %i too large, clamping to 1080\n", value);
        value = 1080;
    }

    return t300rs_set_range(data, value);
 }

-static int tsxw_send_open(struct t300rs_device_entry *tsxw)
+static int tspc_send_open(struct t300rs_device_entry *tspc)
 {
    int r1, r2;
-   tsxw->send_buffer[0] = 0x01;
-   tsxw->send_buffer[1] = 0x04;
-   if ((r1 = t300rs_send_int(tsxw)))
+   tspc->send_buffer[0] = 0x01;
+   tspc->send_buffer[1] = 0x04;
+   if ((r1 = t300rs_send_int(tspc)))
        return r1;

-   tsxw->send_buffer[0] = 0x01;
-   tsxw->send_buffer[1] = 0x05;
-   if ((r2 = t300rs_send_int(tsxw)))
+   tspc->send_buffer[0] = 0x01;
+   tspc->send_buffer[1] = 0x05;
+   if ((r2 = t300rs_send_int(tspc)))
        return r2;

    return 0;
 }

-static int tsxw_open(void *data, int open_mode)
-{
-   struct t300rs_device_entry *tsxw = data;
-
-   if (!tsxw)
+static int tspc_open(void *data, int open_mode)
+{
+   struct t300rs_device_entry *tspc = data;
+
+   if (!tspc)
        return -ENODEV;

    if (open_mode)
-       tsxw_send_open(tsxw);
-
-   return tsxw->open(tsxw->input_dev);
-}
-
-static int tsxw_send_close(struct t300rs_device_entry *tsxw)
+       tspc_send_open(tspc);
+
+   return tspc->open(tspc->input_dev);
+}
+
+static int tspc_send_close(struct t300rs_device_entry *tspc)
 {
    int r1, r2;
-   tsxw->send_buffer[0] = 0x01;
-   tsxw->send_buffer[1] = 0x05;
-   if ((r1 = t300rs_send_int(tsxw)))
+   tspc->send_buffer[0] = 0x01;
+   tspc->send_buffer[1] = 0x05;
+   if ((r1 = t300rs_send_int(tspc)))
        return r1;

-   tsxw->send_buffer[0] = 0x01;
-   tsxw->send_buffer[1] = 0x00;
-   if ((r2 = t300rs_send_int(tsxw)))
+   tspc->send_buffer[0] = 0x01;
+   tspc->send_buffer[1] = 0x00;
+   if ((r2 = t300rs_send_int(tspc)))
        return r2;

    return 0;
 }

-static int tsxw_close(void *data, int open_mode)
-{
-   struct t300rs_device_entry *tsxw = data;
-
-   if (!tsxw)
+static int tspc_close(void *data, int open_mode)
+{
+   struct t300rs_device_entry *tspc = data;
+
+   if (!tspc)
        return -ENODEV;

    if (open_mode)
-       tsxw_send_close(tsxw);
-
-   tsxw->close(tsxw->input_dev);
-   return 0;
-}
-
-int tsxw_wheel_init(struct tmff2_device_entry *tmff2, int open_mode)
-{
-   struct t300rs_device_entry *tsxw = kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL);
+       tspc_send_close(tspc);
+
+   tspc->close(tspc->input_dev);
+   return 0;
+}
+
+int tspc_wheel_init(struct tmff2_device_entry *tmff2, int open_mode)
+{
+   struct t300rs_device_entry *tspc = kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL);
    struct list_head *report_list;
    int ret;

-   if (!tsxw) {
+   if (!tspc) {
        ret = -ENOMEM;
-       goto tsxw_err;
-   }
-
-   tsxw->hdev = tmff2->hdev;
-   tsxw->input_dev = tmff2->input_dev;
-   tsxw->usbdev = to_usb_device(tmff2->hdev->dev.parent->parent);
-   tsxw->buffer_length = TMTSXW_BUFFER_LENGTH;
-
-   tsxw->send_buffer = kzalloc(tsxw->buffer_length, GFP_KERNEL);
-   if (!tsxw->send_buffer) {
+       goto tspc_err;
+   }
+
+   tspc->hdev = tmff2->hdev;
+   tspc->input_dev = tmff2->input_dev;
+   tspc->usbdev = to_usb_device(tmff2->hdev->dev.parent->parent);
+   tspc->buffer_length = TMTSPC_BUFFER_LENGTH;
+
+   tspc->send_buffer = kzalloc(tspc->buffer_length, GFP_KERNEL);
+   if (!tspc->send_buffer) {
        ret = -ENOMEM;
        goto send_err;
    }

-   report_list = &tsxw->hdev->report_enum[HID_OUTPUT_REPORT].report_list;
-   tsxw->report = list_entry(report_list->next, struct hid_report, list);
-   tsxw->ff_field = tsxw->report->field[0];
-
-   tsxw->open = tsxw->input_dev->open;
-   tsxw->close = tsxw->input_dev->close;
-
-   if ((ret = tsxw_interrupts(tsxw)))
+   report_list = &tspc->hdev->report_enum[HID_OUTPUT_REPORT].report_list;
+   tspc->report = list_entry(report_list->next, struct hid_report, list);
+   tspc->ff_field = tspc->report->field[0];
+
+   tspc->open = tspc->input_dev->open;
+   tspc->close = tspc->input_dev->close;
+
+   if ((ret = tspc_interrupts(tspc)))
        goto interrupt_err;

    /* everything went OK */
-   tmff2->data = tsxw;
-   tmff2->params = tsxw_params;
-   tmff2->max_effects = TMTSXW_MAX_EFFECTS;
-   memcpy(tmff2->supported_effects, tsxw_effects, sizeof(tsxw_effects));
+   tmff2->data = tspc;
+   tmff2->params = tspc_params;
+   tmff2->max_effects = TMTSPC_MAX_EFFECTS;
+   memcpy(tmff2->supported_effects, tspc_effects, sizeof(tspc_effects));

    if (!open_mode)
-       tsxw_send_open(tsxw);
-
-   hid_info(tsxw->hdev, "force feedback for TS-XW\n");
+       tspc_send_open(tspc);
+
+   hid_info(tspc->hdev, "force feedback for TS-PC\n");
    return 0;

 interrupt_err:
 send_err:
-   kfree(tsxw);
-tsxw_err:
-   hid_err(tmff2->hdev, "failed initializing TS-XW\n");
+   kfree(tspc);
+tspc_err:
+   hid_err(tmff2->hdev, "failed initializing TS-PC\n");
    return ret;
 }

-static __u8 *tsxw_wheel_fixup(struct hid_device *hdev, __u8 *rdesc,
+static __u8 *tspc_wheel_fixup(struct hid_device *hdev, __u8 *rdesc,
        unsigned int *rsize)
 {
-   rdesc = tsxw_pc_rdesc_fixed;
-   *rsize = sizeof(tsxw_pc_rdesc_fixed);
+   rdesc = tspc_pc_rdesc_fixed;
+   *rsize = sizeof(tspc_pc_rdesc_fixed);
    return rdesc;
 }

-int tsxw_populate_api(struct tmff2_device_entry *tmff2)
+int tspc_populate_api(struct tmff2_device_entry *tmff2)
 {
    tmff2->play_effect = t300rs_play_effect;
    tmff2->upload_effect = t300rs_upload_effect;
@@ -309,15 +309,15 @@

    tmff2->set_gain = t300rs_set_gain;
    tmff2->set_autocenter = t300rs_set_autocenter;
-   /* TS-XW has 1080 degree range, just like T300RS 1080 */
-   tmff2->set_range = tsxw_set_range;
-   tmff2->wheel_fixup = tsxw_wheel_fixup;
-
-   tmff2->open = tsxw_open;
-   tmff2->close = tsxw_close;
-
-   tmff2->wheel_init = tsxw_wheel_init;
-   tmff2->wheel_destroy = tsxw_wheel_destroy;
-
-   return 0;
-}
+   /* TS-PC has 900 degree range, like T300RS 1080 */
+   tmff2->set_range = tspc_set_range;
+   tmff2->wheel_fixup = tspc_wheel_fixup;
+
+   tmff2->open = tspc_open;
+   tmff2->close = tspc_close;
+
+   tmff2->wheel_init = tspc_wheel_init;
+   tmff2->wheel_destroy = tspc_wheel_destroy;
+
+   return 0;
+}
Kimplul commented 2 months ago

@n1njak3bab Nothing's been merged into the repository yet, I'm planning on taking a look at this over the weekend. Please do feel free to try and get things running on your end, always good to have more eyes.

WithHammerandI commented 1 week ago

I am so glad to see this wheel being worked on. It's the last thing I have been waiting for in order to make the transition to Linux full time.

Is it working well yet ?

Also fantastic work guys. Reading through the thread makes me realise I really should of taken up the offer to study Computers and do the Systems Analyst Course when I was offered 40 years ago. I decided to go work for my Dad, as a Furniture Polisher. That did not work out so well. Sigh :(

Kimplul commented 1 week ago

Hello again, I must admit I kind of forgot about this for a while, just got a bit buried under other things on my TODO list. I gave the provided patches a quick lookover, seems mostly fine but I did notice that in one comment the wheel's range is indicated to be 900 degrees, but the range() function allowed up to 1080. I switched 1080 to be 900 and pushed the changes to a separate tspc branch.

I also had a look at the provided USB captures, and I spotted packet number 123, seems very similar to packets that are used by the T300RS to switch modes so I added initial mode switching functionality for testing. Don't have a wheel myself so no real idea if this works or not, and I would appreciate it if somebody could check out the branch and let me know. Please be careful, preferably run this driver in a virtual machine or something as a kernel crash could (theoretically) corrupt hard drives etc. I'm not expecting anything to happen, but best to be safe.

Mode switching happens by writing something to the alternate_modes file, you should be able to find it by something like cd /sys ; find . -iname alternate_modes as root. The exact path might vary. Currently there's only switching from normal mode to advanced mode IF it works at all.

EDIT: Just as an example, echo 1 > /sys/WHATEVER/PATH/FIND/RETURNS/alternate_modes should trigger a mode switch.

WithHammerandI commented 1 week ago

Well that was quick. He says replying after 3 mins. lol

Not my field but I am always willing to try, so will make a VM and have a go later.

Fingers crossed. (someone will beat me to it) Ha ha

Thanks very much for all you are doing.

Potajito commented 6 days ago

Hello again, I must admit I kind of forgot about this for a while, just got a bit buried under other things on my TODO list. I gave the provided patches a quick lookover, seems mostly fine but I did notice that in one comment the wheel's range is indicated to be 900 degrees, but the range() function allowed up to 1080. I switched 1080 to be 900 and pushed the changes to a separate tspc branch.

I also had a look at the provided USB captures, and I spotted packet number 123, seems very similar to packets that are used by the T300RS to switch modes so I added initial mode switching functionality for testing. Don't have a wheel myself so no real idea if this works or not, and I would appreciate it if somebody could check out the branch and let me know. Please be careful, preferably run this driver in a virtual machine or something as a kernel crash could (theoretically) corrupt hard drives etc. I'm not expecting anything to happen, but best to be safe.

Mode switching happens by writing something to the alternate_modes file, you should be able to find it by something like cd /sys ; find . -iname alternate_modes as root. The exact path might vary. Currently there's only switching from normal mode to advanced mode IF it works at all.

EDIT: Just as an example, echo 1 > /sys/WHATEVER/PATH/FIND/RETURNS/alternate_modes should trigger a mode switch.

Nice, probably it was me as I misremembered the max angle. About the mode switch, I guess it's the attachment thing that @BDave95 mentioned? I don't remember seeing anything about that in the win driver or in the manual 🤔. Anyway, I'm going to try the new branch and report. Personally I'll just try it as usual, not in an VM, if something breaks, it was time for a reinstall. Btw, the tmdrv part to init the wheel should still be needed, right? I'd love to get rid of it, specially for new users it's a bit of an extra hassle that it's not very user-friendly. Thanks again, on to testing!

Kimplul commented 6 days ago

About the mode switch, I guess it's the attachment thing that @BDave95 mentioned? I don't remember seeing anything about that in the win driver or in the manual 🤔.

Yep, in tspc-init.zip earlier in the thread.

Btw, the tmdrv part to init the wheel should still be needed, right? I'd love to get rid of it, specially for new users it's a bit of an extra hassle that it's not very user-friendly.

The attached patches include code in hid-tminit, which I interpreted to mean that tmdrv shouldn't be needed anymore. But please do correct me if I'm wrong.

BDave95 commented 7 hours ago

Cool to see it's still moving out there, had no time lastly to follow but i'll try to find some to test last advances, especially mode switching. Thanks to everyone involved.

Nice, probably it was me as I misremembered the max angle. About the mode switch, I guess it's the attachment thing that @BDave95 mentioned? I don't remember seeing anything about that in the win driver or in the manual 🤔. Anyway, I'm going to try the new branch and report. Personally I'll just try it as usual, not in an VM, if something breaks, it was time for a reinstall. Btw, the tmdrv part to init the wheel should still be needed, right? I'd love to get rid of it, specially for new users it's a bit of an extra hassle that it's not very user-friendly. Thanks again, on to testing!

For the mode switch if i understood correctly what it written on Thrustmaster's site it's presence depend on wheel installed, On my Pc it shows like this thr-pan

As you can see the option appear on the lower end of the windows. It might no show with "basic" wheels cause it would be useless as they haven't much buttons but with more advanced wheel like my F488 Challenge or the Ferrari F1 Wheel it makes sense to run only in advanced mode to take advantage of all the added buttons and dials.

Speaking of buttons and dials attributions Thrustmaster give the mapping on it's website for most common wheels, if one need to correct mapping/attribution for a particular wheel it might be a useful help https://support.thrustmaster.com/en/product/tspcracer-en/