Skip to content

Commit afee604

Browse files
committed
Customizable button count
Updated library to allow a custom number of buttons. Other functions are currently broken.
1 parent 7194e1b commit afee604

File tree

3 files changed

+116
-63
lines changed

3 files changed

+116
-63
lines changed

Joystick/examples/MultipleJoystickTest/MultipleJoystickTest.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
#define JOYSTICK_COUNT 4
1111

1212
Joystick_ Joystick[JOYSTICK_COUNT] = {
13-
Joystick_(0x03),
14-
Joystick_(0x04),
15-
Joystick_(0x05),
16-
Joystick_(0x06)
13+
Joystick_(0x03, 4),
14+
Joystick_(0x04, 8),
15+
Joystick_(0x05, 16),
16+
Joystick_(0x06, 32)
1717
};
1818

1919
// Set to true to test "Auto Send" mode or false to test "Manual Send" mode.

Joystick/src/Joystick.cpp

Lines changed: 98 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#if defined(_USING_DYNAMIC_HID)
2424

2525
//#define JOYSTICK_STATE_SIZE 13
26-
#define JOYSTICK_STATE_SIZE 4
26+
//#define JOYSTICK_STATE_SIZE 4
2727

2828
#define JOYSTICK_REPORT_ID_INDEX 7
2929

@@ -100,95 +100,133 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = {
100100
0xc0 // END_COLLECTION
101101
};
102102

103-
Joystick_::Joystick_(uint8_t hidReportId)
103+
Joystick_::Joystick_(uint8_t hidReportId,
104+
uint8_t buttonCount)
104105
{
105106
// Set the USB HID Report ID
106107
_hidReportId = hidReportId;
107-
108-
// Customize HID report
109-
//int hidReportDescriptorSize = sizeof(_hidReportDescriptor);
110108

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;
113123

114124
// USAGE_PAGE (Generic Desktop)
115-
customHidReportDescriptor[0] = 0x05;
116-
customHidReportDescriptor[1] = 0x01;
125+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x05;
126+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01;
117127

118128
// USAGE (Joystick)
119-
customHidReportDescriptor[2] = 0x09;
120-
customHidReportDescriptor[3] = 0x04;
129+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x09;
130+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x04;
121131

122132
// COLLECTION (Application)
123-
customHidReportDescriptor[4] = 0xa1;
124-
customHidReportDescriptor[5] = 0x01;
133+
customHidReportDescriptor[hidReportDescriptorSize++] = 0xa1;
134+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01;
125135

126136
// REPORT_ID (Default: 3)
127-
customHidReportDescriptor[6] = 0x85;
128-
customHidReportDescriptor[7] = _hidReportId;
137+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x85;
138+
customHidReportDescriptor[hidReportDescriptorSize++] = _hidReportId;
129139

130140
// USAGE_PAGE (Button)
131-
customHidReportDescriptor[8] = 0x05;
132-
customHidReportDescriptor[9] = 0x09;
141+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x05;
142+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x09;
133143

134144
// USAGE_MINIMUM (Button 1)
135-
customHidReportDescriptor[10] = 0x19;
136-
customHidReportDescriptor[11] = 0x01;
145+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x19;
146+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01;
137147

138148
// USAGE_MAXIMUM (Button 32)
139-
customHidReportDescriptor[12] = 0x29;
140-
customHidReportDescriptor[13] = 0x20;
149+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x29;
150+
customHidReportDescriptor[hidReportDescriptorSize++] = _buttonCount;
141151

142152
// LOGICAL_MINIMUM (0)
143-
customHidReportDescriptor[14] = 0x15;
144-
customHidReportDescriptor[15] = 0x00;
153+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x15;
154+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x00;
145155

146156
// LOGICAL_MAXIMUM (1)
147-
customHidReportDescriptor[16] = 0x25;
148-
customHidReportDescriptor[17] = 0x01;
157+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x25;
158+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01;
149159

150160
// REPORT_SIZE (1)
151-
customHidReportDescriptor[18] = 0x75;
152-
customHidReportDescriptor[19] = 0x01;
161+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x75;
162+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x01;
153163

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;
157167

158168
// UNIT_EXPONENT (0)
159-
customHidReportDescriptor[22] = 0x55;
160-
customHidReportDescriptor[23] = 0x00;
169+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x55;
170+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x00;
161171

162172
// UNIT (None)
163-
customHidReportDescriptor[24] = 0x65;
164-
customHidReportDescriptor[25] = 0x00;
173+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x65;
174+
customHidReportDescriptor[hidReportDescriptorSize++] = 0x00;
165175

166176
// 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+
}
169194

