Kaynağa Gözat

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>
seb-pau 5 yıl önce
ebeveyn
işleme
f728c249ce

+ 6 - 0
docs/feature_joystick.md

@@ -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
 
 Joystick buttons are normal Quantum keycodes, defined as `JS_BUTTON0` to `JS_BUTTON31`, depending on the number of buttons you have configured.

+ 10 - 2
quantum/joystick.h

@@ -1,5 +1,9 @@
 #pragma once
 
+#include "quantum.h"
+
+#include <stdint.h>
+
 #ifndef JOYSTICK_BUTTON_COUNT
 #    define JOYSTICK_BUTTON_COUNT 8
 #endif
@@ -8,9 +12,13 @@
 #    define JOYSTICK_AXES_COUNT 4
 #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
 // to prevent it from being read from the ADC. This allows outputing forged axis value.

+ 4 - 4
quantum/process_keycode/process_joystick.c

@@ -129,17 +129,17 @@ bool process_joystick_analogread_quantum() {
         // 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) * -JOYSTICK_RESOLUTION) / (range - ref);
 
         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) * JOYSTICK_RESOLUTION) / (range - ref);
         }
 
         // 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 < -JOYSTICK_RESOLUTION ? -JOYSTICK_RESOLUTION : ranged_val;
+        ranged_val = ranged_val > JOYSTICK_RESOLUTION ? JOYSTICK_RESOLUTION : ranged_val;
 
         if (ranged_val != joystick_status.axes[axis_index]) {
             joystick_status.axes[axis_index] = ranged_val;

+ 5 - 1
tmk_core/common/report.h

@@ -192,7 +192,11 @@ typedef struct {
 
 typedef struct {
 #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
 
 #if JOYSTICK_BUTTON_COUNT > 0

+ 13 - 2
tmk_core/protocol/usb_descriptor.c

@@ -41,6 +41,10 @@
 #include "usb_descriptor.h"
 #include "usb_descriptor_common.h"
 
+#ifdef JOYSTICK_ENABLE
+#    include "joystick.h"
+#endif
+
 // clang-format off
 
 /*
@@ -308,10 +312,17 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickReport[] = {
             HID_RI_USAGE(8, 0x35),      // Rz
 #    endif
 #    if JOYSTICK_AXES_COUNT >= 1
-            HID_RI_LOGICAL_MINIMUM(8, -127),
-            HID_RI_LOGICAL_MAXIMUM(8, 127),
+     # if JOYSTICK_AXES_RESOLUTION == 8
+            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_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),
 #    endif