8000 Add absolute mouse support (#1342) · MRemy2/arduino-pico@0963611 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0963611

Browse files
Add absolute mouse support (earlephilhower#1342)
Fixes earlephilhower#1338 To be revisited when TinyUSB native support is added and picked up in the SDK
1 parent 00644db commit 0963611

File tree

20 files changed

+900
-30
lines changed

20 files changed

+900
-30
lines changed
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "pico/usb_reset_interface.h"
3737
#include "hardware/watchdog.h"
3838
#include "pico/bootrom.h"
39+
#include "sdkoverride/tusb_absmouse.h"
3940
#include <device/usbd_pvt.h>
4041

4142
// Big, global USB mutex, shared with all USB devices to make sure we don't
@@ -100,15 +101,15 @@ const uint8_t *tud_descriptor_device_cb(void) {
100101
.iSerialNumber = USBD_STR_SERIAL,
101102
.bNumConfigurations = 1
102103
};
103-
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick && !__USBInstallMassStorage) {
104+
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallAbsoluteMouse && !__USBInstallJoystick && !__USBInstallMassStorage) {
104105
// Can use as-is, this is the default USB case
105106
return (const uint8_t *)&usbd_desc_device;
106107
}
107108
// Need a multi-endpoint config which will require changing the PID to help Windows not barf
108109
if (__USBInstallKeyboard) {
109110
usbd_desc_device.idProduct |= 0x8000;
110111
}
111-
if (__USBInstallMouse) {
112+
if (__USBInstallMouse || __USBInstallAbsoluteMouse) {
112113
usbd_desc_device.idProduct |= 0x4000;
113114
}
114115
if (__USBInstallJoystick) {
@@ -137,7 +138,7 @@ int __USBGetJoystickReportID() {
137138
if (__USBInstallKeyboard) {
138139
i++;
139140
}
140-
if (__USBInstallMouse) {
141+
if (__USBInstallMouse || __USBInstallAbsoluteMouse) {
141142
i++;
142143
}
143144
return i;
@@ -156,6 +157,7 @@ static uint8_t *GetDescHIDReport(int *len) {
156157
void __SetupDescHIDReport() {
157158
//allocate memory for the HID report descriptors. We don't use them, but need the size here.
158159
uint8_t desc_hid_report_mouse[] = { TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1)) };
160+
uint8_t desc_hid_report_absmouse[] = { TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(1)) };
159161
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(1)) };
160162
uint8_t desc_hid_report_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)), 8000 TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(2)) };
161163
int size = 0;
@@ -166,6 +168,8 @@ void __SetupDescHIDReport() {
166168
}
167169
if (__USBInstallMouse) {
168170
size += sizeof(desc_hid_report_mouse);
171+
} else if (__USBInstallAbsoluteMouse) {
172+
size += sizeof(desc_hid_report_absmouse);
169173
}
170174
if (__USBInstallJoystick) {
171175
size += sizeof(desc_hid_report_joystick);
@@ -199,6 +203,14 @@ void __SetupDescHIDReport() {
199203
} else {
200204
memcpy(__hid_report, desc_hid_report_mouse, sizeof(desc_hid_report_mouse));
201205
}
206+
} else if (__USBInstallAbsoluteMouse) {
207+
//determine if we need an offset (USB keyboard is installed)
208+
if (__USBInstallKeyboard) {
209+
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(3)) };
210+
memcpy(__hid_report + sizeof(desc_hid_report_keyboard), desc_local, sizeof(desc_local));
211+
} else {
212+
memcpy(__hid_report, desc_hid_report_absmouse, sizeof(desc_hid_report_absmouse));
213+
}
202214
}
203215

204216
//3.) joystick descriptor. 2 additional checks are necessary for mouse and/or keyboard
@@ -212,6 +224,9 @@ void __SetupDescHIDReport() {
212224
if (__USBInstallMouse) {
213225
reportid++;
214226
offset += sizeof(desc_hid_report_mouse);
227+
} else if (__USBInstallAbsoluteMouse) {
228+
reportid++;
229+
offset += sizeof(desc_hid_report_absmouse);
215230
}
216231
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(reportid)) };
217232
memcpy(__hid_report + offset, desc_local, sizeof(desc_local));
@@ -235,7 +250,7 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
235250

