stick icon indicating copy to clipboard operation
stick copied to clipboard

Sometimes ioctal 0x_8018_4540 returns -1

Open JoNil opened this issue 3 years ago • 11 comments

Hi!

I have an embedded linux system that I'm trying to get some joysticks and steering wheels to work on. For some reason the ioctal EVIOCGABS(0x_8018_4540) returns -1. Maybe there is some kernal module or settings that i'm missing for this ioctal to work.

I could get values from the device with jstest and with this change it works with stick!

I don't know if i16::MIN to i16::MAX is a sane default range but for two thrustmaster devices it seems to be correct.

Cheers!

Jonathan

JoNil avatar Oct 22 '21 11:10 JoNil

@JoNil Thank you for your interest, finding this issue and opening this PR!

This seems like a good issue to try to solve. I just tested 3 of my joysticks and we have the following

  • 0 to 255 PS3 SixAxis
  • -128 to 128 Thrustmaster (Low-end flight stick)
  • -32768 to 32767 Xbox
  • (I also know that joysticks that range from i32::MIN to i32::MAX exist)

I'm not against the i16::MIN to i16::MAX default - but I would like to know why that syscall fails, and if possible fallback to some other method of getting the joystick range (because they vary so wildly). If this turns out to be sadly impossible, I think your PR looks good to merge as is. Otherwise, it could be a secondary fallback if there is another way.

Can you provide any more information about your setup? Are you running Alpine Linux, Raspbian or some other embedded Linux distribution? Which micro-controller are you using?

Thanks again!

AldaronLau avatar Oct 23 '21 03:10 AldaronLau

@JoNil I actually think I know why this is happening after some research.

See this C example of how to use the ioctl - compare with Stick:

https://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/064/6429/6429l17.html

Essentially, stick is only checking for the range of axis 0, and I'm assuming your controller doesn't use axis 0, and starts at a higher number. In order to fix it the "right way", stick needs to run the ioctl for each axis and store each for later reference.

AldaronLau avatar Oct 23 '21 04:10 AldaronLau

@JoNil Let me know if you want to look into it, otherwise I can look into building the fix and ask you to verify if it actually fixes your problem.

AldaronLau avatar Oct 23 '21 04:10 AldaronLau

@AldaronLau

Can you provide any more information about your setup? Are you running Alpine Linux, Raspbian or some other embedded Linux distribution? Which micro-controller are you using?

I'm running a minimal buildroot on a pocket beagle. I based my kernel config on the pocket beagle debian iso. Kernel version is 5.10.65. I had to manually insmod evdev and joydev to get the /dev/input folder with event devices.

Essentially, stick is only checking for the range of axis 0, and I'm assuming your controller doesn't use axis 0, and starts at a higher number. In order to fix it the "right way", stick needs to run the ioctl for each axis and store each for later reference._

This sound like a good theory i will try to port the c snippet and report back the results i get for my device!

JoNil avatar Oct 25 '21 09:10 JoNil

I tried to port the c code to rust. Here is the attempt: https://github.com/voysys/stick/commit/dc2d7528c05109ebbda56fa81fc5d9ee3f718aac

With that test code i got the following output on my device:

[35, 0, 3, 0, 0, 0, 0, 0] 0 AbsInfo { value: 128, minimum: 0, maximum: 255, fuzz: 0, flat: 15, resolution: 0 } 1 AbsInfo { value: 255, minimum: 0, maximum: 255, fuzz: 0, flat: 15, resolution: 0 } 5 AbsInfo { value: 255, minimum: 0, maximum: 255, fuzz: 0, flat: 15, resolution: 0 } 16 AbsInfo { value: 0, minimum: -1, maximum: 1, fuzz: 0, flat: 0, resolution: 0 } 17 AbsInfo { value: 0, minimum: -1, maximum: 1, fuzz: 0, flat: 0, resolution: 0 } Connected p1, id: 03004F0455B60001, name: Thrustmaster FGT Rumble 3-in-1 [0, 0, 0, 0, 0, 0, 0, 0] Connected p2, id: 1800000000000000, name: tps65217_pwr_but

So on one Thrustmaster FGT Rumble 3-in-1 none of the min and max values match what i expected.

And also it's very interesting to me that the power button shows up as a joystick with 0 axis and one button 😅😂 Kind of convenient for me though if i want to use it 😄

Wait that's it that device doesn't have any axis at all!

So i think that my default values were not uses at all i got fooled by the device with no axis.

Do you still want to adapt this code to get axis ranges per axis?

JoNil avatar Oct 25 '21 12:10 JoNil

Ooo i just had one more idea!

In most other joystick libraries i have encountered they don't give an event with the initial value so that the application don't know the state of the axis until one moves. At least on linux we can get the inital value from the value field in the AbsInfo struct and emit that as an initial event 😊

JoNil avatar Oct 25 '21 12:10 JoNil

@JoNil Nice!

on linux we can get the inital value from the value field in the AbsInfo struct and emit that as an initial event

Good idea! I can see where this might be useful.

Do you still want to adapt this code to get axis ranges per axis?

Sounds good to me. Do you want to open a PR for those changes?

AldaronLau avatar Oct 25 '21 12:10 AldaronLau

As far as i understand to scale the input differently per axis i would need to add an axis parameter to the axis function in the Controller trait. This seems like it would have major implications for the design of the library.

If you come up with how you would like to structure this then i could fill in the Linux implementation 😊

An alternative would be to check if there is any axis and if there is then query the range as before. I think that would work in most cases.

JoNil avatar Oct 25 '21 14:10 JoNil

@JoNil I needed to look at the code again, yeah you're right. I think this will change at least some of the library structure. I'll have to think about how to change the design. I think it's best to remove pressure and axis from the trait, and do the conversion internally in the Linux module since it won't need to rely on mapping data anymore.

I'll message you again in this thread when I've come up with the design changes and I think it's ready for testing.

Thanks!

AldaronLau avatar Oct 26 '21 00:10 AldaronLau

@AldaronLau That sounds awesome!

JoNil avatar Oct 26 '21 12:10 JoNil

Happens also for my Saitek Cyborg Evo and Logitech F310 (I'm on Fedora 37 6.5.5-100.fc37.x86_64). Strangely enough, last week it worked fine (I haven't updated the kernel in the meantime). For the time being, I'll be using this branch.

UPDATE: sorry for the confusion, the error is actually triggered by my RTL-SDR dongle ("Realtek RTL2832U Reference Design"), which also gets picked up by stick.

GreatAttractor avatar Nov 12 '23 10:11 GreatAttractor