Skip to content

Commit e31401d

Browse files
committed
Merge candidate/pr175 feedbacks (#9)
1 parent be8c39d commit e31401d

File tree

10 files changed

+451
-538
lines changed

10 files changed

+451
-538
lines changed

Kbuild

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ hid-tmff-new-y := \
77
src/tmtsxw/hid-tmtsxw.o \
88
src/tmt500rs/hid-tmt500rs-usb.o
99

10-
# Pass through the T500RS version define from Makefile (original branch style)
11-
ccflags-y += $(T500RS_VERSION_DEF)
10+
# Pass through the global TMFF2 version define from Makefile
11+
ccflags-y += $(TMFF2_VERSION_DEF)

Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
KDIR ?= /lib/modules/$(shell uname -r)/build
22

3-
# Auto-generated build-time version for T500RS
4-
T500RS_BASE_VERSION ?= 0.1
3+
# Auto-generated global build-time version for TMFF2
4+
TMFF2_BASE_VERSION ?= 0.1
55
GIT_HASH := $(shell git rev-parse --short=7 HEAD 2>/dev/null || echo "local")
66
BUILD_HASH := $(shell date +%s | sha1sum | cut -c1-7)
77

8-
T500RS_VERSION ?= $(T500RS_BASE_VERSION)-$(GIT_HASH)+b$(BUILD_HASH)
9-
export T500RS_VERSION_DEF := -DT500RS_DRIVER_VERSION=\"$(T500RS_VERSION)\"
8+
TMFF2_VERSION ?= $(TMFF2_BASE_VERSION)-$(GIT_HASH)+b$(BUILD_HASH)
9+
export TMFF2_VERSION_DEF := -DTMFF2_DRIVER_VERSION=\"$(TMFF2_VERSION)\"
1010

1111

1212
all: deps/hid-tminit
13-
@echo "T500RS build version: $(T500RS_VERSION)"
14-
@echo " - base: $(T500RS_BASE_VERSION), commit: $(GIT_HASH), build: $(BUILD_HASH)"
13+
@echo "TMFF2 build version: $(TMFF2_VERSION)"
14+
@echo " - base: $(TMFF2_BASE_VERSION), commit: $(GIT_HASH), build: $(BUILD_HASH)"
1515
$(MAKE) -C $(KDIR) M=$(shell pwd) modules
1616

1717
install: deps/hid-tminit

docs/FFBEFFECTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,4 +1025,4 @@ binary hex
10251025
ff00.0021 = 0
10261026
ff00.0021 = 0
10271027
ff00.0021 = 0
1028-
```
1028+
```

docs/FFB_T500RS.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
## T500RS USB FFB Protocol (observed)
2+
3+
This page documents the packet formats and ordering used by the T500RS when driven via the USB interrupt endpoint (0x01 OUT). It mirrors the style of docs/FFBEFFECTS.md for other wheels.
4+
5+
Key rules
6+
- Little‑endian for 16‑bit fields
7+
- DMA‑safe buffer length 32 bytes; typical messages are 2, 4, 9 or 15 bytes
8+
- EffectID semantics (CRITICAL):
9+
- All Report 0x01 main‑effect uploads MUST use EffectID = 0x00 on T500RS
10+
- Report 0x41 START/STOP also uses EffectID = 0x00, except the init‑time STOP for autocenter which targets a fixed ID (15)
11+
- Using per‑effect IDs with 0x01 breaks playback (constant force fails completely)
12+
13+
Report glossary
14+
- 0x01 main upload (15 bytes)
15+
- Layout (unknown bytes kept for completeness):
16+
- b0 id = 0x01
17+
- b1 effect_id = 0x00 (MUST)
18+
- b2 type: 0x00 constant; 0x20..0x24 periodic/ramp
19+
- b3 0x40
20+
- b4 0xff (or duration L for ramp path)
21+
- b5 0xff (or duration H for ramp path)
22+
- b6 0x00
23+
- b7 0xff
24+
- b8 0xff
25+
- b9 0x0e (parameter subtype)
26+
- b10 0x00
27+
- b11 0x1c (envelope subtype)
28+
- b12 0x00
29+
- b13 0x00
30+
- b14 0x00
31+
- 0x02 envelope (9 bytes)
32+
- b0 0x02, b1 0x1c, b2 0x00
33+
- b3..4 attack_length (le16)
34+
- b5 attack_level (0..255)
35+
- b6..7 fade_length (le16)
36+
- b8 fade_level (0..255)
37+
- 0x03 constant level (4 bytes)
38+
- b0 0x03, b1 0x0e, b2 0x00
39+
- b3 level s8 (−127..127)
40+
- 0x04 periodic params (8 bytes)
41+
- b0 0x04, b1 0x0e, b2 0x00
42+
- b3 magnitude u7 (0..127)
43+
- b4 offset = 0, b5 phase = 0
44+
- b6..7 period (le16, ms)
45+
- 0x04 ramp params (9 bytes)
46+
- b0 0x04, b1 0x0e
47+
- b2..3 start (le16), b4..5 cur_val (le16), b6..7 duration (le16), b8 0x00
48+
- 0x05 condition params (11 bytes)
49+
- set 1 (coeff/saturation): b0 0x05, b1 0x0e, b2 0x00, b3 right_strength, b4 left_strength, b9/b10 subtype values vary by type (spring vs damper/friction)
50+
- set 2 (deadband/center): b0 0x05, b1 0x1c, b2 0x00, b3 deadband, b4 center, b9/b10 subtype values
51+
- 0x40 config (4 bytes)
52+
- 0x40 0x04 enable/disable autocenter, 0x40 0x03 set autocenter strength, 0x40 0x11 set range (le16), etc.
53+
- 0x41 start/stop/clear (4 bytes)
54+
- id=0x41, effect_id=0x00 (MUST), command=0x41 START or 0x00 STOP, arg=0x01
55+
- Exception: init‑time STOP for autocenter uses effect_id=15
56+
- 0x42 apply/apply‑like, 0x43 gain
57+
58+
Effect upload and play ordering
59+
- Constant (FF_CONSTANT)
60+
1) 0x02 envelope
61+
2) 0x01 main (type=0x00, effect_id=0x00)
62+
Play: 0x03 level, then 0x41 START (effect_id=0x00)
63+
- Periodic (FF_SINE/FF_SQUARE/FF_TRIANGLE/FF_SAW)
64+
1) 0x02 envelope
65+
2) 0x01 main (type=0x20..0x24, effect_id=0x00)
66+
3) 0x04 periodic params (magnitude/period)
67+
4) 0x01 main (type repeated, effect_id=0x00)
68+
Play: 0x41 START (effect_id=0x00)
69+
- Condition (FF_SPRING/FF_DAMPER/FF_FRICTION/FF_INERTIA)
70+
1) 0x05 coeff/saturation (0x0e)
71+
2) 0x05 deadband/center (0x1c)
72+
3) 0x01 main (type reflects subkind, effect_id=0x00)
73+
Play: 0x41 START (effect_id=0x00)
74+
- Ramp (FF_RAMP)
75+
1) 0x02 envelope
76+
2) 0x04 ramp params (device behaves like hold of start level with duration)
77+
3) 0x01 main (type=0x24, effect_id=0x00)
78+
Play: 0x41 START (effect_id=0x00)
79+
80+
Notes
81+
- All 0x01 uploads must use EffectID=0x00. This was validated on hardware; using per‑effect IDs causes constant force to fail completely and can break other effects.
82+
- 16‑bit values are little‑endian (lo byte first).
83+
- Magnitudes/levels are expected in device ranges (0..127 for periodic magnitude, s8 for constant level). Scaling helpers in code perform conversions from Linux ranges.
84+
- Autocenter is disabled by zeroing spring coefficients via 0x05 messages and/or via 0x40 commands, then explicitly stopping autocenter (ID 15) during init.
85+

