23
23
#if defined(_USING_DYNAMIC_HID)
24
24
25
25
// #define JOYSTICK_STATE_SIZE 13
26
- #define JOYSTICK_STATE_SIZE 4
26
+ // #define JOYSTICK_STATE_SIZE 4
27
27
28
28
#define JOYSTICK_REPORT_ID_INDEX 7
29
29
@@ -100,95 +100,133 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
100
100
0xc0 // END_COLLECTION
101
101
};
102
102
103
- Joystick_::Joystick_ (uint8_t hidReportId)
103
+ Joystick_::Joystick_ (uint8_t hidReportId,
104
+ uint8_t buttonCount)
104
105
{
105
106
// Set the USB HID Report ID
106
107
_hidReportId = hidReportId;
107
-
108
- // Customize HID report
109
- // int hidReportDescriptorSize = sizeof(_hidReportDescriptor);
110
108
111
- int hidReportDescriptorSize = 29 ;
112
- uint8_t *customHidReportDescriptor = new uint8_t [hidReportDescriptorSize];
109
+ // Save Joystick Settings
110
+ _buttonCount = buttonCount;
111
+
112
+ // Build Joystick HID Report Description
113
+ uint8_t buttonsInLastByte = _buttonCount % 8 ;
114
+ uint8_t buttonPaddingBits = 0 ;
115
+ if (buttonsInLastByte > 0 )
116
+ {
117
+ buttonPaddingBits = 8 - buttonsInLastByte;
118
+ }
119
+
120
+ // TODO: Figure out what the max for this could be and set it here...
121
+ uint8_t *customHidReportDescriptor = new uint8_t [100 ];
122
+ int hidReportDescriptorSize = 0 ;
113
123
114
124
// USAGE_PAGE (Generic Desktop)
115
- customHidReportDescriptor[0 ] = 0x05 ;
116
- customHidReportDescriptor[1 ] = 0x01 ;
125
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x05 ;
126
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x01 ;
117
127
118
128
// USAGE (Joystick)
119
- customHidReportDescriptor[2 ] = 0x09 ;
120
- customHidReportDescriptor[3 ] = 0x04 ;
129
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x09 ;
130
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x04 ;
121
131
122
132
// COLLECTION (Application)
123
- customHidReportDescriptor[4 ] = 0xa1 ;
124
- customHidReportDescriptor[5 ] = 0x01 ;
133
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0xa1 ;
134
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x01 ;
125
135
126
136
// REPORT_ID (Default: 3)
127
- customHidReportDescriptor[6 ] = 0x85 ;
128
- customHidReportDescriptor[7 ] = _hidReportId;
137
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x85 ;
138
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = _hidReportId;
129
139
130
140
// USAGE_PAGE (Button)
131
- customHidReportDescriptor[8 ] = 0x05 ;
132
- customHidReportDescriptor[9 ] = 0x09 ;
141
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x05 ;
142
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x09 ;
133
143
134
144
// USAGE_MINIMUM (Button 1)
135
- customHidReportDescriptor[10 ] = 0x19 ;
136
- customHidReportDescriptor[11 ] = 0x01 ;
145
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x19 ;
146
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x01 ;
137
147
138
148
// USAGE_MAXIMUM (Button 32)
139
- customHidReportDescriptor[12 ] = 0x29 ;
140
- customHidReportDescriptor[13 ] = 0x20 ;
149
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x29 ;
150
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = _buttonCount ;
141
151
142
152
// LOGICAL_MINIMUM (0)
143
- customHidReportDescriptor[14 ] = 0x15 ;
144
- customHidReportDescriptor[15 ] = 0x00 ;
153
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x15 ;
154
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x00 ;
145
155
146
156
// LOGICAL_MAXIMUM (1)
147
- customHidReportDescriptor[16 ] = 0x25 ;
148
- customHidReportDescriptor[17 ] = 0x01 ;
157
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x25 ;
158
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x01 ;
149
159
150
160
// REPORT_SIZE (1)
151
- customHidReportDescriptor[18 ] = 0x75 ;
152
- customHidReportDescriptor[19 ] = 0x01 ;
161
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x75 ;
162
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x01 ;
153
163
154
- // REPORT_COUNT (32 )
155
- customHidReportDescriptor[20 ] = 0x95 ;
156
- customHidReportDescriptor[21 ] = 0x20 ;
164
+ // REPORT_COUNT (# of buttons )
165
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x95 ;
166
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = _buttonCount ;
157
167
158
168
// UNIT_EXPONENT (0)
159
- customHidReportDescriptor[22 ] = 0x55 ;
160
- customHidReportDescriptor[23 ] = 0x00 ;
169
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x55 ;
170
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x00 ;
161
171
162
172
// UNIT (None)
163
- customHidReportDescriptor[24 ] = 0x65 ;
164
- customHidReportDescriptor[25 ] = 0x00 ;
173
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x65 ;
174
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0x00 ;
165
175
166
176
// INPUT (Data,Var,Abs)
167
- customHidReportDescriptor[26 ] = 0x81 ;
168
- customHidReportDescriptor[27 ] = 0x02 ;
177
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x81 ;
178
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x02 ;
179
+
180
+ if (buttonPaddingBits > 0 ) {
181
+
182
+ // REPORT_SIZE (1)
183
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x75 ;
184
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
185
+
186
+ // REPORT_COUNT (# of padding bits)
187
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x95 ;
188
+ customHidReportDescriptor[hidReportDescriptorSize++] = buttonPaddingBits;
189
+
190
+ // INPUT (Const,Var,Abs)
191
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x81 ;
192
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x03 ;
193
+ }
169
194
170
195
// END_COLLECTION
171
- customHidReportDescriptor[28 ] = 0xc0 ;
196
+ customHidReportDescriptor[hidReportDescriptorSize++ ] = 0xc0 ;
172
197
173
198
// Create a copy of the HID Report Descriptor template
174
199
// memcpy_P(customHidReportDescriptor, _hidReportDescriptor, hidReportDescriptorSize);
175
200
176
- // Setup HID report structure
201
+ // Register HID Report Description
177
202
_node = new DynamicHIDSubDescriptor (customHidReportDescriptor, hidReportDescriptorSize, false );
178
203
DynamicHID ().AppendDescriptor (_node);
179
204
180
- // Initalize State
205
+ // Setup Joystick State
206
+ _buttonValuesArraySize = _buttonCount / 8 ;
207
+ if ((_buttonCount % 8 ) > 0 ) {
208
+ _buttonValuesArraySize++;
209
+ }
210
+ _buttonValues = new uint8_t [_buttonValuesArraySize];
211
+
212
+ // Calculate HID Report Size
213
+ _hidReportSize = _buttonValuesArraySize;
214
+
215
+ // Initalize Joystick State
181
216
_xAxis = 0 ;
182
217
_yAxis = 0 ;
183
218
_zAxis = 0 ;
184
219
_xAxisRotation = 0 ;
185
220
_yAxisRotation = 0 ;
186
221
_zAxisRotation = 0 ;
187
- _buttons = 0 ;
188
222
_throttle = 0 ;
189
223
_rudder = 0 ;
190
224
_hatSwitch[0 ] = -1 ;
191
225
_hatSwitch[1 ] = -1 ;
226
+ for (int index = 0 ; index < _buttonValuesArraySize; index++)
227
+ {
228
+ _buttonValues[index] = 0 ;
229
+ }
192
230
}
193
231
194
232
void Joystick_::begin (bool initAutoSendState)
@@ -214,12 +252,22 @@ void Joystick_::setButton(uint8_t button, uint8_t value)
214
252
}
215
253
void Joystick_::pressButton (uint8_t button)
216
254
{
217
- bitSet (_buttons, button);
255
+ if (button >= _buttonCount) return ;
256
+
257
+ int index = button / 8 ;
258
+ int bit = button % 8 ;
259
+
260
+ bitSet (_buttonValues[index], bit);
218
261
if (_autoSendState) sendState ();
219
262
}
220
263
void Joystick_::releaseButton (uint8_t button)
221
264
{
222
- bitClear (_buttons, button);
265
+ if (button >= _buttonCount) return ;
266
+
267
+ int index = button / 8 ;
268
+ int bit = button % 8 ;
269
+
270
+ bitClear (_buttonValues[index], bit);
223
271
if (_autoSendState) sendState ();
224
272
}
225
273
@@ -274,17 +322,13 @@ void Joystick_::setHatSwitch(int8_t hatSwitchIndex, int16_t value)
274
322
275
323
void Joystick_::sendState ()
276
324
{
277
- uint8_t data[JOYSTICK_STATE_SIZE];
278
- uint32_t buttonTmp = _buttons;
279
-
280
- // Split 32 bit button-state into 4 bytes
281
- data[0 ] = buttonTmp & 0xFF ;
282
- buttonTmp >>= 8 ;
283
- data[1 ] = buttonTmp & 0xFF ;
284
- buttonTmp >>= 8 ;
285
- data[2 ] = buttonTmp & 0xFF ;
286
- buttonTmp >>= 8 ;
287
- data[3 ] = buttonTmp & 0xFF ;
325
+ uint8_t data[_hidReportSize];
326
+
327
+ // Load Button State
328
+ for (int index = 0 ; index < _hidReportSize; index++)
329
+ {
330
+ data[index] = _buttonValues[index];
331
+ }
288
332
289
333
// data[4] = _throttle;
290
334
// data[5] = _rudder;
@@ -317,7 +361,7 @@ void Joystick_::sendState()
317
361
// data[12] = (_zAxisRotation % 360) * 0.708;
318
362
319
363
// HID().SendReport(Report number, array of values in same order as HID descriptor, length)
320
- DynamicHID ().SendReport (_hidReportId, data, JOYSTICK_STATE_SIZE );
364
+ DynamicHID ().SendReport (_hidReportId, data, _hidReportSize );
321
365
}
322
366
323
367
#endif
0 commit comments