diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 2f8a184bf6..d6f84a2b6d 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -92,9 +92,9 @@ ifeq ($(MUSIC_ENABLE), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
endif
-ifeq ($(strip $(PLOVER_ENABLE)), yes)
- OPT_DEFS += -DPLOVER_ENABLE
- SRC += $(QUANTUM_DIR)/process_keycode/process_plover.c
+ifeq ($(strip $(PLOVER_HID_ENABLE)), yes)
+ OPT_DEFS += -DPLOVER_HID_ENABLE
+ SRC += $(QUANTUM_DIR)/process_keycode/process_plover_hid.c
endif
ifeq ($(strip $(STENO_ENABLE)), yes)
diff --git a/builddefs/show_options.mk b/builddefs/show_options.mk
index 173e74cbc6..8aa2f42ee2 100644
--- a/builddefs/show_options.mk
+++ b/builddefs/show_options.mk
@@ -66,7 +66,7 @@ OTHER_OPTION_NAMES = \
KEYLOGGER_ENABLE \
LCD_BACKLIGHT_ENABLE \
MACROS_ENABLED \
- PLOVER_ENABLE \
+ PLOVER_HID_ENABLE \
PS2_MOUSE_ENABLE \
RAW_ENABLE \
SWAP_HANDS_ENABLE \
diff --git a/quantum/keymap_extras/keymap_plover_hid.h b/quantum/keymap_extras/keymap_plover_hid.h
new file mode 100644
index 0000000000..4792f5d1f3
--- /dev/null
+++ b/quantum/keymap_extras/keymap_plover_hid.h
@@ -0,0 +1,89 @@
+/* Copyright 2017 Joseph Wasson
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+
+#include "keymap.h"
+
+// List of keycodes for the plover HID.
+enum steno_keycodes {
+ PLV__MIN = QK_PLOVER_HID,
+ PLV_N1 = PLV__MIN,
+ PLV_N2,
+ PLV_N3,
+ PLV_N4,
+ PLV_N5,
+ PLV_N6,
+ PLV_N7,
+ PLV_N8,
+ PLV_N9,
+ PLV_NA,
+ PLV_NB,
+ PLV_NC,
+ PLV_X1,
+ PLV_S1,
+ PLV_TL,
+ PLV_PL,
+ PLV_HL,
+ PLV_ST1,
+ PLV_ST3,
+ PLV_FR,
+ PLV_PR,
+ PLV_LR,
+ PLV_TR,
+ PLV_DR,
+ PLV_X2,
+ PLV_S2,
+ PLV_KL,
+ PLV_WL,
+ PLV_RL,
+ PLV_ST2,
+ PLV_ST4,
+ PLV_RR,
+ PLV_BR,
+ PLV_GR,
+ PLV_SR,
+ PLV_ZR,
+ PLV_X3,
+ PLV_A,
+ PLV_O,
+ PLV_E,
+ PLV_U,
+ PLV_X4,
+ PLV_X5,
+ PLV_X6,
+ PLV_X7,
+ PLV_X8,
+ PLV_X9,
+ PLV_X10,
+ PLV_X11,
+ PLV_X12,
+ PLV_X13,
+ PLV_X14,
+ PLV_X15,
+ PLV_X16,
+ PLV_X17,
+ PLV_X18,
+ PLV_X19,
+ PLV_X20,
+ PLV_X21,
+ PLV_X22,
+ PLV_X23,
+ PLV_X24,
+ PLV_X25,
+ PLV_X26,
+ PLV__MAX = PLV_X26,
+};
diff --git a/quantum/plover_hid.h b/quantum/plover_hid.h
new file mode 100644
index 0000000000..e12c2fc630
--- /dev/null
+++ b/quantum/plover_hid.h
@@ -0,0 +1,4 @@
+#pragma once
+
+#define PLOVER_HID_SIMPLE_REPORT_SIZE 9
+void plover_hid_send(uint8_t data[PLOVER_HID_SIMPLE_REPORT_SIZE]);
diff --git a/quantum/process_keycode/process_plover_hid.c b/quantum/process_keycode/process_plover_hid.c
new file mode 100644
index 0000000000..ad0c1196c3
--- /dev/null
+++ b/quantum/process_keycode/process_plover_hid.c
@@ -0,0 +1,23 @@
+#include "process_plover_hid.h"
+#include "keymap_plover_hid.h"
+#include "plover_hid.h"
+
+// Simple report consists of a single byte set to one
+// followed by one bit for each of the 64 buttons defined
+// in the report type.
+static uint8_t report[PLOVER_HID_SIMPLE_REPORT_SIZE] = {1};
+
+bool process_plover_hid(uint16_t keycode, keyrecord_t *record) {
+ if (keycode < PLV__MIN || keycode > PLV__MAX) {
+ return true;
+ }
+ keycode = keycode - PLV__MIN;
+ if (record->event.pressed) {
+ report[1 + keycode/8] |= (1 << (7 - (keycode % 8)));
+ } else {
+ report[1 + keycode/8] &= ~(1 << (7 - (keycode % 8)));
+ }
+
+ plover_hid_send(report);
+ return false;
+}
diff --git a/quantum/process_keycode/process_plover_hid.h b/quantum/process_keycode/process_plover_hid.h
new file mode 100644
index 0000000000..dd9bdb353a
--- /dev/null
+++ b/quantum/process_keycode/process_plover_hid.h
@@ -0,0 +1,20 @@
+/* Copyright 2021 The QMK Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "quantum.h"
+
+bool process_plover_hid(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 33121f6b95..bdd14f4622 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -277,6 +277,9 @@ bool process_record_quantum(keyrecord_t *record) {
#if defined(BACKLIGHT_ENABLE) || defined(LED_MATRIX_ENABLE)
process_backlight(keycode, record) &&
#endif
+#ifdef PLOVER_HID_ENABLE
+ process_plover_hid(keycode, record) &&
+#endif
#ifdef STENO_ENABLE
process_steno(keycode, record) &&
#endif
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 92e1af1c40..fc11c3491b 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -81,6 +81,10 @@ extern layer_state_t layer_state;
# endif
#endif
+#ifdef PLOVER_HID_ENABLE
+# include "process_plover_hid.h"
+#endif
+
#ifdef STENO_ENABLE
# include "process_steno.h"
#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 40355d799a..3527de5950 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -65,6 +65,8 @@ enum quantum_keycodes {
QK_STENO_COMB = 0x5A32,
QK_STENO_COMB_MAX = 0x5A3C,
QK_STENO_MAX = 0x5A3F,
+ QK_PLOVER_HID = 0x5A40,
+ QK_PLOVER_HID_MAX = 0x5A80,
// 0x5C00 - 0x5FFF are reserved, see below
QK_MOD_TAP = 0x6000,
QK_MOD_TAP_MAX = 0x7FFF,
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index f2bb3a1ba7..0ff7dc0f3d 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -313,8 +313,8 @@ typedef struct {
#ifdef RAW_ENABLE
usb_driver_config_t raw_driver;
#endif
-#ifdef PLOVER_ENABLE
- usb_driver_config_t plover_driver;
+#ifdef PLOVER_HID_ENABLE
+ usb_driver_config_t plover_hid_driver;
#endif
#ifdef MIDI_ENABLE
usb_driver_config_t midi_driver;
@@ -353,10 +353,10 @@ static usb_driver_configs_t drivers = {
.raw_driver = QMK_USB_DRIVER_CONFIG(RAW, 0, false),
#endif
-#ifdef PLOVER_ENABLE
-# define PLOVER_IN_CAPACITY 4
-# define PLOVER_IN_MODE USB_EP_MODE_TYPE_INTR
- .plover_driver = QMK_USB_DRIVER_CONFIG(PLOVER, 0, false),
+#ifdef PLOVER_HID_ENABLE
+# define PLOVER_HID_IN_CAPACITY 4
+# define PLOVER_HID_IN_MODE USB_EP_MODE_TYPE_INTR
+ .plover_hid_driver = QMK_USB_DRIVER_CONFIG(PLOVER_HID, 0, false),
#endif
#ifdef MIDI_ENABLE
@@ -1096,6 +1096,12 @@ void console_task(void) {
#endif /* CONSOLE_ENABLE */
+#ifdef PLOVER_HID_ENABLE
+void plover_hid_send(uint8_t data[PLOVER_HID_SIMPLE_REPORT_SIZE]) {
+ chnWrite(&drivers.plover_hid_driver.driver, data, PLOVER_HID_SIMPLE_REPORT_SIZE);
+}
+#endif
+
#ifdef RAW_ENABLE
void raw_hid_send(uint8_t *data, uint8_t length) {
// TODO: implement variable size packet
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 307ba27465..7f59edf1e8 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -86,6 +86,10 @@ extern keymap_config_t keymap_config;
# include "raw_hid.h"
#endif
+#ifdef PLOVER_HID_ENABLE
+# include "plover_hid.h"
+#endif
+
#ifdef JOYSTICK_ENABLE
# include "joystick.h"
#endif
@@ -209,6 +213,28 @@ static void raw_hid_task(void) {
}
#endif
+#ifdef PLOVER_HID_ENABLE
+void plover_hid_send(uint8_t data[PLOVER_HID_SIMPLE_REPORT_SIZE]) {
+ if (USB_DeviceState != DEVICE_STATE_Configured) {
+ return;
+ }
+
+ uint8_t ep = Endpoint_GetCurrentEndpoint();
+
+ Endpoint_SelectEndpoint(PLOVER_HID_IN_EPNUM);
+
+ // Check to see if the host is ready to accept another packet
+ if (Endpoint_IsINReady()) {
+ // Write data
+ Endpoint_Write_Stream_LE(data, PLOVER_HID_SIMPLE_REPORT_SIZE, NULL);
+ // Finalize The stream transfer to send the last packet
+ Endpoint_ClearIN();
+ }
+
+ Endpoint_SelectEndpoint(ep);
+}
+#endif
+
/*******************************************************************************
* Console
******************************************************************************/
@@ -471,9 +497,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) {
ConfigSuccess &= Endpoint_ConfigureEndpoint((RAW_OUT_EPNUM | ENDPOINT_DIR_OUT), EP_TYPE_INTERRUPT, RAW_EPSIZE, 1);
#endif
-#ifdef PLOVER_ENABLE
+#ifdef PLOVER_HID_ENABLE
/* Setup raw HID endpoints */
- ConfigSuccess &= Endpoint_ConfigureEndpoint((PLOVER_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, PLOVER_EPSIZE, 1);
+ ConfigSuccess &= Endpoint_ConfigureEndpoint((PLOVER_HID_IN_EPNUM | ENDPOINT_DIR_IN), EP_TYPE_INTERRUPT, PLOVER_HID_EPSIZE, 1);
#endif
#ifdef CONSOLE_ENABLE
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 2734d8d5c0..962b849ac5 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -322,7 +322,7 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM RawReport[] = {
};
#endif
-#ifdef PLOVER_ENABLE
+#ifdef PLOVER_HID_ENABLE
const USB_Descriptor_HIDReport_Datatype_t PROGMEM PloverReport[] = {
0x06, 0x50, 0xff, // UsagePage (65360)
0x0a, 0x56, 0x4c, // Usage (19542)
@@ -577,7 +577,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
},
#endif
-#ifdef PLOVER_ENABLE
+#ifdef PLOVER_HID_ENABLE
/*
* Plover HID
*/
@@ -586,7 +586,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
.Size = sizeof(USB_Descriptor_Interface_t),
.Type = DTYPE_Interface
},
- .InterfaceNumber = PLOVER_INTERFACE,
+ .InterfaceNumber = PLOVER_HID_INTERFACE,
.AlternateSetting = 0x00,
.TotalEndpoints = 1,
.Class = HID_CSCP_HIDClass,
@@ -610,7 +610,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = {
.Size = sizeof(USB_Descriptor_Endpoint_t),
.Type = DTYPE_Endpoint
},
- .EndpointAddress = (ENDPOINT_DIR_IN | PLOVER_IN_EPNUM),
+ .EndpointAddress = (ENDPOINT_DIR_IN | PLOVER_HID_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
.EndpointSize = RAW_EPSIZE,
.PollingIntervalMS = 0x01
@@ -1211,8 +1211,8 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
break;
#endif
-#ifdef PLOVER_ENABLE
- case PLOVER_INTERFACE:
+#ifdef PLOVER_HID_ENABLE
+ case PLOVER_HID_INTERFACE:
Address = &ConfigurationDescriptor.Plover_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
@@ -1276,8 +1276,8 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
break;
#endif
-#ifdef PLOVER_ENABLE
- case PLOVER_INTERFACE:
+#ifdef PLOVER_HID_ENABLE
+ case PLOVER_HID_INTERFACE:
Address = &PloverReport;
Size = sizeof(PloverReport);
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index 7bb0bf8c2d..39b5ccc59d 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -75,7 +75,7 @@ typedef struct {
USB_Descriptor_Endpoint_t Raw_OUTEndpoint;
#endif
-#ifdef PLOVER_ENABLE
+#ifdef PLOVER_HID_ENABLE
// Plover HID Interface
USB_Descriptor_Interface_t Plover_Interface;
USB_HID_Descriptor_HID_t Plover_HID;
@@ -169,8 +169,8 @@ enum usb_interfaces {
RAW_INTERFACE,
#endif
-#ifdef PLOVER_ENABLE
- PLOVER_INTERFACE,
+#ifdef PLOVER_HID_ENABLE
+ PLOVER_HID_INTERFACE,
#endif
#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
@@ -234,8 +234,8 @@ enum usb_endpoints {
# endif
#endif
-#ifdef PLOVER_ENABLE
- PLOVER_IN_EPNUM = NEXT_EPNUM,
+#ifdef PLOVER_HID_ENABLE
+ PLOVER_HID_IN_EPNUM = NEXT_EPNUM,
#endif
#ifdef SHARED_EP_ENABLE
@@ -318,7 +318,7 @@ enum usb_endpoints {
#define SHARED_EPSIZE 32
#define MOUSE_EPSIZE 8
#define RAW_EPSIZE 32
-#define PLOVER_EPSIZE 32
+#define PLOVER_HID_EPSIZE 9
#define CONSOLE_EPSIZE 32
#define MIDI_STREAM_EPSIZE 64
#define CDC_NOTIFICATION_EPSIZE 8