src/hid-tmff2.c

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#include <linux/version.h>
66
#include "hid-tmff2.h"
77

8-
/* Share t500rs_log_level across compilation units (level 3 = unknown-only) */
9-
extern int t500rs_log_level;
108

119
/* Known vendor/opcode IDs managed by the driver (TX side) */
1210
static inline int tmff2_is_known_vendor_id(unsigned char id)
@@ -376,15 +374,26 @@ static void tmff2_work_handler(struct work_struct *w)
376374

377375
effect_delay = state->effect.replay.delay;
378376
effect_length = state->effect.replay.length;
377+
/* If playing with a finite length, stop when (delay + length) elapses */
379378
if (test_bit(FF_EFFECT_PLAYING, &state->flags) && effect_length) {
380-
if ((time_now - state->start_time) >=
379+
if ((time_now - state->start_time) >=
381380
(effect_delay + effect_length) * state->count) {
382381
__clear_bit(FF_EFFECT_PLAYING, &state->flags);
383382
__clear_bit(FF_EFFECT_QUEUE_UPDATE, &state->flags);
384-
383+
/* Request a STOP in process context */
384+
__set_bit(FF_EFFECT_QUEUE_STOP, &actions);
385385
state->count = 0;
386386
}
387387
}
388+
/* Delay handling for start: only trigger START after replay.delay */
389+
if (test_bit(FF_EFFECT_QUEUE_START, &state->flags)) {
390+
if ((time_now - state->start_time) >= effect_delay) {
391+
__set_bit(FF_EFFECT_QUEUE_START, &actions);
392+
__clear_bit(FF_EFFECT_QUEUE_START, &state->flags);
393+
/* effect is playing since we're starting it now */
394+
__set_bit(FF_EFFECT_PLAYING, &state->flags);
395+
} /* else: keep START pending until delay elapsed */
396+
}
388397

389398
if (test_bit(FF_EFFECT_QUEUE_UPLOAD, &state->flags)) {
390399
__set_bit(FF_EFFECT_QUEUE_UPLOAD, &actions);
@@ -809,7 +818,6 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id)
809818

810819
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,12,0)
811820
static __u8 *tmff2_report_fixup(struct hid_device *hdev, __u8 *rdesc,
812-
813821
unsigned int *rsize)
814822
#else
815823
static const __u8 *tmff2_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -881,44 +889,20 @@ static const struct hid_device_id tmff2_devices[] = {
881889

882890
{}
883891
};
884-
MODULE_DEVICE_TABLE(hid, tmff2_devices);
885-
static int tmff2_raw_event(struct hid_device *hdev, struct hid_report *report,
886-
__u8 *data, int size)
887-
{
888-
/* At level 3: ignore normal input reports (axes/buttons) and idless reports;
889-
* only dump vendor/feature-like unknowns. */
890-
if (t500rs_log_level >= 3 && report && data && size > 0) {
891-
/* Skip input traffic entirely (these are the steering updates you saw). */
892-
if (report->type == HID_INPUT_REPORT)
893-
return 0;
894-
895-
/* Use the real Report ID, not data[0] (id==0 means no Report ID). */
896-
if (report->id == 0)
897-
return 0;
898-
899-
if (!tmff2_is_known_vendor_id((unsigned char)report->id)) {
900-
char hex[3 * 64 + 4];
901-
int i, off = 0, max = size > 64 ? 64 : size;
902-
for (i = 0; i < max && off + 3 < sizeof(hex); i++)
903-
off += scnprintf(hex + off, sizeof(hex) - off, "%02x ", data[i]);
904-
if (size > max)
905-
scnprintf(hex + off, sizeof(hex) - off, "...");
906-
hid_info(hdev, "HID RX UNKNOWN [type=%d id=0x%02x len=%d]: %s\n",
907-
report->type, report->id, size, hex);
908-
}
909-
}
910-
return 0; /* always pass through */
911-
}
912-
913892