170195
// END_COLLECTION
171-
customHidReportDescriptor[28] = 0xc0;
196+
customHidReportDescriptor[hidReportDescriptorSize++] = 0xc0;
172197

173198
// Create a copy of the HID Report Descriptor template
174199
// memcpy_P(customHidReportDescriptor, _hidReportDescriptor, hidReportDescriptorSize);
175200

176-
// Setup HID report structure
201+
// Register HID Report Description
177202
_node = new DynamicHIDSubDescriptor(customHidReportDescriptor, hidReportDescriptorSize, false);
178203
DynamicHID().AppendDescriptor(_node);
179204

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
181216
_xAxis = 0;
182217
_yAxis = 0;
183218
_zAxis = 0;
184219
_xAxisRotation = 0;
185220
_yAxisRotation = 0;
186221
_zAxisRotation = 0;
187-
_buttons = 0;
188222
_throttle = 0;
189223
_rudder = 0;
190224
_hatSwitch[0] = -1;
191225
_hatSwitch[1] = -1;
226+
for (int index = 0; index < _buttonValuesArraySize; index++)
227+
{
228+
_buttonValues[index] = 0;
229+
}
192230
}
193231

194232
void Joystick_::begin(bool initAutoSendState)
@@ -214,12 +252,22 @@ void Joystick_::setButton(uint8_t button, uint8_t value)
214252
}
215253
void Joystick_::pressButton(uint8_t button)
216254
{
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);
218261
if (_autoSendState) sendState();
219262
}
220263
void Joystick_::releaseButton(uint8_t button)
221264
{
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);
223271
if (_autoSendState) sendState();
224272
}
225273

@@ -274,17 +322,13 @@ void Joystick_::setHatSwitch(int8_t hatSwitchIndex, int16_t value)
274322

275323
void Joystick_::sendState()
276324
{
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+
}
288332

289333
// data[4] = _throttle;
290334
// data[5] = _rudder;
@@ -317,7 +361,7 @@ void Joystick_::sendState()
317361
//data[12] = (_zAxisRotation % 360) * 0.708;
318362

319363
// 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);
321365
}
322366

323367
#endif

Joystick/src/Joystick.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,37 @@
4141
//================================================================================
4242
// Joystick (Gamepad)
4343

44-
#define JOYSTICK_DEFAULT_REPORT_ID 0x03
44+
#define JOYSTICK_DEFAULT_REPORT_ID 0x03
45+
#define JOYSTICK_DEFAULT_BUTTON_COUNT 32
4546

4647
class Joystick_
4748
{
4849
private:
49-
bool _autoSendState;
50+
51+
// Joystick State
5052
int16_t _xAxis;
5153
int16_t _yAxis;
5254
int16_t _zAxis;
5355
int16_t _xAxisRotation;
5456
int16_t _yAxisRotation;
5557
int16_t _zAxisRotation;
56-
uint32_t _buttons;
5758
int16_t _throttle;
5859
int16_t _rudder;
5960
int16_t _hatSwitch[2];
60-
61+
uint8_t *_buttonValues;
62+
63+
// Joystick Settings
64+
bool _autoSendState;
65+
uint8_t _buttonCount;
66+
int _buttonValuesArraySize;
67+
6168
DynamicHIDSubDescriptor *_node;
6269
uint8_t _hidReportId;
70+
int _hidReportSize;
6371

6472
public:
65-
Joystick_(uint8_t hidReportId = JOYSTICK_DEFAULT_REPORT_ID);
73+
Joystick_(uint8_t hidReportId = JOYSTICK_DEFAULT_REPORT_ID,
74+
uint8_t buttonCount = JOYSTICK_DEFAULT_BUTTON_COUNT);
6675

6776
void begin(bool initAutoSendState = true);
6877
void end();

0 commit comments

Comments
 (0)