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