Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

16-bit relative USB mouse support #9232

Open
1 task done
wareya opened this issue Feb 10, 2024 · 4 comments
Open
1 task done

16-bit relative USB mouse support #9232

wareya opened this issue Feb 10, 2024 · 4 comments
Assignees
Labels
Status: To be implemented Selected for Development Type: Feature request Feature request for Arduino ESP32

Comments

@wareya
Copy link

wareya commented Feb 10, 2024

Related area

Gaming Mouse

Hardware specification

ESP32-S2

Is your feature request related to a problem?

I'm making a gaming mouse using an ESP32-S2-DevKitM-1U. Modern gaming mice all report at 1000hz with 16 bits of motion per frame.

The HID USB mouse implementation only support 8 bits of motion data per frame: https://github.com/espressif/arduino-esp32/blob/master/libraries/USB/src/USBHIDMouse.cpp

At 125hz and 800dpi, this limits the max tracking speed to 0.5 meters per second. At 1000hz, it's 4 meters per second, which sounds like a lot, but isn't enough for game genres that involve very fast flicking. At higher DPIs, the max tracking speed is reduced; 800dpi isn't really enough to run a HiDPI monitor any more, so "silly" DPIs like 1600, 3200, etc. are increasingly common.

TinyUSB doesn't seem to have a report type for 16-bit mice out of the box, but someone seems to have gotten it working anyway: hathach/tinyusb#366

Describe the solution you'd like

Add a second class that uses 16-bit motion deltas and a proper report descriptor.

Describe alternatives you've considered

Overclocking above 1000hz (e.g. to 8000hz) only works on "High-Speed" USB devices, not "Full-Speed" as is usually used for keyboards and mice.

Additional context

No response

I have checked existing list of Feature requests and the Contribution Guide

  • I confirm I have checked existing list of Feature requests and Contribution Guide.
@wareya wareya added the Type: Feature request Feature request for Arduino ESP32 label Feb 10, 2024
@wareya
Copy link
Author

wareya commented Feb 12, 2024

This header file works with the 3.0.0-a version of the ardunio esp32 support library:

#include <USB.h>
#include <USBHID.h>
#include <USBHIDMouse.h>

#define TUD_HID_REPORT_DESC_MOUSE16(...) \
  HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP      )                   ,\
  HID_USAGE      ( HID_USAGE_DESKTOP_MOUSE     )                   ,\
  HID_COLLECTION ( HID_COLLECTION_APPLICATION  )                   ,\
    /* Report ID if any */\
    __VA_ARGS__ \
    HID_USAGE      ( HID_USAGE_DESKTOP_POINTER )                   ,\
    HID_COLLECTION ( HID_COLLECTION_PHYSICAL   )                   ,\
      HID_USAGE_PAGE  ( HID_USAGE_PAGE_BUTTON  )                   ,\
        HID_USAGE_MIN   ( 1                                      ) ,\
        HID_USAGE_MAX   ( 5                                      ) ,\
        HID_LOGICAL_MIN ( 0                                      ) ,\
        HID_LOGICAL_MAX ( 1                                      ) ,\
        /* Left, Right, Middle, Backward, Forward buttons */ \
        HID_REPORT_COUNT( 5                                      ) ,\
        HID_REPORT_SIZE ( 1                                      ) ,\
        HID_INPUT       ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
        /* 3 bit padding */ \
        HID_REPORT_COUNT( 1                                      ) ,\
        HID_REPORT_SIZE ( 3                                      ) ,\
        HID_INPUT       ( HID_CONSTANT                           ) ,\
      HID_USAGE_PAGE  ( HID_USAGE_PAGE_DESKTOP )                   ,\
        /* X, Y position [-32767, 32767] */ \
        HID_USAGE       ( HID_USAGE_DESKTOP_X                    ) ,\
        HID_USAGE       ( HID_USAGE_DESKTOP_Y                    ) ,\
        HID_LOGICAL_MIN_N ( 0x8001, 2                            ) ,\
        HID_LOGICAL_MAX_N ( 0x7fff, 2                            ) ,\
        HID_REPORT_COUNT( 2                                      ) ,\
        HID_REPORT_SIZE ( 16                                     ) ,\
        HID_INPUT       ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
        /* Verital wheel scroll [-127, 127] */ \
        HID_USAGE       ( HID_USAGE_DESKTOP_WHEEL                )  ,\
        HID_LOGICAL_MIN ( 0x81                                   )  ,\
        HID_LOGICAL_MAX ( 0x7f                                   )  ,\
        HID_REPORT_COUNT( 1                                      )  ,\
        HID_REPORT_SIZE ( 8                                      )  ,\
        HID_INPUT       ( HID_DATA | HID_VARIABLE | HID_RELATIVE )  ,\
      HID_USAGE_PAGE  ( HID_USAGE_PAGE_CONSUMER ), \
       /* Horizontal wheel scroll [-127, 127] */ \
        HID_USAGE_N     ( HID_USAGE_CONSUMER_AC_PAN, 2           ), \
        HID_LOGICAL_MIN ( 0x81                                   ), \
        HID_LOGICAL_MAX ( 0x7f                                   ), \
        HID_REPORT_COUNT( 1                                      ), \
        HID_REPORT_SIZE ( 8                                      ), \
        HID_INPUT       ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
    HID_COLLECTION_END                                            , \
  HID_COLLECTION_END

