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

Joystick 16-bit support #10439

Merged
merged 8 commits into from
Oct 3, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/feature_joystick.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
```

### 16-bit axis values

For use-cases where a higher joystick-precision is desired, it is possible to change axis precision to 16-bit. To use axis values from -32767 to 32767, add the following line to your config.h:

``` #define JOYSTICK_16_BIT ```

This setting works for virtual axes as well as analog axis reading using
`JOYSTICK_AXIS_IN(...)`, `JOYSTICK_AXIS_IN_OUT(...)` or `JOYSTICK_AXIS_IN_OUT_GROUND(...)`.
### Triggering Joystick Buttons

Joystick buttons are normal Quantum keycodes, defined as `JS_BUTTON0` to `JS_BUTTON31`, depending on the number of buttons you have configured.
Expand Down
16 changes: 12 additions & 4 deletions quantum/process_keycode/process_joystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,28 @@ bool process_joystick_analogread_quantum() {
int16_t axis_val = joystick_axes[axis_index].mid_digit;
# endif

# ifndef JOYSTICK_16_BIT
int js_min = -127;
int js_max = 127;
# else
int js_min = -32767;
int js_max = 32767;
# endif

// test the converted value against the lower range
int32_t ref = joystick_axes[axis_index].mid_digit;
int32_t range = joystick_axes[axis_index].min_digit;
int32_t ranged_val = ((axis_val - ref) * -127) / (range - ref);
int32_t ranged_val = ((axis_val - ref) * js_min) / (range - ref);
fauxpark marked this conversation as resolved.
Show resolved Hide resolved

if (ranged_val > 0) {
// the value is in the higher range
range = joystick_axes[axis_index].max_digit;
ranged_val = ((axis_val - ref) * 127) / (range - ref);
ranged_val = ((axis_val - ref) * js_max) / (range - ref);
fauxpark marked this conversation as resolved.
Show resolved Hide resolved
}

// clamp the result in the valid range
ranged_val = ranged_val < -127 ? -127 : ranged_val;
ranged_val = ranged_val > 127 ? 127 : ranged_val;
ranged_val = ranged_val < js_min ? js_min : ranged_val;
ranged_val = ranged_val > js_max ? js_max : ranged_val;
fauxpark marked this conversation as resolved.
Show resolved Hide resolved

if (ranged_val != joystick_status.axes[axis_index]) {
joystick_status.axes[axis_index] = ranged_val;
Expand Down
6 changes: 5 additions & 1 deletion tmk_core/common/report.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,11 @@ typedef struct {

typedef struct {
#if JOYSTICK_AXES_COUNT > 0
int8_t axes[JOYSTICK_AXES_COUNT];
#ifndef JOYSTICK_16_BIT
int8_t axes[JOYSTICK_AXES_COUNT];
#else
int16_t axes[JOYSTICK_AXES_COUNT];
#endif
#endif

#if JOYSTICK_BUTTON_COUNT > 0
Expand Down
8 changes: 8 additions & 0 deletions tmk_core/protocol/usb_descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,19 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = {
HID_RI_USAGE(8, 0x35), // Rz
# endif
# if JOYSTICK_AXES_COUNT >= 1
# ifndef JOYSTICK_16_BIT
HID_RI_LOGICAL_MINIMUM(8, -127),
HID_RI_LOGICAL_MAXIMUM(8, 127),
HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
# else
HID_RI_LOGICAL_MINIMUM(16, -32767),
HID_RI_LOGICAL_MAXIMUM(16, 32767),
HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
HID_RI_REPORT_SIZE(8, 0x10),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
# endif
# endif

# if JOYSTICK_BUTTON_COUNT >= 1
Expand Down