Skip to content

Commit 6546b4c

Browse files
authored
Merge pull request #280 from adafruit/multiple-hid-instances
enable multiple HID instances support, change CFG_TUD_HID=2 for all ports
2 parents 3c5a5bc + 647f6b2 commit 6546b4c

File tree

5 files changed

+62
-32
lines changed

5 files changed

+62
-32
lines changed

src/arduino/hid/Adafruit_USBD_HID.cpp

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,32 @@
3232
#define EPIN 0x80
3333

3434
uint8_t const _ascii2keycode[128][2] = {HID_ASCII_TO_KEYCODE};
35+
static Adafruit_USBD_HID *_hid_instances[CFG_TUD_HID] = {0};
3536

36-
// TODO multiple instances
37-
static Adafruit_USBD_HID *_hid_dev = NULL;
37+
uint8_t Adafruit_USBD_HID::_instance_count = 0;
3838

3939
#ifdef ARDUINO_ARCH_ESP32
4040
static uint16_t hid_load_descriptor(uint8_t *dst, uint8_t *itf) {
4141
// uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB HID");
4242

43-
TU_VERIFY(_hid_dev);
43+
uint8_t const inst_count = Adafruit_USBD_HID::getInstanceCount();
44+
TU_VERIFY(inst_count > 0, 0);
45+
46+
Adafruit_USBD_HID *p_hid = _hid_instances[inst_count - 1];
47+
TU_VERIFY(p_hid);
4448

4549
uint8_t ep_in = tinyusb_get_free_in_endpoint();
4650
TU_VERIFY(ep_in != 0);
4751
ep_in |= 0x80;
4852

4953
uint8_t ep_out = 0;
50-
if (_hid_dev->isOutEndpointEnabled()) {
54+
if (p_hid->isOutEndpointEnabled()) {
5155
ep_out = tinyusb_get_free_out_endpoint();
5256
TU_VERIFY(ep_out != 0);
5357
}
5458

5559
uint16_t const desc_len =
56-
_hid_dev->makeItfDesc(*itf, dst, TUD_HID_INOUT_DESC_LEN, ep_in, ep_out);
60+
p_hid->makeItfDesc(*itf, dst, TUD_HID_INOUT_DESC_LEN, ep_in, ep_out);
5761

5862
*itf += 1;
5963
return desc_len;
@@ -68,6 +72,7 @@ Adafruit_USBD_HID::Adafruit_USBD_HID(void)
6872
Adafruit_USBD_HID::Adafruit_USBD_HID(uint8_t const *desc_report, uint16_t len,
6973
uint8_t protocol, uint8_t interval_ms,
7074
bool has_out_endpoint) {
75+
_instance = INVALID_INSTANCE;
7176
_interval_ms = interval_ms;
7277
_protocol = protocol;
7378

@@ -82,7 +87,13 @@ Adafruit_USBD_HID::Adafruit_USBD_HID(uint8_t const *desc_report, uint16_t len,
8287

8388
#ifdef ARDUINO_ARCH_ESP32
8489
// ESP32 requires setup configuration descriptor within constructor
85-
_hid_dev = this;
90+
if (_instance_count >= CFG_TUD_HID) {
91+
return;
92+
}
93+
94+
_instance = _instance_count++;
95+
_hid_instances[_instance] = this;
96+
8697
uint16_t const desc_len = getInterfaceDescriptor(0, NULL, 0);
8798
tinyusb_enable_interface(USB_INTERFACE_HID, desc_len, hid_load_descriptor);
8899
#endif
@@ -158,31 +169,40 @@ uint16_t Adafruit_USBD_HID::getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf,
158169
}
159170

160171
bool Adafruit_USBD_HID::begin(void) {
172+
if (isValid()) {
173+
return true;
174+
}
175+
176+
if (_instance_count >= CFG_TUD_HID) {
177+
return false;
178+
}
179+
161180
if (!TinyUSBDevice.addInterface(*this)) {
162181
return false;
163182
}
183+
_instance = _instance_count++;
184+
_hid_instances[_instance] = this;
164185

165-
_hid_dev = this;
166186
return true;
167187
}
168188

169-
bool Adafruit_USBD_HID::ready(void) { return tud_hid_ready(); }
189+
bool Adafruit_USBD_HID::ready(void) { return tud_hid_n_ready(_instance); }
170190

171191
bool Adafruit_USBD_HID::sendReport(uint8_t report_id, void const *report,
172192
uint8_t len) {
173-
return tud_hid_report(report_id, report, len);
193+
return tud_hid_n_report(_instance, report_id, report, len);
174194
}
175195

176196
bool Adafruit_USBD_HID::sendReport8(uint8_t report_id, uint8_t num) {
177-
return tud_hid_report(report_id, &num, sizeof(num));
197+
return tud_hid_n_report(_instance, report_id, &num, sizeof(num));
178198
}
179199

180200
bool Adafruit_USBD_HID::sendReport16(uint8_t report_id, uint16_t num) {
181-
return tud_hid_report(report_id, &num, sizeof(num));
201+
return tud_hid_n_report(_instance, report_id, &num, sizeof(num));
182202
}
183203

184204
bool Adafruit_USBD_HID::sendReport32(uint8_t report_id, uint32_t num) {
185-
return tud_hid_report(report_id, &num, sizeof(num));
205+
return tud_hid_n_report(_instance, report_id, &num, sizeof(num));
186206
}
187207

188208
//------------- TinyUSB callbacks -------------//
@@ -192,13 +212,13 @@ extern "C" {
192212
// Application return pointer to descriptor, whose contents must exist long
193213
// enough for transfer to complete
194214
uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
195-
(void)itf;
215+
Adafruit_USBD_HID *p_hid = _hid_instances[itf];
196216

197-
if (!_hid_dev) {
217+
if (!p_hid) {
198218
return NULL;
199219
}
200220

201-
return _hid_dev->_desc_report;
221+
return p_hid->_desc_report;
202222
}
203223

204224
// Invoked when received GET_REPORT control request
@@ -207,27 +227,27 @@ uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
207227
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id,
208228
hid_report_type_t report_type, uint8_t *buffer,
209229
uint16_t reqlen) {
210-
(void)itf;
230+
Adafruit_USBD_HID *p_hid = _hid_instances[itf];
211231

212-
if (!(_hid_dev && _hid_dev->_get_report_cb)) {
232+
if (!(p_hid && p_hid->_get_report_cb)) {
213233
return 0;
214234
}
215235

216-
return _hid_dev->_get_report_cb(report_id, report_type, buffer, reqlen);
236+
return p_hid->_get_report_cb(report_id, report_type, buffer, reqlen);
217237
}
218238

219239
// Invoked when received SET_REPORT control request or
220240
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
221241
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
222242
hid_report_type_t report_type, uint8_t const *buffer,
223243
uint16_t bufsize) {
224-
(void)itf;
244+
Adafruit_USBD_HID *p_hid = _hid_instances[itf];
225245

226-
if (!(_hid_dev && _hid_dev->_set_report_cb)) {
246+
if (!(p_hid && p_hid->_set_report_cb)) {
227247
return;
228248
}
229249

230-
_hid_dev->_set_report_cb(report_id, report_type, buffer, bufsize);
250+
p_hid->_set_report_cb(report_id, report_type, buffer, bufsize);
231251
}
232252

233253
} // extern "C"
@@ -238,7 +258,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id,
238258

239259
bool Adafruit_USBD_HID::keyboardReport(uint8_t report_id, uint8_t modifier,
240260
uint8_t keycode[6]) {
241-
return tud_hid_keyboard_report(report_id, modifier, keycode);
261+
return tud_hid_n_keyboard_report(_instance, report_id, modifier, keycode);
242262
}
243263

244264
bool Adafruit_USBD_HID::keyboardPress(uint8_t report_id, char ch) {
@@ -251,11 +271,11 @@ bool Adafruit_USBD_HID::keyboardPress(uint8_t report_id, char ch) {
251271
}
252272
keycode[0] = _ascii2keycode[uch][1];
253273

254-
return tud_hid_keyboard_report(report_id, modifier, keycode);
274+
return tud_hid_n_keyboard_report(_instance, report_id, modifier, keycode);
255275
}
256276

257277
bool Adafruit_USBD_HID::keyboardRelease(uint8_t report_id) {
258-
return tud_hid_keyboard_report(report_id, 0, NULL);
278+
return tud_hid_n_keyboard_report(_instance, report_id, 0, NULL);
259279
}
260280

261281
//--------------------------------------------------------------------+
@@ -268,24 +288,27 @@ bool Adafruit_USBD_HID::mouseReport(uint8_t report_id, uint8_t buttons,
268288
// cache mouse button for other API such as move, scroll
269289
_mouse_button = buttons;
270290

271-
return tud_hid_mouse_report(report_id, buttons, x, y, vertical, horizontal);
291+
return tud_hid_n_mouse_report(_instance, report_id, buttons, x, y, vertical,
292+
horizontal);
272293
}
273294

274295
bool Adafruit_USBD_HID::mouseMove(uint8_t report_id, int8_t x, int8_t y) {
275-
return tud_hid_mouse_report(report_id, _mouse_button, x, y, 0, 0);
296+
return tud_hid_n_mouse_report(_instance, report_id, _mouse_button, x, y, 0,
297+
0);
276298
}
277299

278300
bool Adafruit_USBD_HID::mouseScroll(uint8_t report_id, int8_t scroll,
279301
int8_t pan) {
280-
return tud_hid_mouse_report(report_id, _mouse_button, 0, 0, scroll, pan);
302+
return tud_hid_n_mouse_report(_instance, report_id, _mouse_button, 0, 0,
303+
scroll, pan);
281304
}
282305

283306
bool Adafruit_USBD_HID::mouseButtonPress(uint8_t report_id, uint8_t buttons) {
284-
return tud_hid_mouse_report(report_id, buttons, 0, 0, 0, 0);
307+
return tud_hid_n_mouse_report(_instance, report_id, buttons, 0, 0, 0, 0);
285308
}
286309

287310
bool Adafruit_USBD_HID::mouseButtonRelease(uint8_t report_id) {
288-
return tud_hid_mouse_report(report_id, 0, 0, 0, 0, 0);
311+
return tud_hid_n_mouse_report(_instance, report_id, 0, 0, 0, 0, 0);
289312
}
290313

291314
#endif // CFG_TUD_ENABLED

src/arduino/hid/Adafruit_USBD_HID.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class Adafruit_USBD_HID : public Adafruit_USBD_Interface {
3737
uint8_t const *buffer,
3838
uint16_t bufsize);
3939

40+
enum { INVALID_INSTANCE = 0xffu };
41+
static uint8_t getInstanceCount(void) { return _instance_count; }
42+
4043
Adafruit_USBD_HID(void);
4144
Adafruit_USBD_HID(uint8_t const *desc_report, uint16_t len,
4245
uint8_t protocol = HID_ITF_PROTOCOL_NONE,
@@ -53,6 +56,7 @@ class Adafruit_USBD_HID : public Adafruit_USBD_Interface {
5356
set_report_callback_t set_report);
5457

5558
bool begin(void);
59+
bool isValid(void) { return _instance != INVALID_INSTANCE; }
5660

5761
bool ready(void);
5862
bool sendReport(uint8_t report_id, void const *report, uint8_t len);
@@ -84,6 +88,9 @@ class Adafruit_USBD_HID : public Adafruit_USBD_Interface {
8488
uint8_t ep_in, uint8_t ep_out);
8589

8690
private:
91+
static uint8_t _instance_count;
92+
93+
uint8_t _instance;
8794
uint8_t _interval_ms;
8895
uint8_t _protocol;
8996
bool _out_endpoint;

src/arduino/ports/nrf/tusb_config_nrf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ extern "C" {
5757
//------------- CLASS -------------//
5858
#define CFG_TUD_CDC 1
5959
#define CFG_TUD_MSC 1
60-
#define CFG_TUD_HID 1
60+
#define CFG_TUD_HID 2
6161
#define CFG_TUD_MIDI 1
6262
#define CFG_TUD_VENDOR 1
6363

src/arduino/ports/rp2040/tusb_config_rp2040.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ extern "C" {
6363

6464
#define CFG_TUD_CDC 1
6565
#define CFG_TUD_MSC 1
66-
#define CFG_TUD_HID 1
66+
#define CFG_TUD_HID 2
6767
#define CFG_TUD_MIDI 1
6868
#define CFG_TUD_VENDOR 1
6969

src/arduino/ports/samd/tusb_config_samd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ extern "C" {
6262
//------------- CLASS -------------//
6363
#define CFG_TUD_CDC 1
6464
#define CFG_TUD_MSC 1
65-
#define CFG_TUD_HID 1
65+
#define CFG_TUD_HID 2
6666
#define CFG_TUD_MIDI 1
6767
#define CFG_TUD_VENDOR 1
6868

0 commit comments

Comments
 (0)