Skip to content

Commit bd902a9

Browse files
Add true 10- and 16-bit joystick modes (#2276)
Fixes #2275 Adds `Joystick.use10bit` and `Joystick.use16bit` methods. 10-bit is unsigned from 0...1023 while 16-bit is signed -32767..32767. Defines a new HID descriptor to support the increased resolution.
1 parent 372fef0 commit bd902a9

File tree

8 files changed

+78
-12
lines changed

8 files changed

+78
-12
lines changed

cores/rp2040/RP2040USB.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,52 @@ static uint8_t *GetDescHIDReport(int *len) {
155155
return __hid_report;
156156
}
157157

158+
#define TUD_HID_REPORT_DESC_GAMEPAD16(...) \
159+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
160+
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
161+
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
162+
/* Report ID if any */\
163+
__VA_ARGS__ \
164+
/* 16 bit X, Y, Z, Rz, Rx, Ry (min -32767, max 32767 ) */ \
165+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
166+
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
167+
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
168+
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
169+
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
170+
HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\
171+
HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\
172+
HID_LOGICAL_MIN_N ( -32767, 2 ) ,\
173+
HID_LOGICAL_MAX_N ( 32767, 2 ) ,\
174+
HID_REPORT_COUNT ( 6 ) ,\
175+
HID_REPORT_SIZE ( 16 ) ,\
176+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
177+
/* 8 bit DPad/Hat Button Map */ \
178+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
179+
HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\
180+
HID_LOGICAL_MIN ( 1 ) ,\
181+
HID_LOGICAL_MAX ( 8 ) ,\
182+
HID_PHYSICAL_MIN ( 0 ) ,\
183+
HID_PHYSICAL_MAX_N ( 315, 2 ) ,\
184+
HID_REPORT_COUNT ( 1 ) ,\
185+
HID_REPORT_SIZE ( 8 ) ,\
186+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
187+
/* 32 bit Button Map */ \
188+
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
189+
HID_USAGE_MIN ( 1 ) ,\
190+
HID_USAGE_MAX ( 32 ) ,\
191+
HID_LOGICAL_MIN ( 0 ) ,\
192+
HID_LOGICAL_MAX ( 1 ) ,\
193+
HID_REPORT_COUNT ( 32 ) ,\
194+
HID_REPORT_SIZE ( 1 ) ,\
195+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
196+
HID_COLLECTION_END \
197+
198+
158199
void __SetupDescHIDReport() {
159200
//allocate memory for the HID report descriptors. We don't use them, but need the size here.
160201
uint8_t desc_hid_report_mouse[] = { TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1)) };
161202
uint8_t desc_hid_report_absmouse[] = { TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(1)) };
162-
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(1)) };
203+
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD16(HID_REPORT_ID(1)) };
163204
uint8_t desc_hid_report_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)), TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(2)) };
164205
int size = 0;
165206

@@ -229,7 +270,7 @@ void __SetupDescHIDReport() {
229270
reportid++;
230271
offset += sizeof(desc_hid_report_absmouse);
231272
}
232-
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(reportid)) };
273+
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD16(HID_REPORT_ID(reportid)) };
233274
memcpy(__hid_report + offset, desc_local, sizeof(desc_local));
234275
}
235276
}

libraries/Joystick/docs/api.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,6 @@ Switch axis value range between 10bit and 8bit.
156156
* Default: 10bit, range for an axis from 0 to 1023
157157
* 8bit mode: range from -127 to 127.
158158

159-
__Note:__ due to the gamepad descriptor of tinyUSB, the maximum range is -127/127. 10bit mode enables mapping, not a higher resolution.
160-
161159

162160
#### Syntax
163161

