summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Didron <fdidron@users.noreply.github.com>2022-05-31 19:03:21 +0900
committerGitHub <noreply@github.com>2022-05-31 19:03:21 +0900
commitfc773ff0cf9c528773fa81be0fc8880ca5153d81 (patch)
treee917ed871290cc78cff818ee896b838d12ccc654
parent1fbd91aa106a4beb6ab84614dde14165a43f009a (diff)
Reimplements Oryx's live training over raw hid (#345)
* feat: initial commit, random pairing sequence generation, host - board pairing handshakes * feat: reimplements ory's live training over raw hid * feat: adds planck / ergodox support * chore: some code styling fixes * fix: build smoke tests * fix: code lint * fix: disable console / command on moonlander, fixes build ci test * fix: code lint * fix: remove unused define(MATRIX_SIZE)
-rw-r--r--builddefs/common_features.mk2
-rw-r--r--keyboards/ergodox_ez/ergodox_ez.c8
-rw-r--r--keyboards/ergodox_ez/keymaps/oryx/config.h3
-rw-r--r--keyboards/moonlander/keymaps/oryx/config.h3
-rw-r--r--keyboards/moonlander/keymaps/oryx/rules.mk2
-rw-r--r--keyboards/moonlander/moonlander.c43
-rw-r--r--keyboards/moonlander/rules.mk4
-rw-r--r--keyboards/planck/ez/ez.c8
-rw-r--r--quantum/eeconfig.c7
-rw-r--r--quantum/oryx.c379
-rw-r--r--quantum/oryx.h103
-rw-r--r--quantum/quantum.c18
-rw-r--r--tmk_core/protocol/chibios/usb_main.c41
-rw-r--r--tmk_core/protocol/lufa/lufa.c67
14 files changed, 302 insertions, 386 deletions
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 686b443421..f7ad32c28e 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -549,7 +549,7 @@ ifeq ($(strip $(TERMINAL_ENABLE)), yes)
endif
ifeq ($(strip $(ORYX_ENABLE)), yes)
- WEBUSB_ENABLE := yes
+ RAW_ENABLE := yes
SRC += $(QUANTUM_DIR)/oryx.c
OPT_DEFS += -DORYX_ENABLE
endif
diff --git a/keyboards/ergodox_ez/ergodox_ez.c b/keyboards/ergodox_ez/ergodox_ez.c
index f415fa0255..8fa038cdda 100644
--- a/keyboards/ergodox_ez/ergodox_ez.c
+++ b/keyboards/ergodox_ez/ergodox_ez.c
@@ -424,13 +424,13 @@ void dynamic_macro_record_end_user(int8_t direction) {
void matrix_scan_kb(void) {
#ifdef ORYX_ENABLE
- if(webusb_state.pairing == true) {
+ if(rawhid_state.pairing == true) {
if(loops == 0) {
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
}
- if(loops % WEBUSB_BLINK_STEPS == 0) {
+ if(loops % PAIRING_BLINK_STEPS == 0) {
if(is_on) {
ergodox_right_led_2_off();
} else {
@@ -438,8 +438,8 @@ void matrix_scan_kb(void) {
}
is_on ^= 1;
}
- if(loops > WEBUSB_BLINK_END) {
- webusb_state.pairing = false;
+ if(loops > PAIRING_BLINK_END) {
+ rawhid_state.pairing = false;
layer_state_set_user(layer_state);
loops = 0;
}
diff --git a/keyboards/ergodox_ez/keymaps/oryx/config.h b/keyboards/ergodox_ez/keymaps/oryx/config.h
index bad98d2c0e..1c7897be6c 100644
--- a/keyboards/ergodox_ez/keymaps/oryx/config.h
+++ b/keyboards/ergodox_ez/keymaps/oryx/config.h
@@ -1,3 +1,6 @@
#pragma once
#define LAYER_STATE_8BIT
+#define FIRMWARE_VERSION u8"default/latest"
+#define RAW_USAGE_PAGE 0xFF60
+#define RAW_USAGE_ID 0x61
diff --git a/keyboards/moonlander/keymaps/oryx/config.h b/keyboards/moonlander/keymaps/oryx/config.h
index be3110d3b0..1ea6cba6b9 100644
--- a/keyboards/moonlander/keymaps/oryx/config.h
+++ b/keyboards/moonlander/keymaps/oryx/config.h
@@ -1,3 +1,6 @@
#pragma once
#include "../default/config.h"
+#define FIRMWARE_VERSION u8"default/latest"
+#define RAW_USAGE_PAGE 0xFF60
+#define RAW_USAGE_ID 0x61
diff --git a/keyboards/moonlander/keymaps/oryx/rules.mk b/keyboards/moonlander/keymaps/oryx/rules.mk
index cc72fbad13..d269d04c82 100644
--- a/keyboards/moonlander/keymaps/oryx/rules.mk
+++ b/keyboards/moonlander/keymaps/oryx/rules.mk
@@ -1,6 +1,4 @@
SRC += ../default/keymap.c
-include ../default/rules.mk
-WEBUSB_ENABLE = yes
ORYX_ENABLE = yes
-DYNAMIC_KEYMAP_ENABLE = yes
diff --git a/keyboards/moonlander/moonlander.c b/keyboards/moonlander/moonlander.c
index cb8a5abca0..3c8f5b4184 100644
--- a/keyboards/moonlander/moonlander.c
+++ b/keyboards/moonlander/moonlander.c
@@ -14,11 +14,10 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
+ */
#include "moonlander.h"
+#include "raw_hid.h"
keyboard_config_t keyboard_config;
@@ -28,7 +27,9 @@ bool is_launching = false;
#ifdef DYNAMIC_MACRO_ENABLE
static bool is_dynamic_recording = false;
-void dynamic_macro_record_start_user(void) { is_dynamic_recording = true; }
+void dynamic_macro_record_start_user(void) {
+ is_dynamic_recording = true;
+}
void dynamic_macro_record_end_user(int8_t direction) {
is_dynamic_recording = false;
@@ -96,7 +97,6 @@ static THD_FUNCTION(LEDThread, arg) {
}
}
-
void keyboard_pre_init_kb(void) {
setPinOutput(B5);
setPinOutput(B4);
@@ -125,9 +125,9 @@ layer_state_t layer_state_set_kb(layer_state_t state) {
bool LED_3 = false;
bool LED_4 = false;
bool LED_5 = false;
-#if !defined(CAPS_LOCK_STATUS)
+# if !defined(CAPS_LOCK_STATUS)
bool LED_6 = false;
-#endif
+# endif
uint8_t layer = get_highest_layer(state);
switch (layer) {
@@ -141,9 +141,9 @@ layer_state_t layer_state_set_kb(layer_state_t state) {
break;
case 3:
LED_3 = true;
-#if !defined(CAPS_LOCK_STATUS)
+# if !defined(CAPS_LOCK_STATUS)
LED_6 = true;
-#endif
+# endif
break;
case 4:
LED_4 = true;
@@ -152,9 +152,9 @@ layer_state_t layer_state_set_kb(layer_state_t state) {
LED_5 = true;
break;
case 6:
-#if !defined(CAPS_LOCK_STATUS)
+# if !defined(CAPS_LOCK_STATUS)
LED_6 = true;
-#endif
+# endif
break;
default:
break;
@@ -165,10 +165,9 @@ layer_state_t layer_state_set_kb(layer_state_t state) {
ML_LED_3(LED_3);
ML_LED_4(LED_4);
ML_LED_5(LED_5);
-#if !defined(CAPS_LOCK_STATUS)
+# if !defined(CAPS_LOCK_STATUS)
ML_LED_6(LED_6);
-#endif
-
+# endif
return state;
}
#endif
@@ -373,7 +372,7 @@ const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_moonlander(
#ifdef CAPS_LOCK_STATUS
bool led_update_kb(led_t led_state) {
bool res = led_update_user(led_state);
- if(res) {
+ if (res) {
ML_LED_6(led_state.caps_lock);
}
return res;
@@ -381,7 +380,9 @@ bool led_update_kb(led_t led_state) {
#endif
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
- if (!process_record_user(keycode, record)) { return false; }
+ if (!process_record_user(keycode, record)) {
+ return false;
+ }
switch (keycode) {
#if !defined(MOONLANDER_USER_LEDS)
case LED_LEVEL:
@@ -434,7 +435,7 @@ void matrix_init_kb(void) {
keyboard_config.raw = eeconfig_read_kb();
if (!keyboard_config.led_level && !keyboard_config.led_level_res) {
- keyboard_config.led_level = true;
+ keyboard_config.led_level = true;
keyboard_config.led_level_res = 0b11;
eeconfig_update_kb(keyboard_config.raw);
}
@@ -448,11 +449,11 @@ void matrix_init_kb(void) {
matrix_init_user();
}
-void eeconfig_init_kb(void) { // EEPROM is getting reset!
- keyboard_config.raw = 0;
+void eeconfig_init_kb(void) { // EEPROM is getting reset!
+ keyboard_config.raw = 0;
keyboard_config.rgb_matrix_enable = true;
- keyboard_config.led_level = true;
- keyboard_config.led_level_res = 0b11;
+ keyboard_config.led_level = true;
+ keyboard_config.led_level_res = 0b11;
eeconfig_update_kb(keyboard_config.raw);
eeconfig_init_user();
}
diff --git a/keyboards/moonlander/rules.mk b/keyboards/moonlander/rules.mk
index 1dd280db16..24ffb3caca 100644
--- a/keyboards/moonlander/rules.mk
+++ b/keyboards/moonlander/rules.mk
@@ -10,8 +10,8 @@ BOOTLOADER = stm32-dfu
BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = yes # Console for debug
-COMMAND_ENABLE = yes # Commands for debug and configuration
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Enable N-Key Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
diff --git a/keyboards/planck/ez/ez.c b/keyboards/planck/ez/ez.c
index c29f3cfa00..2e74ff860a 100644
--- a/keyboards/planck/ez/ez.c
+++ b/keyboards/planck/ez/ez.c
@@ -335,11 +335,11 @@ void dynamic_macro_record_end_user(int8_t direction) {
void matrix_scan_kb(void) {
#ifdef ORYX_ENABLE
- if(webusb_state.pairing == true) {
+ if(rawhid_state.pairing == true) {
if(loops == 0) {
//lights off
}
- if(loops % WEBUSB_BLINK_STEPS == 0) {
+ if(loops % PAIRING_BLINK_STEPS == 0) {
if(is_on) {
planck_ez_left_led_on();
planck_ez_right_led_off();
@@ -350,8 +350,8 @@ void matrix_scan_kb(void) {
}
is_on ^= 1;
}
- if(loops > WEBUSB_BLINK_END * 2) {
- webusb_state.pairing = false;
+ if(loops > PAIRING_BLINK_END * 2) {
+ rawhid_state.pairing = false;
loops = 0;
planck_ez_left_led_off();
planck_ez_right_led_off();
diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c
index 01895bae2a..0ff9996ca4 100644
--- a/quantum/eeconfig.c
+++ b/quantum/eeconfig.c
@@ -3,9 +3,6 @@
#include "eeprom.h"
#include "eeconfig.h"
#include "action_layer.h"
-#ifdef ORYX_ENABLE
-# include "oryx.h"
-#endif
#if defined(EEPROM_DRIVER)
# include "eeprom_driver.h"
@@ -60,10 +57,6 @@ void eeconfig_init_quantum(void) {
eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
eeprom_update_word(EECONFIG_RGB_MATRIX_EXTENDED, 0);
-#ifdef ORYX_ENABLE
- eeconfig_init_oryx();
-#endif
-
// TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
// within the emulated eeprom via dfu-util or another tool
#if defined INIT_EE_HANDS_LEFT
diff --git a/quantum/oryx.c b/quantum/oryx.c
index c1e5dfba31..706a43c42b 100644
--- a/quantum/oryx.c
+++ b/quantum/oryx.c
@@ -1,253 +1,180 @@
#include "oryx.h"
#include "eeprom.h"
-#include <string.h>
-bool oryx_state_live_training_enabled;
+rawhid_state_t rawhid_state = {.pairing = false, .paired = false};
-bool webusb_receive_oryx(uint8_t *data, uint8_t length) {
- uint8_t command = data[0];
- uint8_t *param = &(data[1]);
+keypos_t keyboard_pairing_sequence[PAIRING_SEQUENCE_SIZE];
+keypos_t host_pairing_sequence[PAIRING_SEQUENCE_SIZE];
+uint8_t pairing_input_index = 0;
+
+void raw_hid_receive(uint8_t *data, uint8_t length) {
+ uint8_t command = data[0];
+ uint8_t *param = &data[1];
+ uint8_t cmd_index = 0;
switch (command) {
- case ORYX_GET_LAYER:
- oryx_layer_event();
- return true;
- case ORYX_CMD_LIVE_TRAINING: {
- uint8_t event[4];
- switch (param[0]) { // 0 for querying, 1 for off, 2 for on
- case 0:
- break;
- case 1:
- oryx_state_live_training_enabled = false;
- break;
- case 2:
- oryx_state_live_training_enabled = true;
- break;
- default:
- webusb_error(WEBUSB_STATUS_UNKNOWN_COMMAND);
- return true;
- }
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_TRAINING;
- event[2] = oryx_state_live_training_enabled;
- event[3] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
-#ifdef DYNAMIC_KEYMAP_ENABLE
- case ORYX_CMD_LIVE_UPDATE_GET_KEYCODE: {
- uint8_t event[5];
- // layer, row, col
- uint16_t keycode = dynamic_keymap_get_keycode(param[0], param[1], param[2]);
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_GET_KEYCODE;
- event[2] = keycode >> 8;
- event[3] = keycode & 0xFF;
- event[4] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_SET_KEYCODE: {
- uint8_t event[5];
- dynamic_keymap_set_keycode(param[0], param[1], param[2], (param[3] << 8) | param[4]);
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_SET_KEYCODE;
- event[2] = param[3];
- event[3] = param[4];
- event[4] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_KEYMAP_RESET: {
- uint8_t event[3];
- dynamic_keymap_reset();
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_KEYMAP_RESET;
- event[2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_GET_BUFFER: {
- uint16_t offset = (param[0] << 8) | param[1];
- uint16_t size = param[2]; // size <= 28
- uint8_t event[size+3];
- uint8_t i;
- dynamic_keymap_get_buffer(offset, size, &param[3]);
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_GET_BUFFER;
- for (i = 0; i < size; i++) {
- event[i+2] = param[i];
- }
- event[i+2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_SET_BUFFER: {
- uint16_t offset = (param[0] << 8) | param[1];
- uint16_t size = param[2]; // size <= 28
- uint8_t event[3];
- dynamic_keymap_set_buffer(offset, size, &param[3]);
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_SET_BUFFER;
- event[2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_GET_LAYER_COUNT: {
- uint8_t event[4];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_GET_LAYER_COUNT;
- event[2] = dynamic_keymap_get_layer_count();
- event[3] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_GET_MACRO_COUNT: {
- uint8_t event[4];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_GET_MACRO_COUNT;
- event[2] = dynamic_keymap_macro_get_count();
- event[3] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_GET_MACRO_BUFFER_SIZE: {
- uint16_t size = dynamic_keymap_macro_get_buffer_size();
- uint8_t event[5];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_GET_MACRO_BUFFER_SIZE;
- event[2] = size >> 8;
- event[3] = size & 0xFF;
- event[4] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
+ case ORYX_CMD_GET_FW_VERSION: {
+ uint8_t event[RAW_EPSIZE];
+ uint8_t fw_version_size = sizeof(FIRMWARE_VERSION);
+ uint8_t stop[1];
+
+ event[0] = ORYX_EVT_GET_FW_VERSION;
+ stop[0] = ORYX_STOP_BIT;
+
+ memcpy(event + 1, FIRMWARE_VERSION, fw_version_size);
+ memcpy(event + fw_version_size, stop, 1);
+
+ raw_hid_send(event, RAW_EPSIZE);
+ break;
}
- case ORYX_CMD_LIVE_UPDATE_GET_MACRO_BUFFER: {
- uint16_t offset = (param[0] << 8) | param[1];
- uint16_t size = param[2]; // size <= 28
- uint8_t event[size+3];
- uint8_t i;
- dynamic_keymap_macro_get_buffer(offset, size, &param[3]);
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_GET_MACRO_BUFFER;
- for (i = 0; i < size; i++) {
- event[i+2] = param[i];
+
+ case ORYX_CMD_PAIRING_INIT:
+ pairing_init_handler();
+ store_pairing_sequence(&keyboard_pairing_sequence[0]);
+ break;
+
+ case ORYX_CMD_PAIRING_VALIDATE:
+ for (uint8_t i = 0; i < PAIRING_SEQUENCE_SIZE; i++) {
+ keypos_t pos;
+ pos.col = param[cmd_index++];
+ pos.row = param[cmd_index++];
+ host_pairing_sequence[i] = pos;
}
- event[i+2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_SET_MACRO_BUFFER: {
- uint16_t offset = (param[0] << 8) | param[1];
- uint16_t size = param[2]; // size <= 28
- dynamic_keymap_macro_set_buffer(offset, size, &param[3]);
- uint8_t event[3];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_SET_MACRO_BUFFER;
- event[2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_MACRO_RESET: {
- uint8_t event[3];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_MACRO_RESET;
- event[2] = WEBUSB_STOP_BIT;
- dynamic_keymap_macro_reset();
- webusb_send(event, sizeof(event));
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_EEPROM_RESET: {
- uint8_t event[3];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_EEPROM_RESET;
- event[2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- eeconfig_init();
- return true;
- }
- case ORYX_CMD_LIVE_UPDATE_KEYBOARD_RESET: {
- uint8_t event[3];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LIVE_UPDATE_KEYBOARD_RESET;
- event[2] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
- reset_keyboard();
- return true;
- }
-#endif
- default:
- return webusb_receive_kb(data, length);
+ pairing_validate_handler();
+ break;
}
}
-void oryx_layer_event(void) {
- uint8_t layer;
- uint8_t event[4];
- layer = get_highest_layer(layer_state);
-#ifdef WEBUSB_ENABLE
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LAYER;
- event[2] = layer;
- event[3] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
-#endif
+bool store_pairing_sequence(keypos_t *pairing_sequence) {
+ uint8_t stored_sequences[sizeof(uint16_t) * PAIRING_SEQUENCE_SIZE * PAIRING_SEQUENCE_NUM_STORED];
+
+ eeprom_read_block(&stored_sequences, (uint8_t *)EECONFIG_SIZE, PAIRING_STORAGE_SIZE);
+
+ uint8_t shiftLen = sizeof(&pairing_sequence);
+
+ for (int8_t i = PAIRING_STORAGE_SIZE; i >= 0; i--) {
+ if (i > shiftLen) {
+ stored_sequences[i] = stored_sequences[i - 1];
+ } else {
+ stored_sequences[i] = 0;
+ }
+ }
+ eeprom_update_block(stored_sequences, (uint8_t *)EECONFIG_SIZE, PAIRING_STORAGE_SIZE);
+ return true;
}
-bool is_oryx_live_training_enabled(void) { return (oryx_state_live_training_enabled && webusb_state.paired); }
+void pairing_init_handler(void) {
+ create_pairing_code();
+ uint8_t event[RAW_EPSIZE];
+ uint8_t event_index = 0;
+ event[event_index++] = ORYX_EVT_PAIRING_INPUT;
+ for (uint8_t i = 0; i < PAIRING_SEQUENCE_SIZE; i++) {
+ event[event_index++] = keyboard_pairing_sequence[i].col;
+ event[event_index++] = keyboard_pairing_sequence[i].row;
+ }
+ event[event_index++] = ORYX_STOP_BIT;
+ rawhid_state.pairing = true;
+ raw_hid_send(event, RAW_EPSIZE);
+}
-bool process_record_oryx(uint16_t keycode, keyrecord_t *record) {
- if(is_oryx_live_training_enabled()) {
- uint8_t event[5];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = record->event.pressed ? ORYX_EVT_KEYDOWN : ORYX_EVT_KEYUP;
- event[2] = record->event.key.col;
- event[3] = record->event.key.row;
- event[4] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
+void pairing_validate_handler() {
+ bool valid = true;
+ uint8_t event[RAW_EPSIZE];
+ for (uint8_t i = 0; i < PAIRING_SEQUENCE_SIZE; i++) {
+ if (keyboard_pairing_sequence[i].row != host_pairing_sequence[i].row) {
+ valid = false;
+ break;
+ }
+ if (keyboard_pairing_sequence[i].col != host_pairing_sequence[i].col) {
+ valid = false;
+ break;
+ }
}
- if (keycode == WEBUSB_PAIR && record->event.pressed) {
- webusb_state.pairing ^= true;
- return true;
+ if (valid == true) {
+ event[0] = ORYX_EVT_PAIRING_SUCCESS;
+ rawhid_state.paired = true;
+
+ } else {
+ event[0] = ORYX_EVT_PAIRING_FAILED;
+ rawhid_state.paired = false;
}
+ event[1] = ORYX_STOP_BIT;
+ rawhid_state.pairing = false;
+ raw_hid_send(event, sizeof(event));
+}
-#ifdef DYNAMIC_KEYMAP_ENABLE
- switch (keycode) {
- case MACRO00 ... MACRO15:
- if (record->event.pressed) {
- dynamic_keymap_macro_send(keycode - MACRO00);
- }
- return false;
+keypos_t get_random_keypos(void) {
+ uint8_t col = rand() % MATRIX_COLS;
+ uint8_t row = rand() % MATRIX_ROWS;
+ keypos_t pos = {.col = col, .row = row};
+
+ if (keymap_key_to_keycode(0, pos) != KC_NO) {
+ return pos;
+ } else {
+ return get_random_keypos();
}
-#endif
- return true;
}
-void layer_state_set_oryx(layer_state_t state) {
- if(is_oryx_live_training_enabled()) {
- uint8_t event[4];
- event[0] = WEBUSB_STATUS_OK;
- event[1] = ORYX_EVT_LAYER;
- event[2] = get_highest_layer(state);
- event[3] = WEBUSB_STOP_BIT;
- webusb_send(event, sizeof(event));
+void create_pairing_code(void) {
+ for (uint8_t i = 0; i < PAIRING_SEQUENCE_SIZE; i++) {
+ keypos_t pos = get_random_keypos();
+ keyboard_pairing_sequence[i] = pos;
}
}
-void eeconfig_init_oryx(void) {
-#ifdef DYNAMIC_KEYMAP_ENABLE
- // reread settings from flash into eeprom
- dynamic_keymap_reset();
- dynamic_keymap_macro_reset();
- eeprom_update_block(FIRMWARE_VERSION, (uint8_t *)EECONFIG_SIZE, sizeof(uint8_t)*FIRMWARE_VERSION_SIZE);
+void pairing_key_input_event(void) {
+ uint8_t event[RAW_EPSIZE];
+ event[0] = ORYX_EVT_PAIRING_KEY_INPUT;
+ raw_hid_send(event, sizeof(event));
}
-void matrix_init_oryx(void) {
- uint8_t temp[FIRMWARE_VERSION_SIZE];
- uint8_t firmware[FIRMWARE_VERSION_SIZE] = FIRMWARE_VERSION;
- eeprom_read_block(&temp, (uint8_t *)EECONFIG_SIZE, sizeof(uint8_t)*FIRMWARE_VERSION_SIZE);
- if (!memcmp(&temp, &firmware, sizeof(uint8_t)*FIRMWARE_VERSION_SIZE)) {
- eeconfig_init_oryx();
+void oryx_layer_event(void) {
+ uint8_t layer;
+ uint8_t event[RAW_EPSIZE];
+ layer = get_highest_layer(layer_state);
+ event[0] = ORYX_EVT_LAYER;
+ event[1] = layer;
+ event[2] = ORYX_STOP_BIT;
+ raw_hid_send(event, sizeof(event));
+}
+
+bool process_record_oryx(uint16_t keycode, keyrecord_t *record) {
+ // In pairing mode, key events are absorbed, and the host pairing sequence is filled.
+ // Once filled, the keyboard and host sequence are compaired, pairing state set to false
+ // and the proper pairing validation event is sent to the host
+ if (rawhid_state.pairing == true) {
+ // The host pairing sequence is filled on key up only
+ if (!record->event.pressed) {
+ if (pairing_input_index < PAIRING_SEQUENCE_SIZE) {
+ host_pairing_sequence[pairing_input_index++] = record->event.key;
+ pairing_key_input_event();
+ }
+ if (pairing_input_index == PAIRING_SEQUENCE_SIZE) {
+ rawhid_state.pairing = false;
+ pairing_input_index = 0;
+ pairing_validate_handler();
+ }
+ }
+ return false;
+ }
+ // While paired, the keyboard sends keystrokes positions to the host
+ if (rawhid_state.paired == true) {
+ uint8_t event[RAW_EPSIZE];
+ event[0] = record->event.pressed ? ORYX_EVT_KEYDOWN : ORYX_EVT_KEYUP;
+ event[1] = record->event.key.col;
+ event[2] = record->event.key.row;
+ event[3] = ORYX_STOP_BIT;
+ raw_hid_send(event, sizeof(event));
+ }
+ return true;
+}
+
+void layer_state_set_oryx(layer_state_t state) {
+ if (rawhid_state.paired) {
+ uint8_t event[RAW_EPSIZE];
+ event[0] = ORYX_EVT_LAYER;
+ event[1] = get_highest_layer(state);
+ event[2] = ORYX_STOP_BIT;
+ raw_hid_send(event, sizeof(event));
}
-#endif
}
diff --git a/quantum/oryx.h b/quantum/oryx.h
index b1fe78a061..5f6581235c 100644
--- a/quantum/oryx.h
+++ b/quantum/oryx.h
@@ -1,82 +1,61 @@
#pragma once
#include "quantum.h"
-#include "webusb.h"
+#include "raw_hid.h"
-#ifndef WEBUSB_ENABLE
-# error "WebUSB needs to be enabled, please enable it!"
+#ifndef RAW_ENABLE
+# error "Raw hid needs to be enabled, please enable it!"
+#endif
+#ifndef RAW_EPSIZE
+# define RAW_EPSIZE 32
#endif
-// enum Oryx_Status_code {
-// PLACEHOLDER = WEBUSB_STATUS_SAFE_RANGE,
-// }
+#define ORYX_STOP_BIT -2
+#define PAIRING_BLINK_STEPS 512
+#define PAIRING_BLINK_END PAIRING_BLINK_STEPS * 60
+#define PAIRING_SEQUENCE_SIZE 3
+#define PAIRING_SEQUENCE_NUM_STORED 5
+#define PAIRING_STORAGE_SIZE PAIRING_SEQUENCE_SIZE* PAIRING_SEQUENCE_NUM_STORED * sizeof(uint16_t)
enum Oryx_Command_Code {
- ORYX_GET_LAYER = WEBUSB_CMD_SAFE_RANGE,
- ORYX_CMD_LIVE_TRAINING,
- ORYX_CMD_LIVE_UPDATE_GET_KEYCODE,
- ORYX_CMD_LIVE_UPDATE_SET_KEYCODE,
- ORYX_CMD_LIVE_UPDATE_KEYMAP_RESET,
- ORYX_CMD_LIVE_UPDATE_GET_BUFFER,
- ORYX_CMD_LIVE_UPDATE_SET_BUFFER,
- ORYX_CMD_LIVE_UPDATE_GET_LAYER_COUNT,
- ORYX_CMD_LIVE_UPDATE_GET_MACRO_COUNT,
- ORYX_CMD_LIVE_UPDATE_GET_MACRO_BUFFER_SIZE,
- ORYX_CMD_LIVE_UPDATE_GET_MACRO_BUFFER,
- ORYX_CMD_LIVE_UPDATE_SET_MACRO_BUFFER,
- ORYX_CMD_LIVE_UPDATE_MACRO_RESET,
- ORYX_CMD_LIVE_UPDATE_EEPROM_RESET,
- ORYX_CMD_LIVE_UPDATE_KEYBOARD_RESET,
-
+ ORYX_CMD_GET_FW_VERSION,
+ ORYX_CMD_PAIRING_INIT,
+ ORYX_CMD_PAIRING_VALIDATE,
+ ORYX_CMD_DISCONNECT,
+ ORYX_GET_LAYER,
};
enum Oryx_Event_Code {
- ORYX_EVT_LAYER = WEBUSB_EVT_SAFE_RANGE,
- ORYX_EVT_LIVE_TRAINING,
- ORYX_EVT_LIVE_UPDATE_GET_KEYCODE,
- ORYX_EVT_LIVE_UPDATE_SET_KEYCODE,
- ORYX_EVT_LIVE_UPDATE_KEYMAP_RESET,
- ORYX_EVT_LIVE_UPDATE_GET_BUFFER,
- ORYX_EVT_LIVE_UPDATE_SET_BUFFER,
- ORYX_EVT_LIVE_UPDATE_GET_LAYER_COUNT,
- ORYX_EVT_LIVE_UPDATE_GET_MACRO_COUNT,
- ORYX_EVT_LIVE_UPDATE_GET_MACRO_BUFFER_SIZE,
- ORYX_EVT_LIVE_UPDATE_GET_MACRO_BUFFER,
- ORYX_EVT_LIVE_UPDATE_SET_MACRO_BUFFER,
- ORYX_EVT_LIVE_UPDATE_MACRO_RESET,
- ORYX_EVT_LIVE_UPDATE_EEPROM_RESET,
- ORYX_EVT_LIVE_UPDATE_KEYBOARD_RESET,
+ ORYX_EVT_GET_FW_VERSION,
+ ORYX_EVT_PAIRING_INPUT,
+ ORYX_EVT_PAIRING_KEY_INPUT,
+ ORYX_EVT_PAIRING_FAILED,
+ ORYX_EVT_PAIRING_SUCCESS,
+ ORYX_EVT_LAYER,
ORYX_EVT_KEYDOWN,
ORYX_EVT_KEYUP,
};
-#ifdef DYNAMIC_KEYMAP_ENABLE
-enum dynamic_macros_keycodes {
- MACRO00 = 0x5F12,
- MACRO01,
- MACRO02,
- MACRO03,
- MACRO04,
- MACRO05,
- MACRO06,
- MACRO07,
- MACRO08,
- MACRO09,
- MACRO10,
- MACRO11,
- MACRO12,
- MACRO13,
- MACRO14,
- MACRO15,
-};
-#endif
-
extern bool oryx_state_live_training_enabled;
-bool webusb_receive_oryx(uint8_t *data, uint8_t length);
+typedef struct {
+ bool pairing;
+ bool paired;
+} rawhid_state_t;
+
+extern rawhid_state_t rawhid_state;
+
+void create_pairing_code(void);
+bool store_pairing_sequence(keypos_t* pairing_sequence);
+keypos_t get_random_keypos(void);
+void pairing_init_handler(void);
+void pairing_validate_handler(void);
+void pairing_init_event(void);
+void pairing_key_input_event(void);
+void pairing_failed_event(void);
+void pairing_succesful_event(void);
+
void oryx_layer_event(void);
bool is_oryx_live_training_enabled(void);
-bool process_record_oryx(uint16_t keycode, keyrecord_t *record);
+bool process_record_oryx(uint16_t keycode, keyrecord_t* record);
void layer_state_set_oryx(layer_state_t state);
-void eeconfig_init_oryx(void);
-void matrix_init_oryx(void);
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 077e7d9d8f..7efe97ae52 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -258,7 +258,7 @@ bool process_record_quantum(keyrecord_t *record) {
#endif
#ifdef HAPTIC_ENABLE
process_haptic(keycode, record) &&
-#endif // HAPTIC_ENABLE
+#endif // HAPTIC_ENABLE
#ifdef ORYX_ENABLE
process_record_oryx(keycode, record) &&
#endif
@@ -412,7 +412,6 @@ bool process_record_quantum(keyrecord_t *record) {
}
}
-
return process_action_kb(record);
}
@@ -442,21 +441,19 @@ void matrix_scan_quantum() {
matrix_scan_kb();
}
-
#ifdef WEBUSB_ENABLE
-__attribute__((weak)) bool webusb_receive_user(uint8_t *data, uint8_t length) { return false; }
-__attribute__((weak)) bool webusb_receive_kb(uint8_t *data, uint8_t length) { return webusb_receive_user(data, length); }
+__attribute__((weak)) bool webusb_receive_user(uint8_t *data, uint8_t length) {
+ return false;
+}
+__attribute__((weak)) bool webusb_receive_kb(uint8_t *data, uint8_t length) {
+ return webusb_receive_user(data, length);
+}
bool webusb_receive_quantum(uint8_t *data, uint8_t length) {
-# ifdef ORYX_ENABLE
- return webusb_receive_oryx(data, length);
-# else
return webusb_receive_kb(data, length);
-# endif
}
#endif
-
//------------------------------------------------------------------------------
// Override these functions in your keymap file to play different tunes on
// different events such as startup and bootloader jump
@@ -465,7 +462,6 @@ __attribute__((weak)) void startup_user() {}
__attribute__((weak)) void shutdown_user() {}
-
void suspend_power_down_quantum(void) {
suspend_power_down_kb();
#ifndef NO_SUSPEND_POWER_DOWN
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 66cef7838a..04ae3d7f4d 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -49,6 +49,14 @@
extern keymap_config_t keymap_config;
#endif
+#ifdef RAW_ENABLE
+# include "raw_hid.h"
+#endif
+
+#ifdef ORYX_ENABLE
+# include "oryx.h"
+#endif
+
#ifdef WEBUSB_ENABLE
# include "webusb.h"
#endif
@@ -176,7 +184,6 @@ static const USBEndpointConfig shared_ep_config = {
};
#endif
-
#ifdef WEBUSB_ENABLE
/** Microsoft OS 2.0 Descriptor. This is used by Windows to select the USB driver for the device.
*
@@ -391,10 +398,10 @@ static usb_driver_configs_t drivers = {
#endif
#ifdef WEBUSB_ENABLE
-# define WEBUSB_IN_CAPACITY 4
-# define WEBUSB_OUT_CAPACITY 4
-# define WEBUSB_IN_MODE USB_EP_MODE_TYPE_INTR
-# define WEBUSB_OUT_MODE USB_EP_MODE_TYPE_INTR
+# define WEBUSB_IN_CAPACITY 4
+# define WEBUSB_OUT_CAPACITY 4
+# define WEBUSB_IN_MODE USB_EP_MODE_TYPE_INTR
+# define WEBUSB_OUT_MODE USB_EP_MODE_TYPE_INTR
.webusb_driver = QMK_USB_DRIVER_CONFIG(WEBUSB, 0, false),
#endif
#ifdef JOYSTICK_ENABLE
@@ -463,9 +470,9 @@ static inline void usb_event_wakeup_handler(void) {
suspend_wakeup_init();
usb_device_state_set_resume(USB_DRIVER.configuration != 0, USB_DRIVER.configuration);
#ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
- // NOTE: converters may not accept this
- led_set(host_keyboard_leds());
+ sleep_led_disable();
+ // NOTE: converters may not accept this
+ led_set(host_keyboard_leds());
#endif /* SLEEP_LED_ENABLE */
}
@@ -1145,7 +1152,15 @@ void raw_hid_send(uint8_t *data, uint8_t length) {
if (length != RAW_EPSIZE) {
return;
}
+
+# ifdef ORYX_ENABLE
+ if (chnWriteTimeout(&drivers.raw_driver.driver, data, length, TIME_IMMEDIATE) != length) {
+ rawhid_state.pairing = false;
+ rawhid_state.paired = false;
+ }
+# else
chnWrite(&drivers.raw_driver.driver, data, length);
+# endif
}
__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
@@ -1169,15 +1184,15 @@ void raw_hid_task(void) {
#ifdef WEBUSB_ENABLE
void webusb_send(uint8_t *data, uint8_t length) {
- if(chnWriteTimeout(&drivers.webusb_driver.driver, data, length, TIME_IMMEDIATE) != length){
- webusb_state.paired = false;
+ if (chnWriteTimeout(&drivers.webusb_driver.driver, data, length, TIME_IMMEDIATE) != length) {
+ webusb_state.paired = false;
webusb_state.pairing = false;
}
}
- // Users should #include "raw_hid.h" in their own code
- // and implement this function there. Leave this as weak linkage
- // so users can opt to not handle data coming in.
+// Users should #include "raw_hid.h" in their own code
+// and implement this function there. Leave this as weak linkage
+// so users can opt to not handle data coming in.
void webusb_task(void) {
uint8_t buffer[WEBUSB_EPSIZE];
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index bf005d519f..1084f67659 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -161,7 +161,10 @@ void raw_hid_send(uint8_t *data, uint8_t length) {
// Check to see if the host is ready to accept another packet
if (Endpoint_IsINReady()) {
// Write data
- Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL);
+ if (Endpoint_Write_Stream_LE(data, RAW_EPSIZE, NULL)) {
+ rawhid_state.pairing = false;
+ rawhid_state.paired = false;
+ }
// Finalize the stream transfer to send the last packet
Endpoint_ClearIN();
}
@@ -279,9 +282,9 @@ void webusb_send(uint8_t *data, uint8_t length) {
Endpoint_SelectEndpoint(WEBUSB_IN_EPNUM);
- if(Endpoint_Write_Stream_LE(data, length, NULL)) {
+ if (Endpoint_Write_Stream_LE(data, length, NULL)) {
// Stream failed to complete, resetting WEBUSB's state
- webusb_state.paired = false;
+ webusb_state.paired = false;
webusb_state.pairing = false;
}
Endpoint_ClearIN();
@@ -292,7 +295,6 @@ static void webusb_task(void) {
uint8_t data[WEBUSB_EPSIZE];
bool data_read = false;
-
// Device must be connected and configured for the task to run
if (USB_DeviceState != DEVICE_STATE_Configured) return;
@@ -543,9 +545,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) {
#endif
#ifdef WEBUSB_ENABLE
- /* Setup Webusb Endpoints */
- ConfigSuccess &= Endpoint_ConfigureEndpoint(WEBUSB_IN_EPADDR, EP_TYPE_INTERRUPT, WEBUSB_EPSIZE, 1);
- ConfigSuccess &= Endpoint_ConfigureEndpoint(WEBUSB_OUT_EPADDR, EP_TYPE_INTERRUPT, WEBUSB_EPSIZE, 1);
+ /* Setup Webusb Endpoints */
+ ConfigSuccess &= Endpoint_ConfigureEndpoint(WEBUSB_IN_EPADDR, EP_TYPE_INTERRUPT, WEBUSB_EPSIZE, 1);
+ ConfigSuccess &= Endpoint_ConfigureEndpoint(WEBUSB_OUT_EPADDR, EP_TYPE_INTERRUPT, WEBUSB_EPSIZE, 1);
#endif
#ifdef MIDI_ENABLE
@@ -697,23 +699,23 @@ void EVENT_USB_Device_ControlRequest(void) {
case WEBUSB_VENDOR_CODE:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE)) {
switch (USB_ControlRequest.wIndex) {
- case WebUSB_RTYPE_GetURL:
- switch (USB_ControlRequest.wValue) {
- case WEBUSB_LANDING_PAGE_INDEX:
- Endpoint_ClearSETUP();
- /* Write the descriptor data to the control endpoint */
- Endpoint_Write_Control_PStream_LE(&WebUSB_LandingPage, WebUSB_LandingPage.Header.Size);
- /* Release the endpoint after transaction. */
- Endpoint_ClearStatusStage();
+ case WebUSB_RTYPE_GetURL:
+ switch (USB_ControlRequest.wValue) {
+ case WEBUSB_LANDING_PAGE_INDEX:
+ Endpoint_ClearSETUP();
+ /* Write the descriptor data to the control endpoint */
+ Endpoint_Write_Control_PStream_LE(&WebUSB_LandingPage, WebUSB_LandingPage.Header.Size);
+ /* Release the endpoint after transaction. */
+ Endpoint_ClearStatusStage();
+ break;
+ default: /* Stall transfer on invalid index. */
+ Endpoint_StallTransaction();
+ break;
+ }
break;
- default: /* Stall transfer on invalid index. */
+ default: /* Stall on unknown WebUSB request */
Endpoint_StallTransaction();
break;
- }
- break;
- default: /* Stall on unknown WebUSB request */
- Endpoint_StallTransaction();
- break;
}
}
@@ -721,16 +723,16 @@ void EVENT_USB_Device_ControlRequest(void) {
case MS_OS_20_VENDOR_CODE:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE)) {
switch (USB_ControlRequest.wIndex) {
- case MS_OS_20_DESCRIPTOR_INDEX:
- Endpoint_ClearSETUP();
- /* Write the descriptor data to the control endpoint */
- Endpoint_Write_Control_PStream_LE(&MS_OS_20_Descriptor, MS_OS_20_Descriptor.Header.TotalLength);
- /* Release the endpoint after transaction. */
- Endpoint_ClearStatusStage();
- break;
- default: /* Stall on unknown MS OS 2.0 request */
- Endpoint_StallTransaction();
- break;
+ case MS_OS_20_DESCRIPTOR_INDEX:
+ Endpoint_ClearSETUP();
+ /* Write the descriptor data to the control endpoint */
+ Endpoint_Write_Control_PStream_LE(&MS_OS_20_Descriptor, MS_OS_20_Descriptor.Header.TotalLength);
+ /* Release the endpoint after transaction. */
+ Endpoint_ClearStatusStage();
+ break;
+ default: /* Stall on unknown MS OS 2.0 request */
+ Endpoint_StallTransaction();
+ break;
}
}
break;
@@ -896,7 +898,6 @@ static void send_consumer(uint16_t data) {
#endif
}
-
static void send_programmable_button(uint32_t data) {
#ifdef PROGRAMMABLE_BUTTON_ENABLE
static report_programmable_button_t r;
@@ -1209,7 +1210,7 @@ void protocol_post_task(void) {
#endif
#ifdef WEBUSB_ENABLE
- webusb_task();
+ webusb_task();
#endif
#if !defined(INTERRUPT_CONTROL_ENDPOINT)