Thursday, April 10, 2008

Writing an XBox360 driver...

A long while ago I bought a XBox360 USB pad (the one with a cable) for use in Linux and for a while that worked good enough, however recently the standard xpad driver has caused plenty of problems for me. Main problem, it crashed and left the USB system in an inconsistent state that could only be fixed via a reboot. It also had issues with always detecting four XBox360 controllers instead of just the one that was actually plugged in. I didn't really bother much to fix it, since each time I plugged the thing in required a reboot and that wasn't fun. My knowledge of kernel internals is also happens to be rather limited, so I didn't even try to fix the xpad driver itself.

Long story short, I started a userspace driver for the XBox360 gamepad (wired USB version). And to my surprise that turned out far easier then expected. No messing around with HID, no magic init strings or whatever, you just read from the USB port with libusb, interpret the 20 bytes the controller sends and you are done. To turn the LED on or off or let it blink just three bytes are needed and that worked easy enough as well.

Now would a kernel driver be better? I am not so sure. For one thing it would of course allow easy plug&play if there would be a kernel driver that worked, but on the other side a userspace driver has the advantage of allowing much more customization. Now I haven't implemented any of that, but in theory it should be rather easy to allow free remapping of buttons and to turn axis into buttons and visa verse, which especially on the XBox360 controller with its analog-triggers should be a useful feature.

Anyway, the XBox360 driver as it is now works, it doesn't do anything special, but it gives you a joystick device as you would expect, thanks to uinput. To use it just compile it via 'scons' and then start the xbox360 binary. Make sure you unload the regular xpad driver before this. Once the binary is started a /dev/input/js0 will be created and the thing is ready to use.

You can obtain the driver from:

No comments: