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