914893
static struct hid_driver tmff2_driver = {
915894
.name = "tmff2",
916895
.id_table = tmff2_devices,
917896
.probe = tmff2_probe,
918897
.remove = tmff2_remove,
919898
.report_fixup = tmff2_report_fixup,
920-
.raw_event = tmff2_raw_event,
921899
};
922900
module_hid_driver(tmff2_driver);
923901

902+
903+
#ifndef TMFF2_DRIVER_VERSION
904+
#define TMFF2_DRIVER_VERSION "dev"
905+
#endif
906+
MODULE_VERSION(TMFF2_DRIVER_VERSION);
907+
924908
MODULE_LICENSE("GPL");

src/hid-tmff2.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ struct tmff2_device_entry {
9898
ssize_t (*alt_mode_show)(void *data, char *buf);
9999
ssize_t (*alt_mode_store)(void *data, const char *buf, size_t count);
100100
int (*set_autocenter)(void *data, uint16_t autocenter);
101-
int (*set_spring_level)(void *data, u8 level);
102-
int (*set_damper_level)(void *data, u8 level);
103-
int (*set_friction_level)(void *data, u8 level);
104101

105102
__u8 *(*wheel_fixup)(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize);
106103

@@ -119,7 +116,6 @@ int tsxw_populate_api(struct tmff2_device_entry *tmff2);
119116
#define TMT300RS_PS3_ADV_ID 0xb66f
120117
#define TMT300RS_PS4_NORM_ID 0xb66d
121118

122-
#define TMT500RS_INIT_ID 0xb65d
123119
#define TMT500RS_PC_ID 0xb65e
124120

125121
#define TMT248_PC_ID 0xb696

0 commit comments

Comments
 (0)