3232#define EPIN 0x80
3333
3434uint8_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
4040static 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)
6872Adafruit_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
160171bool 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
171191bool 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
176196bool 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
180200bool 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
184204bool 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
194214uint8_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) {
207227uint16_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 )
221241void 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
239259bool 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
244264bool 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
257277bool 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
274295bool 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
278300bool 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
283306bool 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
287310bool 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
0 commit comments