a3cfb1dab7679a774d8aa09f7b609f3302dad73d

Author
Ryan <fauxpark@gmail.com>
Committer
GitHub <noreply@github.com>
Date

Message

Joystick: add support for 8-way hat switch (#24515)

Diff

This diff is truncated to protect this page.

  1diff --git a/docs/features/joystick.md b/docs/features/joystick.md
  2index 69db4655d594c8a11a5189759e4086cd06e5c202..cbf6c6daf7e9d61c9273d856cf201604c87a33d7 100644
  3--- a/docs/features/joystick.md
  4+++ b/docs/features/joystick.md
  5@@ -1,6 +1,6 @@
  6 # Joystick {#joystick}
  7 
  8-This feature provides game controller input as a joystick device supporting up to 6 axes and 32 buttons. Axes can be read either from an [ADC-capable input pin](../drivers/adc), or can be virtual, so that its value is provided by your code.
  9diff --git a/quantum/joystick.c b/quantum/joystick.c
 10index 32f19b2cd99d26bf7034f50a55945121ba546b8f..62893fd1997a93470c03cfe67ee7333799bc9e4d 100644
 11--- a/quantum/joystick.c
 12+++ b/quantum/joystick.c
 13@@ -29,6 +29,9 @@ joystick_t joystick_state = {
 14             0
 15 #endif
 16         },
 17+#ifdef JOYSTICK_HAS_HAT
 18+    .hat = -1,
 19+#endif
 20     .dirty = false,
 21 };
 22 
 23@@ -145,6 +148,13 @@ void joystick_set_axis(uint8_t axis, int16_t value) {
 24     }
 25 }
 26 
 27+#ifdef JOYSTICK_HAS_HAT
 28+void joystick_set_hat(int8_t value) {
 29+    joystick_state.hat   = value;
 30+    joystick_state.dirty = true;
 31+}
 32+#endif
 33+
 34 void joystick_init(void) {
 35     joystick_init_axes();
 36 }
 37diff --git a/quantum/joystick.h b/quantum/joystick.h
 38index 5a69ceac64a9f5b637223c75c880d40a3dc777ca..24f80c1ad6f600810ac89149bbc3b72170d089e2 100644
 39--- a/quantum/joystick.h
 40+++ b/quantum/joystick.h
 41@@ -52,6 +52,16 @@
 42 
 43 #define JOYSTICK_MAX_VALUE ((1L << (JOYSTICK_AXIS_RESOLUTION - 1)) - 1)
 44 
 45+#define JOYSTICK_HAT_CENTER -1
 46+#define JOYSTICK_HAT_NORTH 0
 47+#define JOYSTICK_HAT_NORTHEAST 1
 48+#define JOYSTICK_HAT_EAST 2
 49+#define JOYSTICK_HAT_SOUTHEAST 3
 50+#define JOYSTICK_HAT_SOUTH 4
 51+#define JOYSTICK_HAT_SOUTHWEST 5
 52+#define JOYSTICK_HAT_WEST 6
 53+#define JOYSTICK_HAT_NORTHWEST 7
 54+
 55 // configure on input_pin of the joystick_axes array entry to NO_PIN
 56 // to prevent it from being read from the ADC. This allows outputting forged axis value.
 57 #define JOYSTICK_AXIS_VIRTUAL \
 58@@ -73,7 +83,10 @@ extern joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT];
 59 typedef struct {
 60     uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
 61     int16_t axes[JOYSTICK_AXIS_COUNT];
 62-    bool    dirty;
 63+#ifdef JOYSTICK_HAS_HAT
 64+    int8_t hat;
 65+#endif
 66+    bool dirty;
 67 } joystick_t;
 68 
 69 extern joystick_t joystick_state;
 70@@ -129,4 +142,11 @@ void joystick_read_axes(void);
 71  */
 72 void joystick_set_axis(uint8_t axis, int16_t value);
 73 
 74+/**
 75+ * \brief Set the position of the hat switch.
 76+ *
 77+ * \param value The hat switch position to set.
 78+ */
 79+void joystick_set_hat(int8_t value);
 80+
 81 /** \} */
 82diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c
 83index 732fbdc37d4d92aaab46928171683d1de1b9f9b2..df805c827c2ac35c9f964940e07a829a1a5fc1bf 100644
 84--- a/tmk_core/protocol/host.c
 85+++ b/tmk_core/protocol/host.c
 86@@ -193,6 +193,10 @@ void host_joystick_send(joystick_t *joystick) {
 87             },
 88 #    endif
 89 
 90+#    ifdef JOYSTICK_HAS_HAT
 91+        .hat = joystick->hat,
 92+#    endif
 93+
 94 #    if JOYSTICK_BUTTON_COUNT > 0
 95         .buttons =
 96             {
 97diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h
 98index 37c8ea48f1b605cc025585d5031c7dc639a1408a..d854f51d5c45cda58668f742dc030f05b174eb1a 100644
 99--- a/tmk_core/protocol/report.h
100+++ b/tmk_core/protocol/report.h
101@@ -246,6 +246,11 @@ typedef struct {
102     joystick_axis_t axes[JOYSTICK_AXIS_COUNT];
103 #endif
104 
105+#ifdef JOYSTICK_HAS_HAT
106+    int8_t  hat : 4;
107+    uint8_t reserved : 4;
108+#endif
109+
110 #if JOYSTICK_BUTTON_COUNT > 0
111     uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
112 #endif
113diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
114index e7d12a07d9f6f1e5be9ea760392b02a04a43ba54..c7fb660b65d6d6c1492f45ba7554845438017521 100644
115--- a/tmk_core/protocol/usb_descriptor.c
116+++ b/tmk_core/protocol/usb_descriptor.c
117@@ -247,6 +247,23 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
118             HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
119 #    endif
120 
121+#    ifdef JOYSTICK_HAS_HAT
122+            // Hat Switch (4 bits)
123+            HID_RI_USAGE(8, 0x39), // Hat Switch
124+            HID_RI_LOGICAL_MINIMUM(8, 0x00),
125+            HID_RI_LOGICAL_MAXIMUM(8, 0x07),
126+            HID_RI_PHYSICAL_MINIMUM(8, 0),
127+            HID_RI_PHYSICAL_MAXIMUM(16, 315),
128+            HID_RI_UNIT(8, 0x14),  // Degree, English Rotation
129+            HID_RI_REPORT_COUNT(8, 1),
130+            HID_RI_REPORT_SIZE(8, 4),
131+            HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NULLSTATE),
132+            // Padding (4 bits)
133+            HID_RI_REPORT_COUNT(8, 0x04),
134+            HID_RI_REPORT_SIZE(8, 0x01),
135+            HID_RI_INPUT(8, HID_IOF_CONSTANT),
136+#    endif
137+
138 #    if JOYSTICK_BUTTON_COUNT > 0
139             HID_RI_USAGE_PAGE(8, 0x09), // Button
140             HID_RI_USAGE_MINIMUM(8, 0x01),
141diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
142index 2a29fe65d90abdb2a8833ff3d200167d8fa52381..fdbfcc17dce14abaa153d34e9d89bc9e5c5d62a8 100644
143--- a/tmk_core/protocol/vusb/vusb.c
144+++ b/tmk_core/protocol/vusb/vusb.c
145@@ -621,6 +621,23 @@ const PROGMEM uchar shared_hid_report[] = {
146     0x81, 0x02, //     Input (Data, Variable, Absolute)
147 #    endif
148 
149+#    ifdef JOYSTICK_HAS_HAT
150+    // Hat Switch (4 bits)
151+    0x09, 0x39,       //     Usage (Hat Switch)
152+    0x15, 0x00,       //     Logical Minimum (0)
153+    0x25, 0x07,       //     Logical Maximum (7)
154+    0x35, 0x00,       //     Physical Minimum (0)
155+    0x46, 0x3B, 0x01, //     Physical Maximum (315)
156+    0x65, 0x14,       //     Unit (Degree, English Rotation)
157+    0x95, 0x01,       //     Report Count (1)
158+    0x75, 0x04,       //     Report Size (4)
159+    0x81, 0x42,       //     Input (Data, Variable, Absolute, Null State)
160+    // Padding (4 bits)
161+    0x95, 0x04, //     Report Count (4)
162+    0x75, 0x01, //     Report Size (1)
163+    0x81, 0x01, //     Input (Constant)
164+#    endif
165+
166 #    if JOYSTICK_BUTTON_COUNT > 0
167     0x05, 0x09,                  //     Usage Page (Button)
168     0x19, 0x01,                  //     Usage Minimum (Button 1)