236251
void __SetupUSBDescriptor() {
237252
if (!usbd_desc_cfg) {
238-
bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallJoystick;
253+
bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallAbsoluteMouse || __USBInstallJoystick;
239254

240255
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMassStorage ? 1 : 0);
241256

cores/rp2040/RP2040USB.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@
2323

2424
// Weak function definitions for each type of endpoint
2525
extern void __USBInstallSerial() __attribute__((weak));
26+
2627
extern void __USBInstallKeyboard() __attribute__((weak));
28+
2729
extern void __USBInstallJoystick() __attribute__((weak));
30+
31+
// One or the other allowed, not both
2832
extern void __USBInstallMouse() __attribute__((weak));
33+
extern void __USBInstallAbsoluteMouse() __attribute__((weak));
34+
2935
extern void __USBInstallMassStorage() __attribute__((weak));
3036

3137
// Big, global USB mutex, shared with all USB devices to make sure we don't
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
Expost absolute mouse HID descriptor and report
3+
Taken from @tobozo PR https://github.com/hathach/tinyusb/pull/1363
4+
TODO - remove once that PR merged with TinyUSB
5+
6+
Copyright (c) 2023 Earle F. Philhower, III <earlephilhower@yahoo.com>
7+
8+
This library is free software; you can redistribute it and/or
9+
modify it under the terms of the GNU Lesser General Public
10+
License as published by the Free Software Foundation; either
11+
version 2.1 of the License, or (at your option) any later version.
12+
13+
This library is distributed in the hope that it will be useful,
14+
but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
Lesser General Public License for more details.
17+
18+
You should have received a copy of the GNU Lesser General Public
19+
License along with this library; if not, write to the Free Software
20+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21+
*/
22+
23+
#pragma once
24+
25+
#include "tusb.h"
26+
#include "class/hid/hid_device.h"
27+
28+
// Absolute Mouse: same as the Standard (relative) Mouse Report but
29+
// with int16_t instead of int8_t for X and Y coordinates.
30+
typedef struct TU_ATTR_PACKED {
31+
uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */
32+
int16_t x; /**< Current x position of the mouse. */
33+
int16_t y; /**< Current y position of the mouse. */
34+
int8_t wheel; /**< Current delta wheel movement on the mouse. */
35+
int8_t pan; // using AC Pan
36+
} hid_abs_mouse_report_t;
37+
38+
39+
// Absolute Mouse Report Descriptor Template
40+
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
41+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
42+
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
43+
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
44+
/* Report ID if any */\
45+
__VA_ARGS__ \
46+
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
47+
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
48+
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
49+
HID_USAGE_MIN ( 1 ) ,\
50+
HID_USAGE_MAX ( 5 ) ,\
51+
HID_LOGICAL_MIN ( 0 ) ,\
52+
HID_LOGICAL_MAX ( 1 ) ,\
53+
/* Left, Right, Middle, Backward, Forward buttons */ \
54+
HID_REPORT_COUNT( 5 ) ,\
55+
HID_REPORT_SIZE ( 1 ) ,\
56+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
57+
/* 3 bit padding */ \
58+
HID_REPORT_COUNT( 1 ) ,\
59+
HID_REPORT_SIZE ( 3 ) ,\
60+
HID_INPUT ( HID_CONSTANT ) ,\
61+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
62+
/* X, Y absolute position [0, 32767] */ \
63+
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
64+
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
65+
HID_LOGICAL_MIN ( 0x00 ) ,\
66+
HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\
67+
HID_REPORT_SIZE ( 16 ) ,\
68+
HID_REPORT_COUNT ( 2 ) ,\
69+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
70+
/* Vertical wheel scroll [-127, 127] */ \
71+
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
72+
HID_LOGICAL_MIN ( 0x81 ) ,\
73+
HID_LOGICAL_MAX ( 0x7f ) ,\
74+
HID_REPORT_COUNT( 1 ) ,\
75+
HID_REPORT_SIZE ( 8 ) ,\
76+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
77+
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
78+
/* Horizontal wheel scroll [-127, 127] */ \
79+
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
80+
HID_LOGICAL_MIN ( 0x81 ), \
81+
HID_LOGICAL_MAX ( 0x7f ), \
82+
HID_REPORT_COUNT( 1 ), \
83+
HID_REPORT_SIZE ( 8 ), \
84+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
85+
HID_COLLECTION_END , \
86+
HID_COLLECTION_END \
87+
88+
89+
static inline bool tud_hid_abs_mouse_report(uint8_t report_id,
90+
uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) {
91+
hid_abs_mouse_report_t report = {
92+
.buttons = buttons,
93+
.x = x,
94+
.y = y,
95+
.wheel = vertical,
96+
.pan = horizontal
97+
};
98+
99+
return tud_hid_n_report(0, report_id, &report, sizeof(report));
100+
}
101+

libraries/MouseAbsolute/README.adoc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
:repository-owner: arduino-libraries
2+
:repository-name: Mouse
3+
4+
= {repository-name} Library for Arduino =
5+
6+
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml/badge.svg["Check Arduino status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-arduino.yml"]
7+
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml/badge.svg["Compile Examples status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/compile-examples.yml"]
8+
image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml/badge.svg["Spell Check status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/spell-check.yml"]
9+
10+
This library allows an Arduino board with USB capabilities to act as a Mouse.
11+
12+
For more information about this library please visit us at
13+
https://www.arduino.cc/reference/en/language/functions/usb/mouse/
14+
15+
== License ==
16+
17+
Copyright (c) Arduino LLC. All right reserved.
18+
19+
This library is free software; you can redistribute it and/or
20+
modify it under the terms of the GNU Lesser General Public
21+
License as published by the Free Software Foundation; either
22+
version 2.1 of the License, or (at your option) any later version.
23+
24+
This library is distributed in the hope that it will be useful,
25+
but WITHOUT ANY WARRANTY; without even the implied warranty of
26+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27+
Lesser General Public License for more details.
28+
29+
You should have received a copy of the GNU Lesser General Public
30+
License along with this library; if not, write to the Free Software
31+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

0 commit comments

Comments
 (0)
0