Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force feedback doesn't work in linux #30

Open
sgtnoodle opened this issue Jun 29, 2021 · 4 comments
Open

Force feedback doesn't work in linux #30

sgtnoodle opened this issue Jun 29, 2021 · 4 comments

Comments

@sgtnoodle
Copy link

I'm not particularly familiar with USB HID descriptors, but it appears that the usbhid driver, hid-pidff.c, is looking for 0xa7 and not finding it.

[1172477.418129] hid-generic 0003:2341:8036.001A: starting pid init
[1172477.418132] hid-generic 0003:2341:8036.001A: found usage 0x21 from field->logical
[1172477.418134] hid-generic 0003:2341:8036.001A: found usage 0x5a from field->logical
[1172477.418135] hid-generic 0003:2341:8036.001A: found usage 0x5f from field->logical
[1172477.418137] hid-generic 0003:2341:8036.001A: found usage 0x6e from field->logical
[1172477.418138] hid-generic 0003:2341:8036.001A: found usage 0x73 from field->logical
[1172477.418139] hid-generic 0003:2341:8036.001A: found usage 0x74 from field->logical
[1172477.418140] hid-generic 0003:2341:8036.001A: found usage 0x77 from field->logical
[1172477.418142] hid-generic 0003:2341:8036.001A: found usage 0x90 from field->logical
[1172477.418143] hid-generic 0003:2341:8036.001A: found usage 0x96 from field->logical
[1172477.418144] hid-generic 0003:2341:8036.001A: found usage 0x7d from field->logical
[1172477.418145] hid-generic 0003:2341:8036.001A: found usage 0xab from collection array
[1172477.418147] hid-generic 0003:2341:8036.001A: found usage 0x89 from field->logical
[1172477.418148] hid-generic 0003:2341:8036.001A: found usage 0x7f from field->logical
[1172477.418149] usbhid: found 0 at 0->0
[1172477.418151] usbhid: maxusage and report_count do not match, skipping
[1172477.418152] usbhid: found 1 at 2->0
[1172477.418153] usbhid: maxusage and report_count do not match, skipping
[1172477.418154] usbhid: found 2 at 3->0
[1172477.418155] usbhid: maxusage and report_count do not match, skipping
[1172477.418156] usbhid: found 3 at 4->0
[1172477.418157] usbhid: maxusage and report_count do not match, skipping
[1172477.418158] usbhid: found 4 at 2->1
[1172477.418158] usbhid: maxusage and report_count do not match, skipping
[1172477.418159] usbhid: found 5 at 6->0
[1172477.418160] usbhid: maxusage and report_count do not match, skipping
[1172477.418161] usbhid: failed to locate 6
[1172477.418163] hid-generic 0003:2341:8036.001A: unknown set_effect report layout
[1172477.418165] hid-generic 0003:2341:8036.001A: input,hidraw8: USB HID v1.11 Multi-Axis Controller [Arduino LLC Arduino Leonardo] on usb-0000:02:00.0-3/input2

This is apparently a "start delay" parameter. Looking in PIDReportType.h, I can see that it's commented out in the corresponding struct:

typedef struct //FFB: Set Effect Output Report
{
	uint8_t	reportId;	// =1
	uint8_t	effectBlockIndex;	// 1..40
	uint8_t	effectType;	// 1..12 (effect usages: 26,27,30,31,32,33,34,40,41,42,43,28)
	uint16_t duration; // 0..32767 ms
	uint16_t triggerRepeatInterval; // 0..32767 ms
	uint16_t samplePeriod;	// 0..32767 ms
	uint8_t	gain;	// 0..255	 (physical 0..10000)
	uint8_t	triggerButton;	// button ID (0..8)
	uint8_t	enableAxis; // bits: 0=X, 1=Y, 2=DirectionEnable
	uint8_t	directionX;	// angle (0=0 .. 255=360deg)
	uint8_t	directionY;	// angle (0=0 .. 255=360deg)
	//	uint16_t	startDelay;	// 0..32767 ms
} USB_FFBReport_SetEffect_Output_Data_t;

This thread seems to talk about the same issue on a Granite Devices SimuCUBE. https://www.spinics.net/lists/linux-usb/msg190787.html

It seems like this is part of the HID PID spec, but maybe the windows driver is buggy and doesn't implement it, and so it's been omitted from the descriptor to make the device work in windows?

It's kind of a bummer that it doesn't work in linux, because it's much easier to develop my firmware from there. I'll try to work around it and report back, but maybe someone else has a better idea.

@sgtnoodle
Copy link
Author

For what it's worth, I added this to the descriptor:

#define ENABLE_START_DELAY 1

and

	  0x95, 0x02,           //          Report Count (2)
	  0x91, 0x02,           //          Output (Data,Var,Abs)
	  0x55, 0x00,           //          Unit Exponent (0)
	  0x66, 0x00, 0x00,     //          Unit (0)
	0xC0,                 //        End Collection Datalink (Logical)

#if ENABLE_START_DELAY
	0x05,0x0F, // USAGE_PAGE (Physical Interface)
	0x09,0xA7, // USAGE (Start Delay)
	0x66,0x03,0x10, // UNIT (Eng Lin:Time)
	0x55,0xFD, // UNIT_EXPONENT (-3)
	0x15,0x00, // LOGICAL_MINIMUM (00)
	0x26,0xFF,0x7F, // LOGICAL_MAXIMUM (7F FF)
	0x35,0x00, // PHYSICAL_MINIMUM (00)
	0x46,0xFF,0x7F, // PHYSICAL_MAXIMUM (7F FF)
	0x75,0x10, // REPORT_SIZE (10)
	0x95,0x01, // REPORT_COUNT (01)
	0x91,0x02, // OUTPUT (Data,Var,Abs)
	0x66,0x00,0x00, // UNIT (None)
	0x55,0x00, // UNIT_EXPONENT (00)
#endif

	0x05, 0x0F,           //    Usage Page (Physical Interface)
	0x09, 0x58,           //      Usage (Type Specific Block Offset)
	0xA1, 0x02,           //        Collection (Logical)
	  0x0B, 0x01, 0, 0x0A, 0,  //          Usage (Ordinals: Instance 1)

and I uncommented startDelay from the struct, and force feedback now seems to "work" in linux, in that the driver is at least happy and fftest can twiddle it. Of course, my version of fftest drives a 100Hz sine wave when it intends to drive a 10Hz sine wave, and so the resulting force output on the arduino simply toggles between -255 and 255 cycle-to-cycle... :-P

I haven't tried it in windows yet, but I am just getting started on developing the firmware for my steering wheel project.

@YukMingLaw
Copy link
Owner

I'll test it on Linux. But I lack of the ffb test application on linux platform, can you provide?

@sgtnoodle
Copy link
Author

There's fftest available in most distributions. It's pretty crappy, though.

I think just looking at the dmesg output will get you pretty far, though. If it gets past unknown set_effect report layout then it's probably good.

I have my fix here, which seems to work well:
sgtnoodle@61ac57e

I haven't tried it in windows, so I'd be curious to know if its driver implementation chokes on the startDelay field or not.

I also have this commit which adds in default auto-centering. I "reverse engineered" it from what the linux driver was expecting, so I don't know how well it would work with the windows driver:
sgtnoodle@7a7df99

@HiranChaudhuri
Copy link

fftest is mentioned at https://docs.kernel.org/input/ff.html
Unfortunately it is not clear to me which of the /dev/input/eventXX files to pick - but this may be related to my hardware, which is not Arduino-based at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants