-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathffb.h
260 lines (221 loc) · 8.37 KB
/
ffb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
Force Feedback Joystick
USB HID descriptors for a force feedback joystick.
Copyright 2012 Tero Loimuneva (tloimu [at] gmail [dot] com)
Copyright 2016 Jaka Simonic (telesimke [at] gmail [dot] com)
MIT License.
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#ifndef _FFB_
#define _FFB_
/* Type Defines: */
/** Type define for the joystick HID report structure, for creating and sending HID reports to the host PC.
* This mirrors the layout described to the host in the HID report descriptor, in Descriptors.c.
*/
// Maximum number of parallel effects in memory
#define MAX_EFFECTS 10
#define SIZE_EFFECT sizeof(TEffectState)
#define MEMORY_SIZE (uint16_t)(MAX_EFFECTS*SIZE_EFFECT)
#define TO_LT_END_16(x) ((x<<8)&0xFF00)|((x>>8)&0x00FF) //to little endian for 16 bit value
#pragma pack(1)
// ---- Input
typedef struct
{ //PID State
uint8_t reportId; // =2
uint8_t status; // Bits: 0=Device Paused,1=Actuators Enabled,2=Safety Switch,3=Actuator Override Switch,4=Actuator Power
uint8_t effectBlockIndex; // Bit7=Effect Playing, Bit0..7=EffectId (1..40)
} USB_FFBReport_PIDStatus_Input_Data_t;
// ---- Output
typedef struct
{ // FFB: Set Effect Output Report
uint8_t reportId; // =1
uint8_t effectBlockIndex; // 1..40
uint8_t effectType; // 1..12 (effect usages: 26,27,30,31,32,33,34,40,41,42,43,28)
uint16_t duration; // 0..32767 ms
uint16_t triggerRepeatInterval; // 0..32767 ms
uint16_t samplePeriod; // 0..32767 ms
uint8_t gain; // 0..255 (physical 0..10000)
uint8_t triggerButton; // button ID (0..8)
uint8_t enableAxis; // bits: 0=X, 1=Y, 2=DirectionEnable
uint8_t directionX; // angle (0=0 .. 255=360deg)
uint8_t directionY; // angle (0=0 .. 255=360deg)
// uint16_t startDelay; // 0..32767 ms
} USB_FFBReport_SetEffect_Output_Data_t;
typedef struct
{ // FFB: Set Envelope Output Report
uint8_t reportId; // =2
uint8_t effectBlockIndex; // 1..40
uint8_t attackLevel;
uint8_t fadeLevel;
uint16_t attackTime; // ms
uint16_t fadeTime; // ms
} USB_FFBReport_SetEnvelope_Output_Data_t;
typedef struct
{ // FFB: Set Condition Output Report
uint8_t reportId; // =3
uint8_t effectBlockIndex; // 1..40
uint8_t parameterBlockOffset; // bits: 0..3=parameterBlockOffset, 4..5=instance1, 6..7=instance2
int8_t cpOffset; // 0..255
int8_t positiveCoefficient; // -128..127
int8_t negativeCoefficient; // -128..127
uint8_t positiveSaturation; // - 128..127
uint8_t negativeSaturation; // -128..127
uint8_t deadBand; // 0..255
} USB_FFBReport_SetCondition_Output_Data_t;
typedef struct
{ // FFB: Set Periodic Output Report
uint8_t reportId; // =4
uint8_t effectBlockIndex; // 1..40
uint8_t magnitude;
int8_t offset;
uint8_t phase; // 0..255 (=0..359, exp-2)
uint16_t period; // 0..32767 ms
} USB_FFBReport_SetPeriodic_Output_Data_t;
typedef struct
{ // FFB: Set ConstantForce Output Report
uint8_t reportId; // =5
uint8_t effectBlockIndex; // 1..40
int16_t magnitude; // -255..255
} USB_FFBReport_SetConstantForce_Output_Data_t;
typedef struct
{ // FFB: Set RampForce Output Report
uint8_t reportId; // =6
uint8_t effectBlockIndex; // 1..40
int8_t start;
int8_t end;
} USB_FFBReport_SetRampForce_Output_Data_t;
typedef struct
{ // FFB: Set CustomForceData Output Report
uint8_t reportId; // =7
uint8_t effectBlockIndex; // 1..40
uint8_t dataOffset;
int8_t data[12];
} USB_FFBReport_SetCustomForceData_Output_Data_t;
typedef struct
{ // FFB: Set DownloadForceSample Output Report
uint8_t reportId; // =8
int8_t x;
int8_t y;
} USB_FFBReport_SetDownloadForceSample_Output_Data_t;
typedef struct
{ // FFB: Set EffectOperation Output Report
uint8_t reportId; // =10
uint8_t effectBlockIndex; // 1..40
uint8_t operation; // 1=Start, 2=StartSolo, 3=Stop
uint8_t loopCount;
} USB_FFBReport_EffectOperation_Output_Data_t;
typedef struct
{ // FFB: Block Free Output Report
uint8_t reportId; // =11
uint8_t effectBlockIndex; // 1..40
} USB_FFBReport_BlockFree_Output_Data_t;
typedef struct
{ // FFB: Device Control Output Report
uint8_t reportId; // =12
uint8_t control; // 1=Enable Actuators, 2=Disable Actuators, 4=Stop All Effects, 8=Reset, 16=Pause, 32=Continue
} USB_FFBReport_DeviceControl_Output_Data_t;
typedef struct
{ // FFB: DeviceGain Output Report
uint8_t reportId; // =13
uint8_t gain;
} USB_FFBReport_DeviceGain_Output_Data_t;
typedef struct
{ // FFB: Set Custom Force Output Report
uint8_t reportId; // =14
uint8_t effectBlockIndex; // 1..40
uint8_t sampleCount;
uint16_t samplePeriod; // 0..32767 ms
} USB_FFBReport_SetCustomForce_Output_Data_t;
// ---- Features
typedef struct
{ // FFB: Create New Effect Feature Report
uint8_t reportId; // =1
uint8_t effectType; // Enum (1..12): ET 26,27,30,31,32,33,34,40,41,42,43,28
uint16_t byteCount; // 0..511
} USB_FFBReport_CreateNewEffect_Feature_Data_t;
typedef struct
{ // FFB: PID Pool Feature Report
uint8_t reportId; // =3
uint16_t ramPoolSize; // ?
uint8_t maxSimultaneousEffects; // ?? 40?
uint8_t memoryManagement; // Bits: 0=DeviceManagedPool, 1=SharedParameterBlocks
} USB_FFBReport_PIDPool_Feature_Data_t;
typedef struct
{ // FFB: PID Block Load Feature Report
uint8_t reportId; // =2
uint8_t effectBlockIndex; // 1..40
uint8_t loadStatus; // 1=Success,2=Full,3=Error
uint16_t ramPoolAvailable; // =0 or 0xFFFF?
} USB_FFBReport_PIDBlockLoad_Feature_Data_t;
#pragma pack(2)
// Handle incoming data from USB
void FfbOnUsbData(uint8_t *data, uint16_t len);
// Handle incoming feature requests
void FfbOnCreateNewEffect(USB_FFBReport_CreateNewEffect_Feature_Data_t* inData);
uint8_t *FfbOnPIDPool(void);
uint8_t *FfbOnPIDBlockLoad(void);
uint8_t *FfbOnPIDStatus(void);
void FfbGetFeedbackValue(int16_t* axisPosition, int16_t* out);
#define USB_DURATION_INFINITE 0x7FFF
#define USB_EFFECT_CONSTANT 0x01
#define USB_EFFECT_RAMP 0x02
#define USB_EFFECT_SQUARE 0x03
#define USB_EFFECT_SINE 0x04
#define USB_EFFECT_TRIANGLE 0x05
#define USB_EFFECT_SAWTOOTHDOWN 0x06
#define USB_EFFECT_SAWTOOTHUP 0x07
#define USB_EFFECT_SPRING 0x08
#define USB_EFFECT_DAMPER 0x09
#define USB_EFFECT_INERTIA 0x0A
#define USB_EFFECT_FRICTION 0x0B
#define USB_EFFECT_CUSTOM 0x0C
// Bit-masks for effect states
#define MEFFECTSTATE_FREE 0x00
#define MEFFECTSTATE_ALLOCATED 0x01
#define MEFFECTSTATE_PLAYING 0x02
#define X_AXIS_ENABLE 0x01
#define Y_AXIS_ENABLE 0x02
#define DIRECTION_ENABLE 0x04
//these were needed for testing
#define INERTIA_FORCE 0xFF
#define FRICTION_FORCE 0xFF
#define INERTIA_DEADBAND 0x30
#define FRICTION_DEADBAND 0x30
typedef struct {
uint8_t state; // see constants <MEffectState_*>
uint8_t effectType; //
int8_t offset;
uint8_t gain, attackLevel, fadeLevel;
uint8_t magnitude;
uint8_t enableAxis; // bits: 0=X, 1=Y, 2=DirectionEnable
uint8_t directionX; // angle (0=0 .. 255=360deg)
uint8_t directionY; // angle (0=0 .. 255=360deg)
uint8_t axesIdx;
int8_t cpOffset[2]; // -128..127
int8_t positiveCoefficient[2]; // -128..127
int8_t negativeCoefficient[2]; // -128..127
uint8_t positiveSaturation[2]; // -128..127
uint8_t negativeSaturation[2]; // -128..127
uint8_t deadBand[2]; // 0..255
uint8_t phase; // 0..255 (=0..359, exp-2)
int8_t start;
int8_t end;
uint16_t period; // 0..32767 ms
uint16_t duration, fadeTime,attackTime,elapsedTime;
} TEffectState;
#endif