Joystick 16-bit support (#10439)
* Joystick 16-bit support * Add variable joystick axes resolution * Moved #define statements to .h files * Moved definitions to quantum/joystick.h Removed duplicate definitions from usb_descriptor.h and process_joysick.h Adjust process_joystick.c and usb_descriptor.c to use the pre-computed "JOYSTICK_RESOLUTION" value which contains the logical maximum value of a joystick axis * Cleaning up unnecessary code * Update docs/feature_joystick.md Co-authored-by: Ryan <fauxpark@gmail.com> * Workaround to joystick.h not being included to report.h * Removed unnecessary newlines, updated report.h Changed JOYSTICK_AXES_RESOLUTION conditional in report.h Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
parent
9664723595
commit
f728c249ce
5 changed files with 38 additions and 9 deletions
|
@ -141,6 +141,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Axis Resolution
|
||||||
|
|
||||||
|
By default, the resolution of each axis is 8 bit, giving a range of -127 to +127. If you need higher precision, you can increase it by defining eg. `JOYSTICK_AXES_RESOLUTION 12` in your `config.h`. The resolution must be between 8 and 16.
|
||||||
|
|
||||||
|
Note that the supported AVR MCUs have a 10-bit ADC, and 12-bit for most STM32 MCUs.
|
||||||
|
|
||||||
### Triggering Joystick Buttons
|
### 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.
|
Joystick buttons are normal Quantum keycodes, defined as `JS_BUTTON0` to `JS_BUTTON31`, depending on the number of buttons you have configured.
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "quantum.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef JOYSTICK_BUTTON_COUNT
|
#ifndef JOYSTICK_BUTTON_COUNT
|
||||||
# define JOYSTICK_BUTTON_COUNT 8
|
# define JOYSTICK_BUTTON_COUNT 8
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,9 +12,13 @@
|
||||||
# define JOYSTICK_AXES_COUNT 4
|
# define JOYSTICK_AXES_COUNT 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "quantum.h"
|
#ifndef JOYSTICK_AXES_RESOLUTION
|
||||||
|
# define JOYSTICK_AXES_RESOLUTION 8
|
||||||
|
#elif JOYSTICK_AXES_RESOLUTION < 8 || JOYSTICK_AXES_RESOLUTION > 16
|
||||||
|
# error JOYSTICK_AXES_RESOLUTION must be between 8 and 16
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#define JOYSTICK_RESOLUTION ((1L << (JOYSTICK_AXES_RESOLUTION - 1)) - 1)
|
||||||
|
|
||||||
// configure on input_pin of the joystick_axes array entry to JS_VIRTUAL_AXIS
|
// configure on input_pin of the joystick_axes array entry to JS_VIRTUAL_AXIS
|
||||||
// to prevent it from being read from the ADC. This allows outputing forged axis value.
|
// to prevent it from being read from the ADC. This allows outputing forged axis value.
|
||||||
|
|
|
@ -129,17 +129,17 @@ bool process_joystick_analogread_quantum() {
|
||||||
// test the converted value against the lower range
|
// test the converted value against the lower range
|
||||||
int32_t ref = joystick_axes[axis_index].mid_digit;
|
int32_t ref = joystick_axes[axis_index].mid_digit;
|
||||||
int32_t range = joystick_axes[axis_index].min_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) * -JOYSTICK_RESOLUTION) / (range - ref);
|
||||||
|
|
||||||
if (ranged_val > 0) {
|
if (ranged_val > 0) {
|
||||||
// the value is in the higher range
|
// the value is in the higher range
|
||||||
range = joystick_axes[axis_index].max_digit;
|
range = joystick_axes[axis_index].max_digit;
|
||||||
ranged_val = ((axis_val - ref) * 127) / (range - ref);
|
ranged_val = ((axis_val - ref) * JOYSTICK_RESOLUTION) / (range - ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clamp the result in the valid range
|
// clamp the result in the valid range
|
||||||
ranged_val = ranged_val < -127 ? -127 : ranged_val;
|
ranged_val = ranged_val < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val;
|
||||||
ranged_val = ranged_val > 127 ? 127 : ranged_val;
|
ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val;
|
||||||
|
|
||||||
if (ranged_val != joystick_status.axes[axis_index]) {
|
if (ranged_val != joystick_status.axes[axis_index]) {
|
||||||
joystick_status.axes[axis_index] = ranged_val;
|
joystick_status.axes[axis_index] = ranged_val;
|
||||||
|
|
|
@ -192,7 +192,11 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#if JOYSTICK_AXES_COUNT > 0
|
#if JOYSTICK_AXES_COUNT > 0
|
||||||
int8_t axes[JOYSTICK_AXES_COUNT];
|
# if JOYSTICK_AXES_RESOLUTION > 8
|
||||||
|
int16_t axes[JOYSTICK_AXES_COUNT];
|
||||||
|
# else
|
||||||
|
int8_t axes[JOYSTICK_AXES_COUNT];
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if JOYSTICK_BUTTON_COUNT > 0
|
#if JOYSTICK_BUTTON_COUNT > 0
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
#include "usb_descriptor.h"
|
#include "usb_descriptor.h"
|
||||||
#include "usb_descriptor_common.h"
|
#include "usb_descriptor_common.h"
|
||||||
|
|
||||||
|
#ifdef JOYSTICK_ENABLE
|
||||||
|
# include "joystick.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -308,10 +312,17 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = {
|
||||||
HID_RI_USAGE(8, 0x35), // Rz
|
HID_RI_USAGE(8, 0x35), // Rz
|
||||||
# endif
|
# endif
|
||||||
# if JOYSTICK_AXES_COUNT >= 1
|
# if JOYSTICK_AXES_COUNT >= 1
|
||||||
HID_RI_LOGICAL_MINIMUM(8, -127),
|
# if JOYSTICK_AXES_RESOLUTION == 8
|
||||||
HID_RI_LOGICAL_MAXIMUM(8, 127),
|
HID_RI_LOGICAL_MINIMUM(8, -JOYSTICK_RESOLUTION),
|
||||||
|
HID_RI_LOGICAL_MAXIMUM(8, JOYSTICK_RESOLUTION),
|
||||||
HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
|
HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
|
||||||
HID_RI_REPORT_SIZE(8, 0x08),
|
HID_RI_REPORT_SIZE(8, 0x08),
|
||||||
|
# else
|
||||||
|
HID_RI_LOGICAL_MINIMUM(16, -JOYSTICK_RESOLUTION),
|
||||||
|
HID_RI_LOGICAL_MAXIMUM(16, JOYSTICK_RESOLUTION),
|
||||||
|
HID_RI_REPORT_COUNT(8, JOYSTICK_AXES_COUNT),
|
||||||
|
HID_RI_REPORT_SIZE(8, 0x10),
|
||||||
|
# endif
|
||||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue