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,11 +169,20 @@ 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
@@ -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"
0 commit comments