@@ -103,8 +103,10 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
103
103
};
104
104
*/
105
105
106
- Joystick_::Joystick_ (uint8_t hidReportId,
106
+ Joystick_::Joystick_ (
107
+ uint8_t hidReportId,
107
108
uint8_t buttonCount,
109
+ uint8_t hatSwitchCount,
108
110
bool includeXAxis,
109
111
bool includeYAxis,
110
112
bool includeZAxis,
@@ -122,6 +124,7 @@ Joystick_::Joystick_(uint8_t hidReportId,
122
124
123
125
// Save Joystick Settings
124
126
_buttonCount = buttonCount;
127
+ _hatSwitchCount = hatSwitchCount;
125
128
_includeXAxis = includeXAxis;
126
129
_includeYAxis = includeYAxis;
127
130
_includeZAxis = includeZAxis;
@@ -159,7 +162,7 @@ Joystick_::Joystick_(uint8_t hidReportId,
159
162
+ (includeSteering == true );
160
163
161
164
// TODO: Figure out what the max for this could be and set it here...
162
- uint8_t *customHidReportDescriptor = new uint8_t [100 ];
165
+ uint8_t *customHidReportDescriptor = new uint8_t [150 ];
163
166
int hidReportDescriptorSize = 0 ;
164
167
165
168
// USAGE_PAGE (Generic Desktop)
@@ -237,13 +240,115 @@ Joystick_::Joystick_(uint8_t hidReportId,
237
240
} // Padding Bits Needed
238
241
239
242
} // Buttons
240
-
241
- if (axisCount > 0 ) {
243
+
244
+ if (( axisCount > 0 ) || (_hatSwitchCount > 0 ) ) {
242
245
243
246
// USAGE_PAGE (Generic Desktop)
244
247
customHidReportDescriptor[hidReportDescriptorSize++] = 0x05 ;
245
248
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
249
+
250
+ }
251
+
252
+ if (_hatSwitchCount > 0 ) {
253
+
254
+ // USAGE (Hat Switch)
255
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x09 ;
256
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x39 ;
257
+
258
+ // LOGICAL_MINIMUM (0)
259
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x15 ;
260
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x00 ;
261
+
262
+ // LOGICAL_MAXIMUM (7)
263
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x25 ;
264
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x07 ;
265
+
266
+ // PHYSICAL_MINIMUM (0)
267
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x35 ;
268
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x00 ;
269
+
270
+ // PHYSICAL_MAXIMUM (315)
271
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x46 ;
272
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x3B ;
273
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
274
+
275
+ // UNIT (Eng Rot:Angular Pos)
276
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x65 ;
277
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x14 ;
278
+
279
+ // REPORT_SIZE (4)
280
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x75 ;
281
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x04 ;
282
+
283
+ // REPORT_COUNT (1)
284
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x95 ;
285
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
286
+
287
+ // INPUT (Data,Var,Abs)
288
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x81 ;
289
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x02 ;
290
+
291
+ if (_hatSwitchCount > 1 ) {
292
+
293
+ // USAGE (Hat Switch)
294
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x09 ;
295
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x39 ;
296
+
297
+ // LOGICAL_MINIMUM (0)
298
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x15 ;
299
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x00 ;
300
+
301
+ // LOGICAL_MAXIMUM (7)
302
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x25 ;
303
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x07 ;
304
+
305
+ // PHYSICAL_MINIMUM (0)
306
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x35 ;
307
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x00 ;
308
+
309
+ // PHYSICAL_MAXIMUM (315)
310
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x46 ;
311
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x3B ;
312
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
313
+
314
+ // UNIT (Eng Rot:Angular Pos)
315
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x65 ;
316
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x14 ;
317
+
318
+ // REPORT_SIZE (4)
319
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x75 ;
320
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x04 ;
321
+
322
+ // REPORT_COUNT (1)
323
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x95 ;
324
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
325
+
326
+ // INPUT (Data,Var,Abs)
327
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x81 ;
328
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x02 ;
329
+
330
+ } else {
331
+
332
+ // Use Padding Bits
333
+
334
+ // REPORT_SIZE (1)
335
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x75 ;
336
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
246
337
338
+ // REPORT_COUNT (4)
339
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x95 ;
340
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x04 ;
341
+
342
+ // INPUT (Const,Var,Abs)
343
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x81 ;
344
+ customHidReportDescriptor[hidReportDescriptorSize++] = 0x03 ;
345
+
346
+ } // One or Two Hat Switches?
347
+
348
+ } // Hat Switches
349
+
350
+ if (axisCount > 0 ) {
351
+
247
352
// USAGE (Pointer)
248
353
customHidReportDescriptor[hidReportDescriptorSize++] = 0x09 ;
249
354
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01 ;
@@ -393,20 +498,20 @@ Joystick_::Joystick_(uint8_t hidReportId,
393
498
DynamicHID ().AppendDescriptor (_node);
394
499
395
500
// Setup Joystick State
396
- _buttonValuesArraySize = _buttonCount / 8 ;
397
- if ((_buttonCount % 8 ) > 0 ) {
398
- _buttonValuesArraySize++;
399
- }
400
- _buttonValues = new uint8_t [_buttonValuesArraySize];
401
-
501
+ if (buttonCount > 0 ) {
502
+ _buttonValuesArraySize = _buttonCount / 8 ;
503
+ if ((_buttonCount % 8 ) > 0 ) {
504
+ _buttonValuesArraySize++;
505
+ }
506
+ _buttonValues = new uint8_t [_buttonValuesArraySize];
507
+ }
508
+
402
509
// Calculate HID Report Size
403
510
_hidReportSize = _buttonValuesArraySize;
511
+ _hidReportSize += (_hatSwitchCount > 0 );
404
512
_hidReportSize += (axisCount * 2 );
405
513
_hidReportSize += (simulationCount * 2 );
406
-
407
- Serial.print (" _hidReportSize: " );
408
- Serial.println (_hidReportSize);
409
-
514
+
410
515
// Initalize Joystick State
411
516
_xAxis = 0 ;
412
517
_yAxis = 0 ;
@@ -419,14 +524,23 @@ Joystick_::Joystick_(uint8_t hidReportId,
419
524
_accelerator = 0 ;
420
525
_brake = 0 ;
421
526
_steering = 0 ;
422
- _hatSwitch[0 ] = -1 ;
423
- _hatSwitch[1 ] = -1 ;
527
+ for (int index = 0 ; index < JOYSTICK_HATSWITCH_COUNT_MAXIMUM; index++)
528
+ {
529
+ _hatSwitchValues[index] = -1 ;
530
+ }
424
531
for (int index = 0 ; index < _buttonValuesArraySize; index++)
425
532
{
426
533
_buttonValues[index] = 0 ;
427
534
}
428
535
}
429
536
537
+ Joystick_::~Joystick_ () {
538
+ if (_buttonValues != NULL ) {
539
+ delete[] _buttonValues;
540
+ _buttonValues = NULL ;
541
+ }
542
+ }
543
+
430
544
void Joystick_::begin (bool initAutoSendState)
431
545
{
432
546
_autoSendState = initAutoSendState;
@@ -617,7 +731,9 @@ void Joystick_::setSteering(int16_t value)
617
731
618
732
void Joystick_::setHatSwitch (int8_t hatSwitchIndex, int16_t value)
619
733
{
620
- _hatSwitch[hatSwitchIndex % 2 ] = value;
734
+ if (hatSwitchIndex >= _hatSwitchCount) return ;
735
+
736
+ _hatSwitchValues[hatSwitchIndex] = value;
621
737
if (_autoSendState) sendState ();
622
738
}
623
739
@@ -632,6 +748,28 @@ void Joystick_::sendState()
632
748
data[index] = _buttonValues[index];
633
749
}
634
750
751
+ // Set Hat Switch Values
752
+ if (_hatSwitchCount > 0 ) {
753
+
754
+ // Calculate hat-switch values
755
+ uint8_t convertedHatSwitch[JOYSTICK_HATSWITCH_COUNT_MAXIMUM];
756
+ for (int hatSwitchIndex = 0 ; hatSwitchIndex < JOYSTICK_HATSWITCH_COUNT_MAXIMUM; hatSwitchIndex++)
757
+ {
758
+ if (_hatSwitchValues[hatSwitchIndex] < 0 )
759
+ {
760
+ convertedHatSwitch[hatSwitchIndex] = 8 ;
761
+ }
762
+ else
763
+ {
764
+ convertedHatSwitch[hatSwitchIndex] = (_hatSwitchValues[hatSwitchIndex] % 360 ) / 45 ;
765
+ }
766
+ }
767
+
768
+ // Pack hat-switch states into a single byte
769
+ data[index++] = (convertedHatSwitch[1 ] << 4 ) | (B00001111 & convertedHatSwitch[0 ]);
770
+
771
+ } // Hat Switches
772
+
635
773
// Set Axis Values
636
774
int16_t convertedValue;
637
775
uint8_t highByte;
@@ -736,26 +874,6 @@ void Joystick_::sendState()
736
874
data[index++] = highByte;
737
875
}
738
876
739
-
740
- // Calculate hat-switch values
741
- /*
742
- uint8_t convertedHatSwitch[2];
743
- for (int hatSwitchIndex = 0; hatSwitchIndex < 2; hatSwitchIndex++)
744
- {
745
- if (_hatSwitch[hatSwitchIndex] < 0)
746
- {
747
- convertedHatSwitch[hatSwitchIndex] = 8;
748
- }
749
- else
750
- {
751
- convertedHatSwitch[hatSwitchIndex] = (_hatSwitch[hatSwitchIndex] % 360) / 45;
752
- }
753
- }
754
- */
755
-
756
- // Pack hat-switch states into a single byte
757
- // data[6] = (convertedHatSwitch[1] << 4) | (B00001111 & convertedHatSwitch[0]);
758
-
759
877
DynamicHID ().SendReport (_hidReportId, data, _hidReportSize);
760
878
}
761
879
0 commit comments