arduino-pico icon indicating copy to clipboard operation
arduino-pico copied to clipboard

Feature Request / Advice: Select HID Types on startup/during runtime

Open benjaminaigner opened this issue 1 year ago • 2 comments

Dear @earlephilhower ,

I've following problem: the FLipMouse/FABI devices should support Mouse, Keyboard, Consumer and Joystick. The problem starts with special USB hosts, for example the XBox Adaptive Controller. Microsoft is not able to handle HID on this device like everyone else,

so using all 4 reports, the XAC is going crazy. Using Joystick only, it works.

What I've tried / what questions came up:

  • is it anyhow possible to assign HID report map / report IDs on startup? __SetupDescHIDReport is called before setup, so IMHO it is not possible to handle it here.

  • I tried to use the tinyUSB stack, what is basically no problem for me, but: when using tinyUSB, it is not possible to use BLE HID libraries anymore (using KeyboardBLE results in linker errors because tinyUSB is used)

  • Is it anyhow possible to define the HID report map & report IDs for USB and BLE on startup or is the only way to achieve that by implementing everything necessary from PicoBluetoothBLEHID.cpp and RP2040USB.cpp in my project and use the tinyUSB stack?

Thank you very much for advice and keep up with the wonderful work on this project! Greetings

benjaminaigner avatar Jan 26 '24 07:01 benjaminaigner

I don't think you can change the USB descriptor or HID report format after a connection is made. You'd need to do a disconnect and reconnect/negotiate sequence for any changes AIUI. I'm not sure that's possible with the existing TinyUSB stack (which is used by the SDK as well as the Adafruit library).

The USB descriptor and HID report IDs and format are set up by the core before setup because that's the only way to guarantee that we get a USB CDC (Serial) with which to reset and upload another sketch. If we don't do this, and the user doesn't do a Serial.begin() then they won't be able to upload anything else w/o manually rebooting and holding BOOTSEL which is non-optimal.

but: when using tinyUSB, it is not possible to use BLE HID libraries anymore (using KeyboardBLE results in linker errors because tinyUSB is used)

What errors exactly? The BT/BLE HID interfaces use the same report formats as TinyUSB, but I don't think they depend on any actual code. It might be simple enough to add fixes bracketed with #ifdef USE_TINYUSB.

earlephilhower avatar Jan 26 '24 17:01 earlephilhower

THX @earlephilhower for the feedback.

I have to split up things:

  1. indeed, when using Adafruit TinyUSB Device + KeyboardBLE it does not compile (attached is an example):
/home/xxx/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld: /tmp/arduino_build_500275/libraries/Keyboard/Keyboard.cpp.o: in function `tud_hid_set_report_cb':
/home/xxx/Arduino/hardware/pico/rp2040/libraries/Keyboard/src/Keyboard.cpp:59: multiple definition of `tud_hid_set_report_cb'; /tmp/arduino_build_500275/libraries/Adafruit_TinyUSB_Arduino/arduino/hid/Adafruit_USBD_HID.cpp.o:/home/xxx/Arduino/hardware/pico/rp2040/libraries/Adafruit_TinyUSB_Arduino/src/arduino/hid/Adafruit_USBD_HID.cpp:243: first defined here
/home/xxx/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld: /tmp/arduino_build_500275/libraries/Keyboard/Keyboard.cpp.o: in function `_ZN9Keyboard_18sendConsumerReportEt':
/home/xxx/Arduino/hardware/pico/rp2040/libraries/Keyboard/src/Keyboard.cpp:52: undefined reference to `_Z13__USBHIDReadyv'
/home/xxx/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld: /home/xxx/Arduino/hardware/pico/rp2040/libraries/Keyboard/src/Keyboard.cpp:53: undefined reference to `_Z24__USBGetKeyboardReportIDv'
/home/xxx/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld: /tmp/arduino_build_500275/libraries/Keyboard/Keyboard.cpp.o: in function `_ZN9Keyboard_10sendReportEP9KeyReport':
/home/xxx/Arduino/hardware/pico/rp2040/libraries/Keyboard/src/Keyboard.cpp:43: undefined reference to `_Z13__USBHIDReadyv'
/home/xxx/Arduino/hardware/pico/rp2040/system/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld: /home/xxx/Arduino/hardware/pico/rp2040/libraries/Keyboard/src/Keyboard.cpp:44: undefined reference to `_Z24__USBGetKeyboardReportIDv'
  1. I see, it is not that easy. I've experimented with Adafruit TinyUSB, .begin(); .detach(); .attach(); and I got a re-enumeration with CDC & a different HID report descriptor. But changing back was not successful. I'll use Adafruit TinyUSB and setting the report descriptor once at startup, without the possibility to change it without a reset. THX for the advice.

Example .ino sketch, using Adafruit TinyUSB + KeyboardBLE library, not compiling. Tools->USB Stack: "Adafruit TinyUSB" Tools->IP/Bluetooth Stack: "IPV4+Bluetooth" AdafruitTinyUSB_BLE.txt

benjaminaigner avatar Jan 30 '24 13:01 benjaminaigner

Closing this as it's not feasible with the current architecture using the built-in setup. TinyUSB can provide some (unstable?) utility here, but in this and other issues we've had reports that the USB re-enumeration by the host just isn't consistently reliable. :(

earlephilhower avatar Jun 24 '24 22:06 earlephilhower