2
\$\begingroup\$

Why do I need 5 commands to declare a Usage Page (Button)?

If these commands are not for the button, then what are they for?

  0x05, 0x01,        /* Usage Page (Generic Desktop Ctrls)     */
  0x09, 0x02,        /* Usage (Mouse)                          */
  0xA1, 0x01,        /* Collection (Application)               */
  0x09, 0x01,        /*   Usage (Pointer)                      */
  0xA1, 0x00,        /*   Collection (Physical)                */
  0x05, 0x09,        /*     Usage Page (Button)                */

For coordinates this code is used

  0x05, 0x01,        /*     Usage Page (Generic Desktop Ctrls) */
  0x09, 0x30,        /*     Usage (X)                          */
  0x09, 0x31,        /*     Usage (Y)                          */

This is the standard USB report descriptor for the mouse. I copied it from auto-generated code.

__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
  0x05, 0x01,        /* Usage Page (Generic Desktop Ctrls)     */
  0x09, 0x02,        /* Usage (Mouse)                          */
  0xA1, 0x01,        /* Collection (Application)               */
  0x09, 0x01,        /*   Usage (Pointer)                      */
  0xA1, 0x00,        /*   Collection (Physical)                */
  0x05, 0x09,        /*     Usage Page (Button)                */
  0x19, 0x01,        /*     Usage Minimum (0x01)               */
  0x29, 0x03,        /*     Usage Maximum (0x03)               */
  0x15, 0x00,        /*     Logical Minimum (0)                */
  0x25, 0x01,        /*     Logical Maximum (1)                */
  0x95, 0x03,        /*     Report Count (3)                   */
  0x75, 0x01,        /*     Report Size (1)                    */
  0x81, 0x02,        /*     Input (Data,Var,Abs)               */
  0x95, 0x01,        /*     Report Count (1)                   */
  0x75, 0x05,        /*     Report Size (5)                    */
  0x81, 0x01,        /*     Input (Const,Array,Abs)            */
  0x05, 0x01,        /*     Usage Page (Generic Desktop Ctrls) */
  0x09, 0x30,        /*     Usage (X)                          */
  0x09, 0x31,        /*     Usage (Y)                          */
  0x09, 0x38,        /*     Usage (Wheel)                      */
  0x15, 0x81,        /*     Logical Minimum (-127)             */
  0x25, 0x7F,        /*     Logical Maximum (127)              */
  0x75, 0x08,        /*     Report Size (8)                    */
  0x95, 0x03,        /*     Report Count (3)                   */
  0x81, 0x06,        /*   Input (Data,Var,Rel)                 */
  0xC0,              /*   End Collection                       */
  0x09, 0x3C,        /*   Usage (Motion Wakeup)                */
  0x05, 0xFF,        /*   Usage Page (Reserved 0xFF)           */
  0x09, 0x01,        /*   Usage (0x01)                         */
  0x15, 0x00,        /*   Logical Minimum (0)                  */
  0x25, 0x01,        /*   Logical Maximum (1)                  */
  0x75, 0x01,        /*   Report Size (1)                      */
  0x95, 0x02,        /*   Report Count (2)                     */
  0xB1, 0x22,        /*   Feature (Data,Var,Abs,NoWrp)         */
  0x75, 0x06,        /*   Report Size (6)                      */
  0x95, 0x01,        /*   Report Count (1)                     */
  0xB1, 0x01,        /*   Feature (Const,Array,Abs,NoWrp)      */
  0xC0               /* End Collection                         */
};

In the HID Descriptor Tool, I declared the Usage Page (Button) in one line and did not receive any warnings.

HID Descriptor Tool interface image

enter image description here

There is also an example of using the button here. Only one command is used: Usage Page (Button) https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/

The following is written here https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/

Ah but we are not done, in order to make the computer know that this is a mouse, we do

USAGE_PAGE (Generic Desktop)
USAGE (Mouse)
COLLECTION (Application)
    USAGE (Pointer)
    COLLECTION (Physical)
    
    ... What we wrote already goes here
    
    END COLLECTION
END COLLECTION

This is done so that the computer understands that this is a mouse button, and not a button, for example, a joystick. Ok this code can be used for that

  0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
  0x09, 0x02, /* Usage (Mouse) */

What is this code for?

USAGE (Pointer)
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

A HID mouse will always have an X/Y pointer.

If you want a minimal HID device with only buttons, you can implement it as a HID joystick or gamepad.

Example:

const uint8_t report_descr_hid_joystick_btn3[] =
{
    UsagePage(USB_HID_GENERIC_DESKTOP),
    Usage(USB_HID_JOYSTICK),
    Collection(USB_HID_APPLICATION),

    // 3 buttons
    UsagePage(USB_HID_BUTTONS),
    UsageMinimum(1),
    UsageMaximum(3),
    LogicalMinimum(0),
    LogicalMaximum(1),
    PhysicalMinimum(0),
    PhysicalMaximum(1),
    ReportSize(1),
    ReportCount(3),
    Input(USB_HID_INPUT_DATA | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS),
    // padding
    ReportSize(5),
    ReportCount(1),
    Input(USB_HID_INPUT_CONSTANT | USB_HID_INPUT_VARIABLE | USB_HID_INPUT_ABS),

    EndCollection
};

Edit

Why does this construction have exactly this sequence?

Usage Page (Generic Desktop Ctrls), Usage (Mouse), Collection (Application), Usage (Pointer), Collection (Physical).

If I do this sequence, the code stops working:

Usage Page (Generic Desktop Ctrls), Usage (Mouse), Usage (Pointer), Collection (Application), Collection (Physical).

This has something to do with collections, but I don’t understand why this is necessary.

Usage Page (Generic Desktop Ctrls) 
Usage (Mouse) 
Usage (Pointer) 
Collection (Application) 
Collection (Physical)

Here Usage (Pointer) is wrong because it's overriding Usage (Mouse). And HID doesn't support Usage (Pointer) within the context of Usage Page (Generic Desktop Ctrls).

\$\endgroup\$
1
  • \$\begingroup\$ Why does this construction have exactly this sequence? Usage Page (Generic Desktop Ctrls), Usage (Mouse), Collection (Application), Usage (Pointer), Collection (Physical). If I do this sequence, the code stops working: Usage Page (Generic Desktop Ctrls), Usage (Mouse), Usage (Pointer), Collection (Application), Collection (Physical). This has something to do with collections, but I don’t understand why this is necessary. \$\endgroup\$
    – stm
    Sep 15, 2023 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.