요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===============
Iforce Protocol
===============
:Author: Johann Deneux <johann.deneux@gmail.com>
Home page at `<http://web.archive.org/web/*/http://www.esil.univ-mrs.fr>`_
:Additions: by Vojtech Pavlik.
Introduction
============
This document describes what I managed to discover about the protocol used to
specify force effects to I-Force 2.0 devices. None of this information comes
from Immerse. That's why you should not trust what is written in this
document. This document is intended to help understanding the protocol.
This is not a reference. Comments and corrections are welcome. To contact me,
send an email to: johann.deneux@gmail.com
.. warning::
I shall not be held responsible for any damage or harm caused if you try to
send data to your I-Force device based on what you read in this document.
Preliminary Notes
=================
All values are hexadecimal with big-endian encoding (msb on the left). Beware,
values inside packets are encoded using little-endian. Bytes whose roles are
unknown are marked ??? Information that needs deeper inspection is marked (?)
General form of a packet
------------------------
This is how packets look when the device uses the rs232 to communicate.
== == === ==== ==
2B OP LEN DATA CS
== == === ==== ==
CS is the checksum. It is equal to the exclusive or of all bytes.
When using USB:
== ====
OP DATA
== ====
The 2B, LEN and CS fields have disappeared, probably because USB handles
frames and data corruption is handled or insignificant.
First, I describe effects that are sent by the device to the computer
Device input state
==================
This packet is used to indicate the state of each button and the value of each
axis::
OP= 01 for a joystick, 03 for a wheel
LEN= Varies from device to device
00 X-Axis lsb
01 X-Axis msb
02 Y-Axis lsb, or gas pedal for a wheel
03 Y-Axis msb, or brake pedal for a wheel
04 Throttle
05 Buttons
06 Lower 4 bits: Buttons
Upper 4 bits: Hat
07 Rudder
Device effects states
=====================
::
OP= 02
LEN= Varies
00 ? Bit 1 (Value 2) is the value of the deadman switch
01 Bit 8 is set if the effect is playing. Bits 0 to 7 are the effect id.
02 ??
03 Address of parameter block changed (lsb)
04 Address of parameter block changed (msb)
05 Address of second parameter block changed (lsb)
... depending on the number of parameter blocks updated
Force effect
------------
::
OP= 01
LEN= 0e
00 Channel (when playing several effects at the same time, each must
be assigned a channel)
01 Wave form
Val 00 Constant
Val 20 Square
Val 21 Triangle
Val 22 Sine
Val 23 Sawtooth up
Val 24 Sawtooth down
Val 40 Spring (Force = f(pos))
Val 41 Friction (Force = f(velocity)) and Inertia
(Force = f(acceleration))
02 Axes affected and trigger
Bits 4-7: Val 2 = effect along one axis. Byte 05 indicates direction
Val 4 = X axis only. Byte 05 must contain 5a
Val 8 = Y axis only. Byte 05 must contain b4
Val c = X and Y axes. Bytes 05 must contain 60
Bits 0-3: Val 0 = No trigger
Val x+1 = Button x triggers the effect
When the whole byte is 0, cancel the previously set trigger
03-04 Duration of effect (little endian encoding, in ms)
05 Direction of effect, if applicable. Else, see 02 for value to assign.
06-07 Minimum time between triggering.
08-09 Address of periodicity or magnitude parameters
0a-0b Address of attack and fade parameters, or ffff if none.
*or*
08-09 Address of interactive parameters for X-axis,
or ffff if not applicable
0a-0b Address of interactive parameters for Y-axis,
or ffff if not applicable
0c-0d Delay before execution of effect (little endian encoding, in ms)
Time based parameters
---------------------
Attack and fade
^^^^^^^^^^^^^^^
::
OP= 02
LEN= 08
00-01 Address where to store the parameters
02-03 Duration of attack (little endian encoding, in ms)
04 Level at end of attack. Signed byte.
05-06 Duration of fade.
07 Level at end of fade.
Magnitude
^^^^^^^^^
::
OP= 03
LEN= 03
00-01 Address
02 Level. Signed byte.
Periodicity
^^^^^^^^^^^
::
OP= 04
LEN= 07
00-01 Address
02 Magnitude. Signed byte.
03 Offset. Signed byte.
04 Phase. Val 00 = 0 deg, Val 40 = 90 degs.
05-06 Period (little endian encoding, in ms)
Interactive parameters
----------------------
::
OP= 05
LEN= 0a
00-01 Address
02 Positive Coeff
03 Negative Coeff
04+05 Offset (center)
06+07 Dead band (Val 01F4 = 5000 (decimal))
08 Positive saturation (Val 0a = 1000 (decimal) Val 64 = 10000 (decimal))
09 Negative saturation
The encoding is a bit funny here: For coeffs, these are signed values. The
maximum value is 64 (100 decimal), the min is 9c.
For the offset, the minimum value is FE0C, the maximum value is 01F4.
For the deadband, the minimum value is 0, the max is 03E8.
Controls
--------
::
OP= 41
LEN= 03
00 Channel
01 Start/Stop
Val 00: Stop
Val 01: Start and play once.
Val 41: Start and play n times (See byte 02 below)
02 Number of iterations n.
Init
----
Querying features
^^^^^^^^^^^^^^^^^
::
OP= ff
Query command. Length varies according to the query type.
The general format of this packet is:
ff 01 QUERY [INDEX] CHECKSUM
responses are of the same form:
FF LEN QUERY VALUE_QUERIED CHECKSUM2
where LEN = 1 + length(VALUE_QUERIED)
Query ram size
~~~~~~~~~~~~~~
::
QUERY = 42 ('B'uffer size)
The device should reply with the same packet plus two additional bytes
containing the size of the memory:
ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
Query number of effects
~~~~~~~~~~~~~~~~~~~~~~~
::
QUERY = 4e ('N'umber of effects)
The device should respond by sending the number of effects that can be played
at the same time (one byte)
ff 02 4e 14 CS would stand for 20 effects.
Vendor's id
~~~~~~~~~~~
::
QUERY = 4d ('M'anufacturer)
Query the vendors'id (2 bytes)
Product id
~~~~~~~~~~
::
QUERY = 50 ('P'roduct)
Query the product id (2 bytes)
Open device
~~~~~~~~~~~
::
QUERY = 4f ('O'pen)
No data returned.
Close device
~~~~~~~~~~~~
::
QUERY = 43 ('C')lose
No data returned.
Query effect
~~~~~~~~~~~~
::
QUERY = 45 ('E')
Send effect type.
Returns nonzero if supported (2 bytes)
Firmware Version
~~~~~~~~~~~~~~~~
::
QUERY = 56 ('V'ersion)
Sends back 3 bytes - major, minor, subminor
Initialisation of the device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Set Control
~~~~~~~~~~~
.. note::
Device dependent, can be different on different models!
::
OP= 40 <idx> <val> [<val>]
LEN= 2 or 3
00 Idx
Idx 00 Set dead zone (0..2048)
Idx 01 Ignore Deadman sensor (0..1)
Idx 02 Enable comm watchdog (0..1)
Idx 03 Set the strength of the spring (0..100)
Idx 04 Enable or disable the spring (0/1)
Idx 05 Set axis saturation threshold (0..2048)
Set Effect State
~~~~~~~~~~~~~~~~
::
OP= 42 <val>
LEN= 1
00 State
Bit 3 Pause force feedback
Bit 2 Enable force feedback
Bit 0 Stop all effects
Set overall
~~~~~~~~~~~
::
OP= 43 <val>
LEN= 1
00 Gain
Val 00 = 0%
Val 40 = 50%
Val 80 = 100%
Parameter memory
----------------
Each device has a certain amount of memory to store parameters of effects.
The amount of RAM may vary, I encountered values from 200 to 1000 bytes. Below
is the amount of memory apparently needed for every set of parameters:
- period : 0c
- magnitude : 02
- attack and fade : 0e
- interactive : 08
Appendix: How to study the protocol?
====================================
1. Generate effects using the force editor provided with the DirectX SDK, or
use Immersion Studio (freely available at their web site in the developer section:
www.immersion.com)
2. Start a soft spying RS232 or USB (depending on where you connected your
joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
3. Play the effect, and watch what happens on the spy screen.
A few words about ComPortSpy:
At first glance, this software seems, hum, well... buggy. In fact, data appear with a
few seconds latency. Personally, I restart it every time I play an effect.
Remember it's free (as in free beer) and alpha!
URLS
====
Check http://www.immerse.com for Immersion Studio,
and http://www.fcoder.com for ComPortSpy.
I-Force is trademark of Immersion Corp.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
역공학 문서의 한계와 전송 프레임
1-53이 문서는 Johann Deneux가 작성하고 Vojtech Pavlik가 내용을 보탠 I-Force 프로토콜 역공학 기록입니다. 보관된 프로젝트 홈페이지 링크와 저자 연락처는 원문에 보존되어 있습니다.
I-Force 2.0 장치에 force effect를 지정하는 프로토콜을 관찰해 정리한 것이며 Immerse가 제공한 공식 정보가 아닙니다. 이해를 돕기 위한 문서일 뿐 참조 명세가 아니므로, 내용에 근거해 장치로 데이터를 전송하다 발생하는 손상이나 위해에 저자는 책임지지 않는다고 경고합니다.
표시된 값은 모두 16진수이고 문서 표기 자체는 MSB가 왼쪽인 big-endian입니다. 그러나 패킷 내부의 다중 바이트 값은 little-endian으로 인코딩됩니다. 역할을 모르는 바이트는 `???`, 추가 조사가 필요한 정보는 `(?)`로 표시합니다.
RS-232와 USB에서 같은 명령이 감싸지는 방식을 비교합니다.
RS-232의 `CS`는 모든 바이트를 exclusive OR한 checksum입니다. USB에서는 `2B`, `LEN`, `CS`가 사라지는데, USB가 프레임을 처리하고 데이터 손상도 전송 계층에서 처리하거나 중요하지 않기 때문으로 추정합니다.
논리 명령을 직렬 또는 USB 프레임으로 만드는 차이입니다.
===============
Iforce Protocol
===============
:Author: Johann Deneux <johann.deneux@gmail.com>
Home page at `<http://web.archive.org/web/*/http://www.esil.univ-mrs.fr>`_
:Additions: by Vojtech Pavlik.
Introduction
============
This document describes what I managed to discover about the protocol used to
specify force effects to I-Force 2.0 devices. None of this information comes
from Immerse. That's why you should not trust what is written in this
document. This document is intended to help understanding the protocol.
This is not a reference. Comments and corrections are welcome. To contact me,
send an email to: johann.deneux@gmail.com
.. warning::
I shall not be held responsible for any damage or harm caused if you try to
send data to your I-Force device based on what you read in this document.
Preliminary Notes
=================
All values are hexadecimal with big-endian encoding (msb on the left). Beware,
values inside packets are encoded using little-endian. Bytes whose roles are
unknown are marked ??? Information that needs deeper inspection is marked (?)
General form of a packet
------------------------
This is how packets look when the device uses the rs232 to communicate.
== == === ==== ==
2B OP LEN DATA CS
== == === ==== ==
CS is the checksum. It is equal to the exclusive or of all bytes.
When using USB:
== ====
OP DATA
== ====
The 2B, LEN and CS fields have disappeared, probably because USB handles
frames and data corruption is handled or insignificant.
장치 입력과 효과 상태 보고
54-88먼저 장치가 컴퓨터로 보내는 보고를 설명합니다. Device input state 패킷은 각 버튼 상태와 각 축 값을 전달합니다. `OP=01`은 조이스틱, `OP=03`은 휠이며 길이는 장치마다 다릅니다.
조이스틱·휠 입력 보고의 바이트 오프셋입니다.
Device effects states는 `OP=02`이고 길이는 갱신된 매개변수 블록 수에 따라 달라집니다.
효과 재생 상태와 변경된 parameter block 주소입니다.
입력 상태와 효과 상태 opcode를 구분하는 흐름입니다.
First, I describe effects that are sent by the device to the computer
Device input state
==================
This packet is used to indicate the state of each button and the value of each
axis::
OP= 01 for a joystick, 03 for a wheel
LEN= Varies from device to device
00 X-Axis lsb
01 X-Axis msb
02 Y-Axis lsb, or gas pedal for a wheel
03 Y-Axis msb, or brake pedal for a wheel
04 Throttle
05 Buttons
06 Lower 4 bits: Buttons
Upper 4 bits: Hat
07 Rudder
Device effects states
=====================
::
OP= 02
LEN= Varies
00 ? Bit 1 (Value 2) is the value of the deadman switch
01 Bit 8 is set if the effect is playing. Bits 0 to 7 are the effect id.
02 ??
03 Address of parameter block changed (lsb)
04 Address of parameter block changed (msb)
05 Address of second parameter block changed (lsb)
... depending on the number of parameter blocks updated
Force effect 정의 패킷
89-135Force effect 명령은 `OP=01`, `LEN=0e`입니다. 여러 효과를 동시에 재생할 때 각각 채널을 배정하고, 파형·적용 축·트리거·지속시간·방향·재트리거 간격·매개변수 주소·실행 지연을 지정합니다.
Force effect 바이트 01의 waveform 코드입니다.
상위 nibble은 축, 하위 nibble은 버튼 트리거입니다.
14바이트 데이터의 전체 필드입니다.
주기·크기 효과에서는 08~09가 periodicity 또는 magnitude 매개변수 주소이고 0a~0b가 attack/fade 주소입니다. Interactive 효과에서는 같은 위치가 X축과 Y축 interactive 매개변수 주소가 되며 해당하지 않으면 `ffff`를 사용합니다.
효과 정의가 별도 parameter block과 연결되는 방식입니다.
Force effect
------------
::
OP= 01
LEN= 0e
00 Channel (when playing several effects at the same time, each must
be assigned a channel)
01 Wave form
Val 00 Constant
Val 20 Square
Val 21 Triangle
Val 22 Sine
Val 23 Sawtooth up
Val 24 Sawtooth down
Val 40 Spring (Force = f(pos))
Val 41 Friction (Force = f(velocity)) and Inertia
(Force = f(acceleration))
02 Axes affected and trigger
Bits 4-7: Val 2 = effect along one axis. Byte 05 indicates direction
Val 4 = X axis only. Byte 05 must contain 5a
Val 8 = Y axis only. Byte 05 must contain b4
Val c = X and Y axes. Bytes 05 must contain 60
Bits 0-3: Val 0 = No trigger
Val x+1 = Button x triggers the effect
When the whole byte is 0, cancel the previously set trigger
03-04 Duration of effect (little endian encoding, in ms)
05 Direction of effect, if applicable. Else, see 02 for value to assign.
06-07 Minimum time between triggering.
08-09 Address of periodicity or magnitude parameters
0a-0b Address of attack and fade parameters, or ffff if none.
*or*
08-09 Address of interactive parameters for X-axis,
or ffff if not applicable
0a-0b Address of interactive parameters for Y-axis,
or ffff if not applicable
0c-0d Delay before execution of effect (little endian encoding, in ms)
시간·상호작용 매개변수와 재생 제어
136-208효과 시작·종료 엔벌로프 매개변수입니다.
정적 크기 parameter block입니다.
주기 효과의 크기·오프셋·위상·주기입니다.
위치·속도·가속도 기반 효과 함수의 계수와 범위입니다.
Interactive 인코딩은 특이합니다. 계수는 signed이고 최대 `64`(decimal 100), 최소 `9c`입니다. Offset 범위는 `FE0C`~`01F4`, deadband 범위는 0~`03E8`입니다. 원문의 예시 숫자와 설명은 그대로 보존합니다.
채널별 효과 시작·정지와 반복 횟수입니다.
parameter memory에 블록을 올리고 채널을 시작하는 순서입니다.
Time based parameters
---------------------
Attack and fade
^^^^^^^^^^^^^^^
::
OP= 02
LEN= 08
00-01 Address where to store the parameters
02-03 Duration of attack (little endian encoding, in ms)
04 Level at end of attack. Signed byte.
05-06 Duration of fade.
07 Level at end of fade.
Magnitude
^^^^^^^^^
::
OP= 03
LEN= 03
00-01 Address
02 Level. Signed byte.
Periodicity
^^^^^^^^^^^
::
OP= 04
LEN= 07
00-01 Address
02 Magnitude. Signed byte.
03 Offset. Signed byte.
04 Phase. Val 00 = 0 deg, Val 40 = 90 degs.
05-06 Period (little endian encoding, in ms)
Interactive parameters
----------------------
::
OP= 05
LEN= 0a
00-01 Address
02 Positive Coeff
03 Negative Coeff
04+05 Offset (center)
06+07 Dead band (Val 01F4 = 5000 (decimal))
08 Positive saturation (Val 0a = 1000 (decimal) Val 64 = 10000 (decimal))
09 Negative saturation
The encoding is a bit funny here: For coeffs, these are signed values. The
maximum value is 64 (100 decimal), the min is 9c.
For the offset, the minimum value is FE0C, the maximum value is 01F4.
For the deadband, the minimum value is 0, the max is 03E8.
Controls
--------
::
OP= 41
LEN= 03
00 Channel
01 Start/Stop
Val 00: Stop
Val 01: Start and play once.
Val 41: Start and play n times (See byte 02 below)
02 Number of iterations n.
초기 기능 질의 명령
209-301기능 질의는 `OP=ff`를 사용하고 길이는 질의 종류에 따라 달라집니다. 일반 RS-232 요청은 `ff 01 QUERY [INDEX] CHECKSUM`, 응답은 `FF LEN QUERY VALUE_QUERIED CHECKSUM2`이며 `LEN = 1 + length(VALUE_QUERIED)`입니다.
초기화 중 사용할 수 있는 질의와 반환 데이터입니다.
원문의 RAM과 동시 효과 수 예시를 해석합니다.
Effect 질의 `45`에는 효과 유형을 보내고 지원하면 0이 아닌 2바이트를 반환합니다. Open과 Close는 반환 데이터가 없습니다. Firmware 질의는 major, minor, subminor 세 바이트를 돌려줍니다.
초기화 전에 식별과 자원을 확인하는 권장 질의 흐름입니다.
Init
----
Querying features
^^^^^^^^^^^^^^^^^
::
OP= ff
Query command. Length varies according to the query type.
The general format of this packet is:
ff 01 QUERY [INDEX] CHECKSUM
responses are of the same form:
FF LEN QUERY VALUE_QUERIED CHECKSUM2
where LEN = 1 + length(VALUE_QUERIED)
Query ram size
~~~~~~~~~~~~~~
::
QUERY = 42 ('B'uffer size)
The device should reply with the same packet plus two additional bytes
containing the size of the memory:
ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
Query number of effects
~~~~~~~~~~~~~~~~~~~~~~~
::
QUERY = 4e ('N'umber of effects)
The device should respond by sending the number of effects that can be played
at the same time (one byte)
ff 02 4e 14 CS would stand for 20 effects.
Vendor's id
~~~~~~~~~~~
::
QUERY = 4d ('M'anufacturer)
Query the vendors'id (2 bytes)
Product id
~~~~~~~~~~
::
QUERY = 50 ('P'roduct)
Query the product id (2 bytes)
Open device
~~~~~~~~~~~
::
QUERY = 4f ('O'pen)
No data returned.
Close device
~~~~~~~~~~~~
::
QUERY = 43 ('C')lose
No data returned.
Query effect
~~~~~~~~~~~~
::
QUERY = 45 ('E')
Send effect type.
Returns nonzero if supported (2 bytes)
Firmware Version
~~~~~~~~~~~~~~~~
::
QUERY = 56 ('V'ersion)
Sends back 3 bytes - major, minor, subminor
장치 제어 초기화와 매개변수 메모리
302-358Set Control은 장치 모델마다 다를 수 있으므로 값의 의미를 장치별로 확인해야 합니다. 형식은 `OP=40 <idx> <val> [<val>]`, `LEN=2` 또는 `3`입니다.
문서에 알려진 장치 제어 index와 범위입니다.
상태 바이트의 force feedback 제어 비트입니다.
전체 gain 값과 백분율의 대응입니다.
각 장치는 효과 parameter를 저장할 RAM을 가지며 관찰된 크기는 200~1000바이트입니다. 업로드 전에 `QUERY=42`로 실제 크기를 확인해야 합니다.
각 매개변수 세트에 필요한 것으로 관찰된 바이트 수입니다.
장치를 열고 전역 제어와 효과 메모리를 준비하는 순서입니다.
Initialisation of the device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Set Control
~~~~~~~~~~~
.. note::
Device dependent, can be different on different models!
::
OP= 40 <idx> <val> [<val>]
LEN= 2 or 3
00 Idx
Idx 00 Set dead zone (0..2048)
Idx 01 Ignore Deadman sensor (0..1)
Idx 02 Enable comm watchdog (0..1)
Idx 03 Set the strength of the spring (0..100)
Idx 04 Enable or disable the spring (0/1)
Idx 05 Set axis saturation threshold (0..2048)
Set Effect State
~~~~~~~~~~~~~~~~
::
OP= 42 <val>
LEN= 1
00 State
Bit 3 Pause force feedback
Bit 2 Enable force feedback
Bit 0 Stop all effects
Set overall
~~~~~~~~~~~
::
OP= 43 <val>
LEN= 1
00 Gain
Val 00 = 0%
Val 40 = 50%
Val 80 = 100%
Parameter memory
----------------
Each device has a certain amount of memory to store parameters of effects.
The amount of RAM may vary, I encountered values from 200 to 1000 bytes. Below
is the amount of memory apparently needed for every set of parameters:
- period : 0c
- magnitude : 02
- attack and fade : 0e
- interactive : 08
프로토콜 조사 절차와 도구
359-381프로토콜을 조사하려면 DirectX SDK의 force editor 또는 Immersion Studio로 효과를 생성하고, 조이스틱이나 휠의 연결 방식에 따라 RS-232 또는 USB 소프트웨어 감시를 시작한 뒤 효과를 재생하면서 패킷을 관찰합니다.
원문의 세 단계와 사용 도구입니다.
ComPortSpy는 처음에는 버그가 많은 것처럼 보이지만 실제로 데이터가 몇 초 늦게 나타납니다. 저자는 효과를 재생할 때마다 프로그램을 재시작했습니다. 무료이지만 alpha 버전이라는 점을 감안해야 합니다.
프로토콜 조사 도구의 원문 주소입니다.
I-Force는 Immersion Corp.의 상표입니다.
비공식 역공학 결과를 재현 가능하게 확인하는 흐름입니다.
Appendix: How to study the protocol?
====================================
1. Generate effects using the force editor provided with the DirectX SDK, or
use Immersion Studio (freely available at their web site in the developer section:
www.immersion.com)
2. Start a soft spying RS232 or USB (depending on where you connected your
joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
3. Play the effect, and watch what happens on the spy screen.
A few words about ComPortSpy:
At first glance, this software seems, hum, well... buggy. In fact, data appear with a
few seconds latency. Personally, I restart it every time I play an effect.
Remember it's free (as in free beer) and alpha!
URLS
====
Check http://www.immerse.com for Immersion Studio,
and http://www.fcoder.com for ComPortSpy.
I-Force is trademark of Immersion Corp.
요약·해설
iforce-protocol.rst:1-381I-Force 프로토콜 문서는 공식 명세가 아닌 관찰 기반 역공학 기록입니다. 효과 정의는 작은 opcode 패킷과 장치 RAM의 parameter block을 연결하며, 전송 프레이밍과 패킷 내부 little-endian 값을 구분하는 것이 핵심입니다.
프로토콜의 주요 방향과 명령군을 요약합니다.
기능 질의부터 효과 재생까지의 순서입니다.