Commit | Line | Data |
---|---|---|
3057d509 MCC |
1 | ======================== |
2 | Force feedback for Linux | |
3 | ======================== | |
4 | ||
5 | :Author: Johann Deneux <johann.deneux@gmail.com> on 2001/04/22. | |
6 | :Updated: Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09. | |
7 | ||
deeb1e90 MCC |
8 | You may redistribute this file. Please remember to include shape.svg and |
9 | interactive.svg as well. | |
1da177e4 | 10 | |
3057d509 MCC |
11 | Introduction |
12 | ~~~~~~~~~~~~ | |
13 | ||
1da177e4 LT |
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. | |
8b8277a1 AH |
18 | This document only describes the force feedback part of the Linux input |
19 | interface. Please read joystick.txt and input.txt before reading further this | |
20 | document. | |
1da177e4 | 21 | |
3057d509 MCC |
22 | Instructions to the user |
23 | ~~~~~~~~~~~~~~~~~~~~~~~~ | |
24 | ||
8b8277a1 AH |
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. | |
1da177e4 LT |
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". | |
a3f061bc | 34 | To stop this annoying behaviour, move your joystick to its limits. Anyway, you |
8b8277a1 | 35 | should keep a hand on your device, in order to avoid it to break down if |
1da177e4 LT |
36 | something goes wrong. |
37 | ||
8b8277a1 AH |
38 | If you have a serial iforce device, you need to start inputattach. See |
39 | joystick.txt for details. | |
1da177e4 | 40 | |
3057d509 MCC |
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 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
1da177e4 | 50 | |
8b8277a1 | 51 | All interactions are done using the event API. That is, you can use ioctl() |
1da177e4 | 52 | and write() on /dev/input/eventXX. |
8b8277a1 | 53 | This information is subject to change. |
1da177e4 | 54 | |
3057d509 MCC |
55 | Querying device capabilities |
56 | ---------------------------- | |
1da177e4 | 57 | |
3057d509 | 58 | :: |
1da177e4 | 59 | |
3057d509 MCC |
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); | |
1da177e4 LT |
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: | |
3057d509 | 72 | |
1da177e4 | 73 | - FF_CONSTANT can render constant force effects |
8b8277a1 | 74 | - FF_PERIODIC can render periodic effects with the following waveforms: |
3057d509 | 75 | |
8b8277a1 AH |
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 | |
3057d509 | 82 | |
1da177e4 LT |
83 | - FF_RAMP can render ramp effects |
84 | - FF_SPRING can simulate the presence of a spring | |
8b8277a1 | 85 | - FF_FRICTION can simulate friction |
1da177e4 | 86 | - FF_DAMPER can simulate damper effects |
8b8277a1 | 87 | - FF_RUMBLE rumble effects |
1da177e4 | 88 | - FF_INERTIA can simulate inertia |
8b8277a1 AH |
89 | - FF_GAIN gain is adjustable |
90 | - FF_AUTOCENTER autocenter is adjustable | |
91 | ||
3057d509 MCC |
92 | .. note:: |
93 | ||
94 | - In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All | |
8b8277a1 AH |
95 | devices that support FF_RUMBLE support FF_PERIODIC (square, triangle, |
96 | sine) and the other way around. | |
97 | ||
3057d509 | 98 | - The exact syntax FF_CUSTOM is undefined for the time being as no driver |
8b8277a1 | 99 | supports it yet. |
1da177e4 | 100 | |
3057d509 | 101 | :: |
1da177e4 | 102 | |
3057d509 | 103 | int ioctl(int fd, EVIOCGEFFECTS, int *n); |
1da177e4 LT |
104 | |
105 | Returns the number of effects the device can keep in its memory. | |
106 | ||
3057d509 MCC |
107 | Uploading effects to the device |
108 | ------------------------------- | |
109 | ||
110 | :: | |
8b8277a1 | 111 | |
3057d509 MCC |
112 | #include <linux/input.h> |
113 | #include <sys/ioctl.h> | |
114 | ||
115 | int ioctl(int file_descriptor, int request, struct ff_effect *effect); | |
1da177e4 LT |
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). | |
a3f061bc | 124 | The "id" field must be set to -1 by the user in order to tell the driver to |
1da177e4 | 125 | allocate a new effect. |
8b8277a1 AH |
126 | |
127 | Effects are file descriptor specific. | |
128 | ||
16a12fa9 LT |
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: | |
deeb1e90 | 132 | |
aeb899af | 133 | .. kernel-figure:: shape.svg |
1da177e4 | 134 | |
deeb1e90 MCC |
135 | Shape |
136 | ||
aeb899af | 137 | .. kernel-figure:: interactive.svg |
deeb1e90 MCC |
138 | |
139 | Interactive | |
1da177e4 | 140 | |
3057d509 MCC |
141 | |
142 | Removing an effect from the device | |
143 | ---------------------------------- | |
144 | ||
145 | :: | |
146 | ||
147 | int ioctl(int fd, EVIOCRMFF, effect.id); | |
1da177e4 | 148 | |
8b8277a1 AH |
149 | This makes room for new effects in the device's memory. Note that this also |
150 | stops the effect if it was playing. | |
1da177e4 | 151 | |
3057d509 MCC |
152 | Controlling the playback of effects |
153 | ----------------------------------- | |
154 | ||
1da177e4 LT |
155 | Control of playing is done with write(). Below is an example: |
156 | ||
3057d509 MCC |
157 | :: |
158 | ||
159 | #include <linux/input.h> | |
160 | #include <unistd.h> | |
1da177e4 LT |
161 | |
162 | struct input_event play; | |
163 | struct input_event stop; | |
164 | struct ff_effect effect; | |
165 | int fd; | |
3057d509 | 166 | ... |
1da177e4 | 167 | fd = open("/dev/input/eventXX", O_RDWR); |
3057d509 | 168 | ... |
1da177e4 LT |
169 | /* Play three times */ |
170 | play.type = EV_FF; | |
171 | play.code = effect.id; | |
172 | play.value = 3; | |
8b8277a1 | 173 | |
1da177e4 | 174 | write(fd, (const void*) &play, sizeof(play)); |
3057d509 | 175 | ... |
1da177e4 LT |
176 | /* Stop an effect */ |
177 | stop.type = EV_FF; | |
178 | stop.code = effect.id; | |
179 | stop.value = 0; | |
8b8277a1 | 180 | |
a3f061bc | 181 | write(fd, (const void*) &stop, sizeof(stop)); |
1da177e4 | 182 | |
3057d509 MCC |
183 | Setting the gain |
184 | ---------------- | |
185 | ||
1da177e4 LT |
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 | |
8b8277a1 | 188 | persistent across access to the driver. |
1da177e4 | 189 | |
3057d509 | 190 | :: |
1da177e4 | 191 | |
3057d509 MCC |
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 */ | |
1da177e4 | 195 | |
3057d509 MCC |
196 | ie.type = EV_FF; |
197 | ie.code = FF_GAIN; | |
198 | ie.value = 0xFFFFUL * gain / 100; | |
1da177e4 | 199 | |
3057d509 | 200 | if (write(fd, &ie, sizeof(ie)) == -1) |
1da177e4 LT |
201 | perror("set gain"); |
202 | ||
3057d509 MCC |
203 | Enabling/Disabling autocenter |
204 | ----------------------------- | |
205 | ||
1da177e4 LT |
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 | ||
3057d509 | 210 | :: |
1da177e4 | 211 | |
3057d509 MCC |
212 | int autocenter; /* between 0 and 100 */ |
213 | struct input_event ie; | |
1da177e4 | 214 | |
3057d509 MCC |
215 | ie.type = EV_FF; |
216 | ie.code = FF_AUTOCENTER; | |
217 | ie.value = 0xFFFFUL * autocenter / 100; | |
1da177e4 | 218 | |
3057d509 | 219 | if (write(fd, &ie, sizeof(ie)) == -1) |
1da177e4 LT |
220 | perror("set auto-center"); |
221 | ||
222 | A value of 0 means "no auto-center". | |
223 | ||
3057d509 MCC |
224 | Dynamic update of an effect |
225 | --------------------------- | |
226 | ||
1da177e4 LT |
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 | ||
8b8277a1 AH |
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. | |
1da177e4 | 236 | |
3057d509 MCC |
237 | Information about the status of effects |
238 | --------------------------------------- | |
239 | ||
1da177e4 | 240 | Every time the status of an effect is changed, an event is sent. The values |
3057d509 | 241 | and meanings of the fields of the event are as follows:: |
8b8277a1 | 242 | |
3057d509 MCC |
243 | struct input_event { |
244 | /* When the status of the effect changed */ | |
245 | struct timeval time; | |
1da177e4 | 246 | |
3057d509 MCC |
247 | /* Set to EV_FF_STATUS */ |
248 | unsigned short type; | |
1da177e4 | 249 | |
3057d509 MCC |
250 | /* Contains the id of the effect */ |
251 | unsigned short code; | |
1da177e4 | 252 | |
3057d509 MCC |
253 | /* Indicates the status */ |
254 | unsigned int value; | |
255 | }; | |
1da177e4 | 256 | |
3057d509 MCC |
257 | FF_STATUS_STOPPED The effect stopped playing |
258 | FF_STATUS_PLAYING The effect started to play | |
8b8277a1 | 259 | |
3057d509 | 260 | .. note:: |
8b8277a1 | 261 | |
3057d509 | 262 | - Status feedback is only supported by iforce driver. If you have |
8b8277a1 AH |
263 | a really good reason to use this, please contact |
264 | linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com | |
265 | so that support for it can be added to the rest of the drivers. |