static const uint8_t rel16_mouse_report_descriptor[] = {
    TUD_HID_REPORT_DESC_MOUSE16(HID_REPORT_ID(HID_REPORT_ID_MOUSE))
};

typedef struct TU_ATTR_PACKED
{
    uint8_t buttons;
    int16_t  x;
    int16_t  y;
    int8_t  wheel;
    int8_t  pan;
} hid_mouse_report_16_t;

HIDMouseType_t HIDMouseRel16 = { HID_MOUSE_RELATIVE, rel16_mouse_report_descriptor, sizeof(rel16_mouse_report_descriptor), sizeof(hid_mouse_report_16_t) };

class USBHIDRelativeMouse16: public USBHIDMouseBase {
public:
    USBHIDRelativeMouse16(void): USBHIDMouseBase(&HIDMouseRel16) { }
    void move(int16_t x, int16_t y, int8_t wheel = 0, int8_t pan = 0) {
        hid_mouse_report_16_t report = {
            .buttons = _buttons,
            .x       = x,
            .y       = y,
            .wheel   = wheel,
            .pan     = pan
        };
        sendReport(report);
    }
    void click(uint8_t b = MOUSE_LEFT) override {
        _buttons = b;
        move(0,0);
        _buttons = 0;
        move(0,0);
    }
    void buttons(uint8_t b) override {
        if (b != _buttons) {
            _buttons = b;
            move(0,0);
        }
    }
};

Based on USBHIDMouse.cpp.

@SuGlider
Copy link
Collaborator

SuGlider commented Feb 13, 2024

@wareya - It is already within Arduino Core 3.0.0-Alpha3. You can test it.

Looking in master branch I can see that
https://github.com/espressif/arduino-esp32/commits/master/libraries/USB/src/tusb_hid_mouse.h
has already 2 bytes for X,Y absolute mouse feature.

Check the PR from #8831

@SuGlider SuGlider self-assigned this Feb 13, 2024
@wareya
Copy link
Author

wareya commented Feb 13, 2024

Absolute mouse and relative mouse support is different. This is for 16-bit relative mouse support.

@SuGlider
Copy link
Collaborator

Thanks for noting that. You are right. Absolute has a different report descriptor.
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) --- HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE )

I'll work a way to add this feature.

@SuGlider SuGlider added Status: To be implemented Selected for Development and removed Status: Solved labels Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: To be implemented Selected for Development Type: Feature request Feature request for Arduino ESP32
Projects
None yet
Development

No branches or pull requests

2 participants