Skip to content

Commit b75604f

Browse files
committed
enable multiple HID instances support, change CFG_TUD_HID=2 for all ports except esp32sx
1 parent 34362e5 commit b75604f

File tree

5 files changed

+46
-19
lines changed

5 files changed

+46
-19
lines changed

src/arduino/hid/Adafruit_USBD_HID.cpp

Lines changed: 36 additions & 16 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,11 +169,20 @@ 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

@@ -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"

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)