HID usb device example dev_hid_composite does not seem to work for gamepads unless you shorten the HID descriptor

Open
#618 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
42/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
c
Domain
embedded-iot

Research direction

Start with usb_descriptors.c and the hid_task path in the dev_hid_composite example, then reproduce the reported behavior on an RP2040 Pico with Windows Game Controllers. Compare the full composite descriptor with the gamepad-only descriptor; done means the gamepad report exposes and registers button, HAT, and analog-axis input without removing the other reports.

Written by the indexing model from the issue text.

Description

I discovered something unusual today. I was playing around with the dev_hid_composite and noticed that if I tried sending gamepad data by simply changing the line in hid_task that reads send_hid_report(REPORT_ID_KEYBOARD, btn); to send_hid_report(REPORT_ID_GAMEPAD, btn); that it will compile and run, but when I look at the device in the Windows Game Controllers settings, it shows only 32 buttons and none of them show up as pressed when the code attempts to press button 1. It doesn't show the HAT or Analog Axes at all.

Image

I did find a workaround. If you change the HID descriptor to exclude the HID reports for everything but the HID gamepad report by changing these lines in usb_descriptors.c:

//--------------------------------------------------------------------+
// HID Report Descriptor
//--------------------------------------------------------------------+

uint8_t const desc_hid_report[] =
{
    TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD         )),
    TUD_HID_REPORT_DESC_MOUSE   ( HID_REPORT_ID(REPORT_ID_MOUSE            )),
    TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
    TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD          ))
};

to this:

//--------------------------------------------------------------------+
// HID Report Descriptor
//--------------------------------------------------------------------+

uint8_t const desc_hid_report[] =
{
    TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD          ))
};

Then everything works as it should. It seems like the HID descriptor may be too long for the RP2040 pico.
If anyone is having issues creating an HID device using this example code, then they may want to try shortening the HID descriptor.

My dev setup:
Pi Pico RP2040
Windows 11 x64 running VSCode with the Pi Pico extension
sdkVersion 2.1.0
toolchainVersion 13_3_Rel1
picotoolVersion 2.1.0
TinyUSB commit 5217cee5d (this is what was downloaded by the Pi Pico extension)

Dominant language
C
Stars
3.9k
Forks
1k
Avg merge
1d 16h
Merged PRs (30d)
1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from raspberrypi/pico-examples

All issues in raspberrypi/pico-examples

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.