1*4882a593Smuzhiyun======================== 2*4882a593SmuzhiyunForce feedback for Linux 3*4882a593Smuzhiyun======================== 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun:Author: Johann Deneux <johann.deneux@gmail.com> on 2001/04/22. 6*4882a593Smuzhiyun:Updated: Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09. 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunYou may redistribute this file. Please remember to include shape.svg and 9*4882a593Smuzhiyuninteractive.svg as well. 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunIntroduction 12*4882a593Smuzhiyun~~~~~~~~~~~~ 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunThis document describes how to use force feedback devices under Linux. The 15*4882a593Smuzhiyungoal is not to support these devices as if they were simple input-only devices 16*4882a593Smuzhiyun(as it is already the case), but to really enable the rendering of force 17*4882a593Smuzhiyuneffects. 18*4882a593SmuzhiyunThis document only describes the force feedback part of the Linux input 19*4882a593Smuzhiyuninterface. Please read joystick.txt and input.txt before reading further this 20*4882a593Smuzhiyundocument. 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunInstructions to the user 23*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~ 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunTo enable force feedback, you have to: 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun1. have your kernel configured with evdev and a driver that supports your 28*4882a593Smuzhiyun device. 29*4882a593Smuzhiyun2. make sure evdev module is loaded and /dev/input/event* device files are 30*4882a593Smuzhiyun created. 31*4882a593Smuzhiyun 32*4882a593SmuzhiyunBefore you start, let me WARN you that some devices shake violently during the 33*4882a593Smuzhiyuninitialisation phase. This happens for example with my "AVB Top Shot Pegasus". 34*4882a593SmuzhiyunTo stop this annoying behaviour, move your joystick to its limits. Anyway, you 35*4882a593Smuzhiyunshould keep a hand on your device, in order to avoid it to break down if 36*4882a593Smuzhiyunsomething goes wrong. 37*4882a593Smuzhiyun 38*4882a593SmuzhiyunIf you have a serial iforce device, you need to start inputattach. See 39*4882a593Smuzhiyunjoystick.txt for details. 40*4882a593Smuzhiyun 41*4882a593SmuzhiyunDoes it work ? 42*4882a593Smuzhiyun-------------- 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunThere is an utility called fftest that will allow you to test the driver:: 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun % fftest /dev/input/eventXX 47*4882a593Smuzhiyun 48*4882a593SmuzhiyunInstructions to the developer 49*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 50*4882a593Smuzhiyun 51*4882a593SmuzhiyunAll interactions are done using the event API. That is, you can use ioctl() 52*4882a593Smuzhiyunand write() on /dev/input/eventXX. 53*4882a593SmuzhiyunThis information is subject to change. 54*4882a593Smuzhiyun 55*4882a593SmuzhiyunQuerying device capabilities 56*4882a593Smuzhiyun---------------------------- 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun:: 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun #include <linux/input.h> 61*4882a593Smuzhiyun #include <sys/ioctl.h> 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun #define BITS_TO_LONGS(x) \ 64*4882a593Smuzhiyun (((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long))) 65*4882a593Smuzhiyun unsigned long features[BITS_TO_LONGS(FF_CNT)]; 66*4882a593Smuzhiyun int ioctl(int file_descriptor, int request, unsigned long *features); 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun"request" must be EVIOCGBIT(EV_FF, size of features array in bytes ) 69*4882a593Smuzhiyun 70*4882a593SmuzhiyunReturns the features supported by the device. features is a bitfield with the 71*4882a593Smuzhiyunfollowing bits: 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun- FF_CONSTANT can render constant force effects 74*4882a593Smuzhiyun- FF_PERIODIC can render periodic effects with the following waveforms: 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun - FF_SQUARE square waveform 77*4882a593Smuzhiyun - FF_TRIANGLE triangle waveform 78*4882a593Smuzhiyun - FF_SINE sine waveform 79*4882a593Smuzhiyun - FF_SAW_UP sawtooth up waveform 80*4882a593Smuzhiyun - FF_SAW_DOWN sawtooth down waveform 81*4882a593Smuzhiyun - FF_CUSTOM custom waveform 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun- FF_RAMP can render ramp effects 84*4882a593Smuzhiyun- FF_SPRING can simulate the presence of a spring 85*4882a593Smuzhiyun- FF_FRICTION can simulate friction 86*4882a593Smuzhiyun- FF_DAMPER can simulate damper effects 87*4882a593Smuzhiyun- FF_RUMBLE rumble effects 88*4882a593Smuzhiyun- FF_INERTIA can simulate inertia 89*4882a593Smuzhiyun- FF_GAIN gain is adjustable 90*4882a593Smuzhiyun- FF_AUTOCENTER autocenter is adjustable 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun.. note:: 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun - In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All 95*4882a593Smuzhiyun devices that support FF_RUMBLE support FF_PERIODIC (square, triangle, 96*4882a593Smuzhiyun sine) and the other way around. 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun - The exact syntax FF_CUSTOM is undefined for the time being as no driver 99*4882a593Smuzhiyun supports it yet. 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun:: 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun int ioctl(int fd, EVIOCGEFFECTS, int *n); 104*4882a593Smuzhiyun 105*4882a593SmuzhiyunReturns the number of effects the device can keep in its memory. 106*4882a593Smuzhiyun 107*4882a593SmuzhiyunUploading effects to the device 108*4882a593Smuzhiyun------------------------------- 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun:: 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun #include <linux/input.h> 113*4882a593Smuzhiyun #include <sys/ioctl.h> 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun int ioctl(int file_descriptor, int request, struct ff_effect *effect); 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun"request" must be EVIOCSFF. 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun"effect" points to a structure describing the effect to upload. The effect is 120*4882a593Smuzhiyunuploaded, but not played. 121*4882a593SmuzhiyunThe content of effect may be modified. In particular, its field "id" is set 122*4882a593Smuzhiyunto the unique id assigned by the driver. This data is required for performing 123*4882a593Smuzhiyunsome operations (removing an effect, controlling the playback). 124*4882a593SmuzhiyunThe "id" field must be set to -1 by the user in order to tell the driver to 125*4882a593Smuzhiyunallocate a new effect. 126*4882a593Smuzhiyun 127*4882a593SmuzhiyunEffects are file descriptor specific. 128*4882a593Smuzhiyun 129*4882a593SmuzhiyunSee <uapi/linux/input.h> for a description of the ff_effect struct. You 130*4882a593Smuzhiyunshould also find help in a few sketches, contained in files shape.svg 131*4882a593Smuzhiyunand interactive.svg: 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun.. kernel-figure:: shape.svg 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun Shape 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun.. kernel-figure:: interactive.svg 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun Interactive 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun 142*4882a593SmuzhiyunRemoving an effect from the device 143*4882a593Smuzhiyun---------------------------------- 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun:: 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun int ioctl(int fd, EVIOCRMFF, effect.id); 148*4882a593Smuzhiyun 149*4882a593SmuzhiyunThis makes room for new effects in the device's memory. Note that this also 150*4882a593Smuzhiyunstops the effect if it was playing. 151*4882a593Smuzhiyun 152*4882a593SmuzhiyunControlling the playback of effects 153*4882a593Smuzhiyun----------------------------------- 154*4882a593Smuzhiyun 155*4882a593SmuzhiyunControl of playing is done with write(). Below is an example: 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun:: 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun #include <linux/input.h> 160*4882a593Smuzhiyun #include <unistd.h> 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun struct input_event play; 163*4882a593Smuzhiyun struct input_event stop; 164*4882a593Smuzhiyun struct ff_effect effect; 165*4882a593Smuzhiyun int fd; 166*4882a593Smuzhiyun ... 167*4882a593Smuzhiyun fd = open("/dev/input/eventXX", O_RDWR); 168*4882a593Smuzhiyun ... 169*4882a593Smuzhiyun /* Play three times */ 170*4882a593Smuzhiyun play.type = EV_FF; 171*4882a593Smuzhiyun play.code = effect.id; 172*4882a593Smuzhiyun play.value = 3; 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun write(fd, (const void*) &play, sizeof(play)); 175*4882a593Smuzhiyun ... 176*4882a593Smuzhiyun /* Stop an effect */ 177*4882a593Smuzhiyun stop.type = EV_FF; 178*4882a593Smuzhiyun stop.code = effect.id; 179*4882a593Smuzhiyun stop.value = 0; 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun write(fd, (const void*) &stop, sizeof(stop)); 182*4882a593Smuzhiyun 183*4882a593SmuzhiyunSetting the gain 184*4882a593Smuzhiyun---------------- 185*4882a593Smuzhiyun 186*4882a593SmuzhiyunNot all devices have the same strength. Therefore, users should set a gain 187*4882a593Smuzhiyunfactor depending on how strong they want effects to be. This setting is 188*4882a593Smuzhiyunpersistent across access to the driver. 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun:: 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /* Set the gain of the device 193*4882a593Smuzhiyun int gain; /* between 0 and 100 */ 194*4882a593Smuzhiyun struct input_event ie; /* structure used to communicate with the driver */ 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun ie.type = EV_FF; 197*4882a593Smuzhiyun ie.code = FF_GAIN; 198*4882a593Smuzhiyun ie.value = 0xFFFFUL * gain / 100; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun if (write(fd, &ie, sizeof(ie)) == -1) 201*4882a593Smuzhiyun perror("set gain"); 202*4882a593Smuzhiyun 203*4882a593SmuzhiyunEnabling/Disabling autocenter 204*4882a593Smuzhiyun----------------------------- 205*4882a593Smuzhiyun 206*4882a593SmuzhiyunThe autocenter feature quite disturbs the rendering of effects in my opinion, 207*4882a593Smuzhiyunand I think it should be an effect, which computation depends on the game 208*4882a593Smuzhiyuntype. But you can enable it if you want. 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun:: 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun int autocenter; /* between 0 and 100 */ 213*4882a593Smuzhiyun struct input_event ie; 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun ie.type = EV_FF; 216*4882a593Smuzhiyun ie.code = FF_AUTOCENTER; 217*4882a593Smuzhiyun ie.value = 0xFFFFUL * autocenter / 100; 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun if (write(fd, &ie, sizeof(ie)) == -1) 220*4882a593Smuzhiyun perror("set auto-center"); 221*4882a593Smuzhiyun 222*4882a593SmuzhiyunA value of 0 means "no auto-center". 223*4882a593Smuzhiyun 224*4882a593SmuzhiyunDynamic update of an effect 225*4882a593Smuzhiyun--------------------------- 226*4882a593Smuzhiyun 227*4882a593SmuzhiyunProceed as if you wanted to upload a new effect, except that instead of 228*4882a593Smuzhiyunsetting the id field to -1, you set it to the wanted effect id. 229*4882a593SmuzhiyunNormally, the effect is not stopped and restarted. However, depending on the 230*4882a593Smuzhiyuntype of device, not all parameters can be dynamically updated. For example, 231*4882a593Smuzhiyunthe direction of an effect cannot be updated with iforce devices. In this 232*4882a593Smuzhiyuncase, the driver stops the effect, up-load it, and restart it. 233*4882a593Smuzhiyun 234*4882a593SmuzhiyunTherefore it is recommended to dynamically change direction while the effect 235*4882a593Smuzhiyunis playing only when it is ok to restart the effect with a replay count of 1. 236*4882a593Smuzhiyun 237*4882a593SmuzhiyunInformation about the status of effects 238*4882a593Smuzhiyun--------------------------------------- 239*4882a593Smuzhiyun 240*4882a593SmuzhiyunEvery time the status of an effect is changed, an event is sent. The values 241*4882a593Smuzhiyunand meanings of the fields of the event are as follows:: 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun struct input_event { 244*4882a593Smuzhiyun /* When the status of the effect changed */ 245*4882a593Smuzhiyun struct timeval time; 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun /* Set to EV_FF_STATUS */ 248*4882a593Smuzhiyun unsigned short type; 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun /* Contains the id of the effect */ 251*4882a593Smuzhiyun unsigned short code; 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun /* Indicates the status */ 254*4882a593Smuzhiyun unsigned int value; 255*4882a593Smuzhiyun }; 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun FF_STATUS_STOPPED The effect stopped playing 258*4882a593Smuzhiyun FF_STATUS_PLAYING The effect started to play 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun.. note:: 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun - Status feedback is only supported by iforce driver. If you have 263*4882a593Smuzhiyun a really good reason to use this, please contact 264*4882a593Smuzhiyun linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com 265*4882a593Smuzhiyun so that support for it can be added to the rest of the drivers. 266