xref: /OK3568_Linux_fs/kernel/Documentation/input/devices/iforce-protocol.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun===============
2*4882a593SmuzhiyunIforce Protocol
3*4882a593Smuzhiyun===============
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun:Author: Johann Deneux <johann.deneux@gmail.com>
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunHome page at `<http://web.archive.org/web/*/http://www.esil.univ-mrs.fr>`_
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun:Additions: by Vojtech Pavlik.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun
12*4882a593SmuzhiyunIntroduction
13*4882a593Smuzhiyun============
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunThis document describes what I managed to discover about the protocol used to
16*4882a593Smuzhiyunspecify force effects to I-Force 2.0 devices.  None of this information comes
17*4882a593Smuzhiyunfrom Immerse. That's why you should not trust what is written in this
18*4882a593Smuzhiyundocument. This document is intended to help understanding the protocol.
19*4882a593SmuzhiyunThis is not a reference. Comments and corrections are welcome.  To contact me,
20*4882a593Smuzhiyunsend an email to: johann.deneux@gmail.com
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun.. warning::
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun    I shall not be held responsible for any damage or harm caused if you try to
25*4882a593Smuzhiyun    send data to your I-Force device based on what you read in this document.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunPreliminary Notes
28*4882a593Smuzhiyun=================
29*4882a593Smuzhiyun
30*4882a593SmuzhiyunAll values are hexadecimal with big-endian encoding (msb on the left). Beware,
31*4882a593Smuzhiyunvalues inside packets are encoded using little-endian.  Bytes whose roles are
32*4882a593Smuzhiyununknown are marked ???  Information that needs deeper inspection is marked (?)
33*4882a593Smuzhiyun
34*4882a593SmuzhiyunGeneral form of a packet
35*4882a593Smuzhiyun------------------------
36*4882a593Smuzhiyun
37*4882a593SmuzhiyunThis is how packets look when the device uses the rs232 to communicate.
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun== == === ==== ==
40*4882a593Smuzhiyun2B OP LEN DATA CS
41*4882a593Smuzhiyun== == === ==== ==
42*4882a593Smuzhiyun
43*4882a593SmuzhiyunCS is the checksum. It is equal to the exclusive or of all bytes.
44*4882a593Smuzhiyun
45*4882a593SmuzhiyunWhen using USB:
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun== ====
48*4882a593SmuzhiyunOP DATA
49*4882a593Smuzhiyun== ====
50*4882a593Smuzhiyun
51*4882a593SmuzhiyunThe 2B, LEN and CS fields have disappeared, probably because USB handles
52*4882a593Smuzhiyunframes and data corruption is handled or unsignificant.
53*4882a593Smuzhiyun
54*4882a593SmuzhiyunFirst, I describe effects that are sent by the device to the computer
55*4882a593Smuzhiyun
56*4882a593SmuzhiyunDevice input state
57*4882a593Smuzhiyun==================
58*4882a593Smuzhiyun
59*4882a593SmuzhiyunThis packet is used to indicate the state of each button and the value of each
60*4882a593Smuzhiyunaxis::
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun    OP= 01 for a joystick, 03 for a wheel
63*4882a593Smuzhiyun    LEN= Varies from device to device
64*4882a593Smuzhiyun    00 X-Axis lsb
65*4882a593Smuzhiyun    01 X-Axis msb
66*4882a593Smuzhiyun    02 Y-Axis lsb, or gas pedal for a wheel
67*4882a593Smuzhiyun    03 Y-Axis msb, or brake pedal for a wheel
68*4882a593Smuzhiyun    04 Throttle
69*4882a593Smuzhiyun    05 Buttons
70*4882a593Smuzhiyun    06 Lower 4 bits: Buttons
71*4882a593Smuzhiyun       Upper 4 bits: Hat
72*4882a593Smuzhiyun    07 Rudder
73*4882a593Smuzhiyun
74*4882a593SmuzhiyunDevice effects states
75*4882a593Smuzhiyun=====================
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun::
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun    OP= 02
80*4882a593Smuzhiyun    LEN= Varies
81*4882a593Smuzhiyun    00 ? Bit 1 (Value 2) is the value of the deadman switch
82*4882a593Smuzhiyun    01 Bit 8 is set if the effect is playing. Bits 0 to 7 are the effect id.
83*4882a593Smuzhiyun    02 ??
84*4882a593Smuzhiyun    03 Address of parameter block changed (lsb)
85*4882a593Smuzhiyun    04 Address of parameter block changed (msb)
86*4882a593Smuzhiyun    05 Address of second parameter block changed (lsb)
87*4882a593Smuzhiyun    ... depending on the number of parameter blocks updated
88*4882a593Smuzhiyun
89*4882a593SmuzhiyunForce effect
90*4882a593Smuzhiyun------------
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun::
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun    OP=  01
95*4882a593Smuzhiyun    LEN= 0e
96*4882a593Smuzhiyun    00 Channel (when playing several effects at the same time, each must
97*4882a593Smuzhiyun                be assigned a channel)
98*4882a593Smuzhiyun    01 Wave form
99*4882a593Smuzhiyun	    Val 00 Constant
100*4882a593Smuzhiyun	    Val 20 Square
101*4882a593Smuzhiyun	    Val 21 Triangle
102*4882a593Smuzhiyun	    Val 22 Sine
103*4882a593Smuzhiyun	    Val 23 Sawtooth up
104*4882a593Smuzhiyun	    Val 24 Sawtooth down
105*4882a593Smuzhiyun	    Val 40 Spring (Force = f(pos))
106*4882a593Smuzhiyun	    Val 41 Friction (Force = f(velocity)) and Inertia
107*4882a593Smuzhiyun	           (Force = f(acceleration))
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun    02 Axes affected and trigger
111*4882a593Smuzhiyun	    Bits 4-7: Val 2 = effect along one axis. Byte 05 indicates direction
112*4882a593Smuzhiyun		    Val 4 = X axis only. Byte 05 must contain 5a
113*4882a593Smuzhiyun		    Val 8 = Y axis only. Byte 05 must contain b4
114*4882a593Smuzhiyun		    Val c = X and Y axes. Bytes 05 must contain 60
115*4882a593Smuzhiyun	    Bits 0-3: Val 0 = No trigger
116*4882a593Smuzhiyun		    Val x+1 = Button x triggers the effect
117*4882a593Smuzhiyun	    When the whole byte is 0, cancel the previously set trigger
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun    03-04 Duration of effect (little endian encoding, in ms)
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun    05 Direction of effect, if applicable. Else, see 02 for value to assign.
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun    06-07 Minimum time between triggering.
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun    08-09 Address of periodicity or magnitude parameters
126*4882a593Smuzhiyun    0a-0b Address of attack and fade parameters, or ffff if none.
127*4882a593Smuzhiyun    *or*
128*4882a593Smuzhiyun    08-09 Address of interactive parameters for X-axis,
129*4882a593Smuzhiyun          or ffff if not applicable
130*4882a593Smuzhiyun    0a-0b Address of interactive parameters for Y-axis,
131*4882a593Smuzhiyun	  or ffff if not applicable
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun    0c-0d Delay before execution of effect (little endian encoding, in ms)
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun
136*4882a593SmuzhiyunTime based parameters
137*4882a593Smuzhiyun---------------------
138*4882a593Smuzhiyun
139*4882a593SmuzhiyunAttack and fade
140*4882a593Smuzhiyun^^^^^^^^^^^^^^^
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun::
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun    OP=  02
145*4882a593Smuzhiyun    LEN= 08
146*4882a593Smuzhiyun    00-01 Address where to store the parameters
147*4882a593Smuzhiyun    02-03 Duration of attack (little endian encoding, in ms)
148*4882a593Smuzhiyun    04 Level at end of attack. Signed byte.
149*4882a593Smuzhiyun    05-06 Duration of fade.
150*4882a593Smuzhiyun    07 Level at end of fade.
151*4882a593Smuzhiyun
152*4882a593SmuzhiyunMagnitude
153*4882a593Smuzhiyun^^^^^^^^^
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun::
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun    OP=  03
158*4882a593Smuzhiyun    LEN= 03
159*4882a593Smuzhiyun    00-01 Address
160*4882a593Smuzhiyun    02 Level. Signed byte.
161*4882a593Smuzhiyun
162*4882a593SmuzhiyunPeriodicity
163*4882a593Smuzhiyun^^^^^^^^^^^
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun::
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun    OP=  04
168*4882a593Smuzhiyun    LEN= 07
169*4882a593Smuzhiyun    00-01 Address
170*4882a593Smuzhiyun    02 Magnitude. Signed byte.
171*4882a593Smuzhiyun    03 Offset. Signed byte.
172*4882a593Smuzhiyun    04 Phase. Val 00 = 0 deg, Val 40 = 90 degs.
173*4882a593Smuzhiyun    05-06 Period (little endian encoding, in ms)
174*4882a593Smuzhiyun
175*4882a593SmuzhiyunInteractive parameters
176*4882a593Smuzhiyun----------------------
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun::
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun    OP=  05
181*4882a593Smuzhiyun    LEN= 0a
182*4882a593Smuzhiyun    00-01 Address
183*4882a593Smuzhiyun    02 Positive Coeff
184*4882a593Smuzhiyun    03 Negative Coeff
185*4882a593Smuzhiyun    04+05 Offset (center)
186*4882a593Smuzhiyun    06+07 Dead band (Val 01F4 = 5000 (decimal))
187*4882a593Smuzhiyun    08 Positive saturation (Val 0a = 1000 (decimal) Val 64 = 10000 (decimal))
188*4882a593Smuzhiyun    09 Negative saturation
189*4882a593Smuzhiyun
190*4882a593SmuzhiyunThe encoding is a bit funny here: For coeffs, these are signed values. The
191*4882a593Smuzhiyunmaximum value is 64 (100 decimal), the min is 9c.
192*4882a593SmuzhiyunFor the offset, the minimum value is FE0C, the maximum value is 01F4.
193*4882a593SmuzhiyunFor the deadband, the minimum value is 0, the max is 03E8.
194*4882a593Smuzhiyun
195*4882a593SmuzhiyunControls
196*4882a593Smuzhiyun--------
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun::
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun    OP=  41
201*4882a593Smuzhiyun    LEN= 03
202*4882a593Smuzhiyun    00 Channel
203*4882a593Smuzhiyun    01 Start/Stop
204*4882a593Smuzhiyun	    Val 00: Stop
205*4882a593Smuzhiyun	    Val 01: Start and play once.
206*4882a593Smuzhiyun	    Val 41: Start and play n times (See byte 02 below)
207*4882a593Smuzhiyun    02 Number of iterations n.
208*4882a593Smuzhiyun
209*4882a593SmuzhiyunInit
210*4882a593Smuzhiyun----
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun
213*4882a593SmuzhiyunQuerying features
214*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^
215*4882a593Smuzhiyun::
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun    OP=  ff
218*4882a593Smuzhiyun    Query command. Length varies according to the query type.
219*4882a593Smuzhiyun    The general format of this packet is:
220*4882a593Smuzhiyun    ff 01 QUERY [INDEX] CHECKSUM
221*4882a593Smuzhiyun    responses are of the same form:
222*4882a593Smuzhiyun    FF LEN QUERY VALUE_QUERIED CHECKSUM2
223*4882a593Smuzhiyun    where LEN = 1 + length(VALUE_QUERIED)
224*4882a593Smuzhiyun
225*4882a593SmuzhiyunQuery ram size
226*4882a593Smuzhiyun~~~~~~~~~~~~~~
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun::
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun    QUERY = 42 ('B'uffer size)
231*4882a593Smuzhiyun
232*4882a593SmuzhiyunThe device should reply with the same packet plus two additional bytes
233*4882a593Smuzhiyuncontaining the size of the memory:
234*4882a593Smuzhiyunff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
235*4882a593Smuzhiyun
236*4882a593SmuzhiyunQuery number of effects
237*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun::
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun    QUERY = 4e ('N'umber of effects)
242*4882a593Smuzhiyun
243*4882a593SmuzhiyunThe device should respond by sending the number of effects that can be played
244*4882a593Smuzhiyunat the same time (one byte)
245*4882a593Smuzhiyunff 02 4e 14 CS would stand for 20 effects.
246*4882a593Smuzhiyun
247*4882a593SmuzhiyunVendor's id
248*4882a593Smuzhiyun~~~~~~~~~~~
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun::
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun    QUERY = 4d ('M'anufacturer)
253*4882a593Smuzhiyun
254*4882a593SmuzhiyunQuery the vendors'id (2 bytes)
255*4882a593Smuzhiyun
256*4882a593SmuzhiyunProduct id
257*4882a593Smuzhiyun~~~~~~~~~~
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun::
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun    QUERY = 50 ('P'roduct)
262*4882a593Smuzhiyun
263*4882a593SmuzhiyunQuery the product id (2 bytes)
264*4882a593Smuzhiyun
265*4882a593SmuzhiyunOpen device
266*4882a593Smuzhiyun~~~~~~~~~~~
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun::
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun    QUERY = 4f ('O'pen)
271*4882a593Smuzhiyun
272*4882a593SmuzhiyunNo data returned.
273*4882a593Smuzhiyun
274*4882a593SmuzhiyunClose device
275*4882a593Smuzhiyun~~~~~~~~~~~~
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun::
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun    QUERY = 43 ('C')lose
280*4882a593Smuzhiyun
281*4882a593SmuzhiyunNo data returned.
282*4882a593Smuzhiyun
283*4882a593SmuzhiyunQuery effect
284*4882a593Smuzhiyun~~~~~~~~~~~~
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun::
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun    QUERY = 45 ('E')
289*4882a593Smuzhiyun
290*4882a593SmuzhiyunSend effect type.
291*4882a593SmuzhiyunReturns nonzero if supported (2 bytes)
292*4882a593Smuzhiyun
293*4882a593SmuzhiyunFirmware Version
294*4882a593Smuzhiyun~~~~~~~~~~~~~~~~
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun::
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun    QUERY = 56 ('V'ersion)
299*4882a593Smuzhiyun
300*4882a593SmuzhiyunSends back 3 bytes - major, minor, subminor
301*4882a593Smuzhiyun
302*4882a593SmuzhiyunInitialisation of the device
303*4882a593Smuzhiyun^^^^^^^^^^^^^^^^^^^^^^^^^^^^
304*4882a593Smuzhiyun
305*4882a593SmuzhiyunSet Control
306*4882a593Smuzhiyun~~~~~~~~~~~
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun.. note::
309*4882a593Smuzhiyun    Device dependent, can be different on different models!
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun::
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun    OP=  40 <idx> <val> [<val>]
314*4882a593Smuzhiyun    LEN= 2 or 3
315*4882a593Smuzhiyun    00 Idx
316*4882a593Smuzhiyun       Idx 00 Set dead zone (0..2048)
317*4882a593Smuzhiyun       Idx 01 Ignore Deadman sensor (0..1)
318*4882a593Smuzhiyun       Idx 02 Enable comm watchdog (0..1)
319*4882a593Smuzhiyun       Idx 03 Set the strength of the spring (0..100)
320*4882a593Smuzhiyun       Idx 04 Enable or disable the spring (0/1)
321*4882a593Smuzhiyun       Idx 05 Set axis saturation threshold (0..2048)
322*4882a593Smuzhiyun
323*4882a593SmuzhiyunSet Effect State
324*4882a593Smuzhiyun~~~~~~~~~~~~~~~~
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun::
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun    OP=  42 <val>
329*4882a593Smuzhiyun    LEN= 1
330*4882a593Smuzhiyun    00 State
331*4882a593Smuzhiyun       Bit 3 Pause force feedback
332*4882a593Smuzhiyun       Bit 2 Enable force feedback
333*4882a593Smuzhiyun       Bit 0 Stop all effects
334*4882a593Smuzhiyun
335*4882a593SmuzhiyunSet overall
336*4882a593Smuzhiyun~~~~~~~~~~~
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun::
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun    OP=  43 <val>
341*4882a593Smuzhiyun    LEN= 1
342*4882a593Smuzhiyun    00 Gain
343*4882a593Smuzhiyun       Val 00 = 0%
344*4882a593Smuzhiyun       Val 40 = 50%
345*4882a593Smuzhiyun       Val 80 = 100%
346*4882a593Smuzhiyun
347*4882a593SmuzhiyunParameter memory
348*4882a593Smuzhiyun----------------
349*4882a593Smuzhiyun
350*4882a593SmuzhiyunEach device has a certain amount of memory to store parameters of effects.
351*4882a593SmuzhiyunThe amount of RAM may vary, I encountered values from 200 to 1000 bytes. Below
352*4882a593Smuzhiyunis the amount of memory apparently needed for every set of parameters:
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun - period : 0c
355*4882a593Smuzhiyun - magnitude : 02
356*4882a593Smuzhiyun - attack and fade : 0e
357*4882a593Smuzhiyun - interactive : 08
358*4882a593Smuzhiyun
359*4882a593SmuzhiyunAppendix: How to study the protocol?
360*4882a593Smuzhiyun====================================
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun1. Generate effects using the force editor provided with the DirectX SDK, or
363*4882a593Smuzhiyunuse Immersion Studio (freely available at their web site in the developer section:
364*4882a593Smuzhiyunwww.immersion.com)
365*4882a593Smuzhiyun2. Start a soft spying RS232 or USB (depending on where you connected your
366*4882a593Smuzhiyunjoystick/wheel). I used ComPortSpy from fCoder (alpha version!)
367*4882a593Smuzhiyun3. Play the effect, and watch what happens on the spy screen.
368*4882a593Smuzhiyun
369*4882a593SmuzhiyunA few words about ComPortSpy:
370*4882a593SmuzhiyunAt first glance, this software seems, hum, well... buggy. In fact, data appear with a
371*4882a593Smuzhiyunfew seconds latency. Personally, I restart it every time I play an effect.
372*4882a593SmuzhiyunRemember it's free (as in free beer) and alpha!
373*4882a593Smuzhiyun
374*4882a593SmuzhiyunURLS
375*4882a593Smuzhiyun====
376*4882a593Smuzhiyun
377*4882a593SmuzhiyunCheck http://www.immerse.com for Immersion Studio,
378*4882a593Smuzhiyunand http://www.fcoder.com for ComPortSpy.
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun
381*4882a593SmuzhiyunI-Force is trademark of Immersion Corp.
382