@@ -216,6 +214,11 @@ void loop() {
216214
* [Joystick.sliderRight()](#joysticksliderright)
217215

218216

217+
### `Joystick.use10bit()`
218+
### `Joystick.use16bit()`
219+
220+
Set axis value range to 10-bit (0...1024) or 16-bit (-32767...32767).
221+
219222
### `Joystick.useManualSend()`
220223

221224
To fully control transmitting the USB-HID reports, enable manual sending.

libraries/Joystick/examples/Joystick-AllFunctions/Joystick-AllFunctions.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ void loop() {
3333
}
3434
Joystick.useManualSend(false);
3535

36+
Joystick.use10bit();
3637
// Iterate all joystick axis
37-
// Note: although you can use 0-1023 here (10bit), internally 8bits are used (-127 to 127)
3838
Serial.println("Joystick X");
3939
for (uint16_t i = 0; i < 1023; i++) {
4040
Joystick.X(i);
@@ -74,7 +74,7 @@ void loop() {
7474
// Use int8 mode for the axis.
7575
// Note: hat is not used differently.
7676
Serial.println("Now all axis in 8bit mode, -127 to 127");
77-
Joystick.use8bit(true);
77+
Joystick.use8bit();
7878
Serial.println("Joystick X");
7979
for (int16_t i = -127; i < 128; i++) {
8080
Joystick.X(i);
@@ -105,6 +105,6 @@ void loop() {
105105
Joystick.sliderRight(i);
106106
delay(2);
107107
} Joystick.sliderRight(0);
108-
Joystick.use8bit(false);
108+
Joystick.use10bit();
109109
}
110110
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <Joystick.h>
2+
3+
// Set 1KHz polling frequency (1000/second)
4+
int usb_hid_poll_interval = 1;
5+
6+
void setup() {
7+
Joystick.use16bit();
8+
Joystick.begin();
9+
}
10+
11+
void loop() {
12+
static int16_t delta = 1;
13+
static int16_t p = 0;
14+
if (p == 32767) {
15+
delta = -1;
16+
} else if (p == -32767) {
17+
delta = 1;
18+
}
19+
p += delta;
20+
Joystick.X(p);
21+
Joystick.Y(-p);
22+
}

libraries/JoystickBLE/src/JoystickBLE.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void JoystickBLE_::setBattery(int lvl) {
6565

6666
void JoystickBLE_::send_now() {
6767
//insert report ID; not part of the hid_gamepad_report_t
68-
uint8_t *report = (uint8_t *)malloc(sizeof(hid_gamepad_report_t) +1);
68+
uint8_t *report = (uint8_t *)malloc(sizeof(hid_gamepad16_report_t) + 1);
6969
if (report) {
7070
report[0] = __BLEGetJoystickReportID();
7171
memcpy(&report[1], (uint8_t*)&data, sizeof(data));

libraries/KeyboardBLE/src/KeyboardBLE.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ void KeyboardBLE_::sendReport(KeyReport* keys) {
6868
memcpy(data.keycode, keys->keys, sizeof(data.keycode));
6969

7070
//stitch in report id
71-
static uint8_t report[sizeof(hid_keyboard_report_t) +1];
71+
static uint8_t report[sizeof(hid_keyboard_report_t) + 1];
7272
report[0] = __BLEGetKeyboardReportID();
7373
memcpy(&report[1], (uint8_t*)&data, sizeof(hid_keyboard_report_t));
74-
PicoBluetoothBLEHID.send(&report, sizeof(hid_keyboard_report_t) +1);
74+
PicoBluetoothBLEHID.send(&report, sizeof(hid_keyboard_report_t) + 1);
7575
}
7676

7777
void KeyboardBLE_::sendConsumerReport(uint16_t key) {

libraries/MouseBLE/src/MouseBLE.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void MouseBLE_::setAbsolute(bool absolute) {
6868
}
6969

7070
void MouseBLE_::move(int x, int y, signed char wheel) {
71-
static uint8_t report[sizeof(hid_abs_mouse_report_t) +1];
71+
static uint8_t report[sizeof(hid_abs_mouse_report_t) + 1];
7272

7373
if (!_absolute) {
7474
hid_mouse_report_t data;

0 commit comments

Comments
 (0)