earlephilhower / arduino-pico

Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
GNU Lesser General Public License v2.1
2.03k stars 423 forks source link

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

Closed benjaminaigner closed 4 months ago

benjaminaigner commented 9 months ago

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:

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

earlephilhower commented 9 months ago

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.

benjaminaigner commented 9 months ago

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'
  2. 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

earlephilhower commented 4 months ago

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. :(