Merge remote-tracking branch 'origin/master' into develop

master
QMK Bot 2022-05-31 05:03:28 +00:00
commit e869d089b7
59 changed files with 672 additions and 769 deletions

View File

@ -23,8 +23,8 @@
// clang-format off // clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT( [_QWERTY] = LAYOUT(
KC_VOLU, KC_MPLY, KC_MPRV, RESET, KC_VOLU, KC_MPLY, KC_MPRV, QK_BOOT,
KC_VOLD, KC_MUTE, KC_MNXT, RESET KC_VOLD, KC_MUTE, KC_MNXT, QK_BOOT
), ),
}; };

View File

@ -1,38 +0,0 @@
/* Copyright 2020 QMK
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file was auto-generated by:
* `qmk chibios-confmigrate -i keyboards/handwired/onekey/blackpill_f411/chconf.h -r platforms/chibios/common/configs/chconf.h`
*/
#pragma once
#define CH_CFG_ST_FREQUENCY 10000
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
#define CH_CFG_FACTORY_SEMAPHORES TRUE
#define CH_CFG_FACTORY_MAILBOXES TRUE
#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
#define CH_CFG_FACTORY_PIPES TRUE
#include_next <chconf.h>

View File

@ -71,6 +71,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 #define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 #define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
#define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100 #define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100
#define SERIAL_USART_SPEED 921600
// #define SERIAL_USART_PIN_SWAP // swap RX and TX pins on master // #define SERIAL_USART_PIN_SWAP // swap RX and TX pins on master
// To use the highest possible baudrate (3.75Mbit/s) uncomment the following // To use the highest possible baudrate (3.75Mbit/s) uncomment the following
// line, this can result in dropped communications so lower the speed if there // line, this can result in dropped communications so lower the speed if there
@ -102,8 +103,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PMW3360_SPI_MODE 3 #define PMW3360_SPI_MODE 3
#define PMW3360_SPI_DIVISOR 64 #define PMW3360_SPI_DIVISOR 64
#define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
# define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200 #define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 400
# define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 400 #define CHARYBDIS_MINIMUM_SNIPING_DPI 200
# define CHARYBDIS_MINIMUM_SNIPING_DPI 200 #define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 100
# define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 100

View File

@ -73,13 +73,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_________________RAISE_L1__________________, _________________RAISE_R1__________________, _________________RAISE_L1__________________, _________________RAISE_R1__________________,
_________________RAISE_L2__________________, _________________RAISE_R2__________________, _________________RAISE_L2__________________, _________________RAISE_R2__________________,
_________________RAISE_L3__________________, _________________RAISE_R3__________________, _________________RAISE_L3__________________, _________________RAISE_R3__________________,
REBOOT, KEYLOCK, _______, _______, _______ QK_RBT, _______, _______, _______, _______
), ),
[_ADJUST] = LAYOUT_charybdis_3x5_wrapper( [_ADJUST] = LAYOUT_charybdis_3x5_wrapper(
_________________ADJUST_L1_________________, _________________ADJUST_R1_________________, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________,
_________________ADJUST_L2_________________, _________________ADJUST_R2_________________, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________,
_________________ADJUST_L3_________________, _________________ADJUST_R3_________________, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________,
EEP_RST, KC_NUKE, _______, _______, RESET EE_CLR, KC_NUKE, _______, _______, QK_BOOT
), ),
}; };
@ -98,3 +98,9 @@ bool usb_vbus_state(void) {
return readPin(USB_VBUS_PIN); return readPin(USB_VBUS_PIN);
} }
#endif #endif
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
for (int32_t i = 0; i < 40; i++) {
__asm__ volatile("nop" ::: "memory");
}
}

View File

@ -1,38 +0,0 @@
/* Copyright 2020 QMK
*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* This file was auto-generated by:
* `qmk chibios-confmigrate -i keyboards/handwired/onekey/blackpill_f411/chconf.h -r platforms/chibios/common/configs/chconf.h`
*/
#pragma once
#define CH_CFG_ST_FREQUENCY 10000
#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
#define CH_CFG_FACTORY_SEMAPHORES TRUE
#define CH_CFG_FACTORY_MAILBOXES TRUE
#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
#define CH_CFG_FACTORY_PIPES TRUE
#include_next <chconf.h>

View File

@ -59,6 +59,7 @@
// // line, this can result in dropped communications so lower the speed if there // // line, this can result in dropped communications so lower the speed if there
// // are many timeouts. // // are many timeouts.
// // #define SERIAL_USART_SPEED (STM32_PCLK2 >> 4) // // #define SERIAL_USART_SPEED (STM32_PCLK2 >> 4)
#define SERIAL_USART_SPEED 921600
#define CRC8_USE_TABLE #define CRC8_USE_TABLE
#define CRC8_OPTIMIZE_SPEED #define CRC8_OPTIMIZE_SPEED

View File

@ -100,7 +100,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _________________LOWER_L3__________________, _________________LOWER_R3__________________, _______, _______, _________________LOWER_L3__________________, _________________LOWER_R3__________________, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______ _______, _______, _______
), ),
[_RAISE] = LAYOUT_charybdis_4x6_wrapper( [_RAISE] = LAYOUT_charybdis_4x6_wrapper(
KC_F12, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, KC_F11, KC_F12, _________________FUNC_LEFT_________________, _________________FUNC_RIGHT________________, KC_F11,
@ -109,8 +109,16 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _________________RAISE_L3__________________, _________________RAISE_R3__________________, _______, _______, _________________RAISE_L3__________________, _________________RAISE_R3__________________, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______ _______, _______, _______
) ),
[_ADJUST] = LAYOUT_charybdis_4x6_wrapper(
QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE, KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EE_CLR,
KEYLOCK, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS,
UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, KC_MPLY,
QK_RBT, AUTO_CTN, _______, KC_NUKE, _______,
_______, _______, _______
)
}; };
// clang-format on // clang-format on
@ -130,3 +138,9 @@ bool usb_vbus_state(void) {
return readPin(USB_VBUS_PIN); return readPin(USB_VBUS_PIN);
} }
#endif #endif
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
for (int32_t i = 0; i < 40; i++) {
__asm__ volatile("nop" ::: "memory");
}
}

View File

@ -78,8 +78,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_gergo_wrapper( [_ADJUST] = LAYOUT_gergo_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RESET, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, _______, KC_NUKE, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _______, KC_NUKE, _________________ADJUST_R2_________________, EE_CLR,
_______, _________________ADJUST_L3_________________, _______, _______, _______, _______, _________________ADJUST_R3_________________, TG_MODS, _______, _________________ADJUST_L3_________________, _______, _______, _______, _______, _________________ADJUST_R3_________________, TG_MODS,
_______, _______, _______, _______, _______, _______, _______, _______ _______, _______, _______, _______, _______, _______, _______, _______
), ),

View File

@ -105,8 +105,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______ _______, _______, _______, _______
), ),
[_ADJUST] = LAYOUT_4x6_right_wrapper( [_ADJUST] = LAYOUT_4x6_right_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RST, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS, UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS,
HPT_DWLI, HPT_DWLD, TG_GAME, TG_DBLO, HPT_DWLI, HPT_DWLD, TG_GAME, TG_DBLO,
HPT_TOG, HPT_BUZ, KC_NUKE, HPT_TOG, HPT_BUZ, KC_NUKE,

View File

@ -68,7 +68,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 #define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
#define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 #define SERIAL_USART_RX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7
#define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100 #define SERIAL_USART_TIMEOUT 100 // USART driver timeout. default 100
#define SERIAL_USART_SPEED 921600
#define CRC8_USE_TABLE #define CRC8_USE_TABLE
#define CRC8_OPTIMIZE_SPEED #define CRC8_OPTIMIZE_SPEED

View File

@ -58,3 +58,9 @@ bool usb_vbus_state(void) {
return readPin(USB_VBUS_PIN); return readPin(USB_VBUS_PIN);
} }
#endif #endif
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
for (int32_t i = 0; i < 40; i++) {
__asm__ volatile("nop" ::: "memory");
}
}

View File

@ -17,13 +17,19 @@
#pragma once #pragma once
#define DEBOUNCE 45 #define DEBOUNCE 45
#define ENCODER_DEFAULT_POS 0x3
#ifdef OLED_DRIVER_SH1107 #ifdef OLED_DRIVER_SH1107
# undef OLED_DISPLAY_128X64 # undef OLED_DISPLAY_128X64
#endif #endif
# define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200 #define CHARYBDIS_MINIMUM_DEFAULT_DPI 1200
# define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 200 #define CHARYBDIS_DEFAULT_DPI_CONFIG_STEP 200
# define CHARYBDIS_MINIMUM_SNIPING_DPI 400 #define CHARYBDIS_MINIMUM_SNIPING_DPI 400
# define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 200 #define CHARYBDIS_SNIPING_DPI_CONFIG_STEP 200
#define ENCODER_DEFAULT_POS 0x3
#define SECURE_UNLOCK_SEQUENCE \
{ \
{ 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 } \
}

View File

@ -120,25 +120,24 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______ _______, _______, _______, _______
), ),
[_ADJUST] = LAYOUT_5x6_right_wrapper( [_ADJUST] = LAYOUT_5x6_right_wrapper(
KC_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE, KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, KC_RST, QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE, KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EEP_RST, VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EE_CLR,
KEYLOCK, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS, KEYLOCK, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS,
UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, KC_MPLY, UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, KC_MPLY,
TG(_DIABLOII), AUTO_CTN, TG_GAME, TG_DBLO, TG(_DIABLOII), AUTO_CTN, TG_GAME, TG_DBLO,
_______, REBOOT, KC_NUKE, _______, QK_RBT, KC_NUKE,
_______, _______, _______, _______, _______, _______,
_______, _______, KC_NUKE, _______ _______, _______, KC_NUKE, _______
), ),
}; };
#define BASE_ENCODERS { { KC_VOLD, KC_VOLU }, { KC_WH_D, KC_WH_U } }
#ifdef ENCODER_MAP_ENABLE #ifdef ENCODER_MAP_ENABLE
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = { const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
[_DEFAULT_LAYER_1] = BASE_ENCODERS, [_DEFAULT_LAYER_1] = { { KC_VOLD, KC_VOLU }, { KC_WH_D, KC_WH_U } },
[_DEFAULT_LAYER_2] = BASE_ENCODERS, [_DEFAULT_LAYER_2] = { { _______, _______ }, { _______, _______ } },
[_DEFAULT_LAYER_3] = BASE_ENCODERS, [_DEFAULT_LAYER_3] = { { _______, _______ }, { _______, _______ } },
[_DEFAULT_LAYER_4] = BASE_ENCODERS, [_DEFAULT_LAYER_4] = { { _______, _______ }, { _______, _______ } },
[_GAMEPAD] = { { _______, _______ }, { _______, _______ } }, [_GAMEPAD] = { { _______, _______ }, { _______, _______ } },
[_DIABLO] = { { _______, _______ }, { _______, _______ } }, [_DIABLO] = { { _______, _______ }, { _______, _______ } },
[_MOUSE] = { { _______, _______ }, { KC_WH_D, KC_WH_U } }, [_MOUSE] = { { _______, _______ }, { KC_WH_D, KC_WH_U } },
@ -188,15 +187,15 @@ bool encoder_update_user(uint8_t index, bool clockwise) {
#endif #endif
#ifdef OLED_ENABLE #ifdef OLED_ENABLE
extern uint16_t typing_mode; # include "keyrecords/unicode.h"
oled_rotation_t oled_init_keymap(oled_rotation_t rotation) { oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
return OLED_ROTATION_180; return OLED_ROTATION_180;
} }
void oled_render_large_display(void) { void oled_render_large_display(bool side) {
if (is_keyboard_left()) { if (side) {
render_wpm_graph(54, 64); render_wpm_graph(56, 64);
} else { } else {
oled_advance_page(true); oled_advance_page(true);
oled_advance_page(true); oled_advance_page(true);
@ -214,25 +213,25 @@ void oled_render_large_display(void) {
oled_set_cursor(1, 14); oled_set_cursor(1, 14);
oled_write_ln_P(PSTR("Unicode:"), false); oled_write_ln_P(PSTR("Unicode:"), false);
switch (typing_mode) { switch (typing_mode) {
case KC_WIDE: case UCTM_WIDE:
oled_write_P(PSTR(" Wide"), false); oled_write_P(PSTR(" Wide"), false);
break; break;
case KC_SCRIPT: case UCTM_SCRIPT:
oled_write_P(PSTR(" Script"), false); oled_write_P(PSTR(" Script"), false);
break; break;
case KC_BLOCKS: case UCTM_BLOCKS:
oled_write_P(PSTR(" Blocks"), false); oled_write_P(PSTR(" Blocks"), false);
break; break;
case KC_REGIONAL: case UCTM_REGIONAL:
oled_write_P(PSTR(" Regional"), false); oled_write_P(PSTR(" Regional"), false);
break; break;
case KC_AUSSIE: case UCTM_AUSSIE:
oled_write_P(PSTR(" Aussie"), false); oled_write_P(PSTR(" Aussie"), false);
break; break;
case KC_ZALGO: case UCTM_ZALGO:
oled_write_P(PSTR(" Zalgo"), false); oled_write_P(PSTR(" Zalgo"), false);
break; break;
case KC_NOMODE: case UCTM_NO_MODE:
oled_write_P(PSTR(" Normal"), false); oled_write_P(PSTR(" Normal"), false);
break; break;
default: default:

View File

@ -32,6 +32,9 @@ ifeq ($(strip $(KEYBOARD)), handwired/tractyl_manuform/5x6_right/teensy2pp)
AUTOCORRECTION_ENABLE = no AUTOCORRECTION_ENABLE = no
CAPS_WORD_ENABLE = yes CAPS_WORD_ENABLE = yes
endif endif
ifeq ($(strip $(KEYBOARD)), handwired/tractyl_manuform/5x6_right/f411)
BOOTLOADER = tinyuf2
endif
# DEBOUNCE_TYPE = sym_eager_pk # DEBOUNCE_TYPE = sym_eager_pk
OLED_DRIVER = custom OLED_DRIVER = custom

View File

@ -91,8 +91,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_wrapper( [_ADJUST] = LAYOUT_wrapper(
KC_MAKE, _______, _______, _______, _______, _______, _________________ADJUST_R1_________________, KC_RST, QK_MAKE, _______, _______, _______, _______, _______, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L1_________________, KC_NUKE, _______, _______, _______, _______, EEP_RST, VRSN, _________________ADJUST_L1_________________, KC_NUKE, _______, _______, _______, _______, EE_CLR,
_______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS, _______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, TG_MODS,
_______, _________________ADJUST_L3_________________, TG_GAME, _______, _________________ADJUST_R3_________________, KC_MPLY, _______, _________________ADJUST_L3_________________, TG_GAME, _______, _________________ADJUST_R3_________________, KC_MPLY,
_______, _______, _______, _______, _______, _______ _______, _______, _______, _______, _______, _______

View File

@ -51,8 +51,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_MEDIA] = LAYOUT_ortho_5x7( [_MEDIA] = LAYOUT_ortho_5x7(
KC_MAKE, RESET, MU_TOG, AU_ON, AU_OFF, CK_TOGG, RGB_SAD, QK_MAKE, QK_BOOT, MU_TOG, AU_ON, AU_OFF, CK_TOGG, RGB_SAD,
_______, EEP_RST, KC_RGB_T,RGB_M_P, RGB_M_B, RGB_M_R, RGB_SAI, _______, EE_CLR, KC_RGB_T,RGB_M_P, RGB_M_B, RGB_M_R, RGB_SAI,
RGB_TOG, RGB_MOD, RGB_RMOD,RGB_M_SW,RGB_M_SN,RGB_M_K, RGB_HUD, RGB_TOG, RGB_MOD, RGB_RMOD,RGB_M_SW,RGB_M_SN,RGB_M_K, RGB_HUD,
KC_MPLY, KC_MPRV, KC_MNXT, RGB_M_X, RGB_M_G, RGB_M_P, RGB_HUI, KC_MPLY, KC_MPRV, KC_MNXT, RGB_M_X, RGB_M_G, RGB_M_P, RGB_HUI,
KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, XXXXXXX, RGB_VAD, RGB_VAI KC_MUTE, KC_VOLD, KC_VOLU, XXXXXXX, XXXXXXX, RGB_VAD, RGB_VAI

View File

@ -75,8 +75,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_wrapper( [_ADJUST] = LAYOUT_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, KC_NUKE, _________________ADJUST_R1_________________, KC_RST, QK_MAKE, _________________ADJUST_L1_________________, KC_NUKE, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, MG_NKRO, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, MG_NKRO, _________________ADJUST_R2_________________, EE_CLR,
TG_MODS, _________________ADJUST_L3_________________, KC_RGB_T,_________________ADJUST_R3_________________, RGB_IDL TG_MODS, _________________ADJUST_L3_________________, KC_RGB_T,_________________ADJUST_R3_________________, RGB_IDL
) )
}; };

View File

@ -79,7 +79,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_Q, CALTDEL, \ KC_Q, CALTDEL, \
KC_A, TSKMGR, \ KC_A, TSKMGR, \
KC_Z, KC_X, \ KC_Z, KC_X, \
_______, RESET \ _______, QK_BOOT \
) )
}; };

View File

@ -18,5 +18,10 @@
#pragma once #pragma once
#define TAPPING_TERM_PER_KEY #define TAPPING_TERM_PER_KEY
#define WAIT_FOR_USB // #define WAIT_FOR_USB
// #define NO_USB_STARTUP_CHECK // #define NO_USB_STARTUP_CHECK
#define SECURE_UNLOCK_SEQUENCE \
{ \
{ 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 } \
}

View File

@ -106,12 +106,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_moonlander_wrapper( [_ADJUST] = LAYOUT_moonlander_wrapper(
KC_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE,_______, KC_NUKE,KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, KC_RST, QK_MAKE, KC_WIDE,KC_AUSSIE,KC_SCRIPT,KC_ZALGO,KC_NOMODE,_______, KC_NUKE,KC_NOMODE,KC_BLOCKS,KC_REGIONAL,_______,_______, QK_BOOT,
VRSN, _________________ADJUST_L1_________________, TG(_DIABLOII), _______, _________________ADJUST_R1_________________, EEP_RST, VRSN, _________________ADJUST_L1_________________, TG(_DIABLOII), _______, _________________ADJUST_R1_________________, EE_CLR,
KEYLOCK, _________________ADJUST_L2_________________, _______, _______, _________________ADJUST_R2_________________, RGB_IDL, KEYLOCK, _________________ADJUST_L2_________________, _______, _______, _________________ADJUST_R2_________________, RGB_IDL,
UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS, UC_MOD, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, AUTO_CTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, AUTO_CTN,
REBOOT, _______, _______, _______, _______, _______ QK_RBT, _______, _______, _______, _______, _______
), ),
}; };

View File

@ -61,8 +61,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_wrapper(\ [_ADJUST] = LAYOUT_wrapper(\
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RESET, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, _______, _______, _______, KC_NUKE, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _______, _______, _______, KC_NUKE, _________________ADJUST_R2_________________, EE_CLR,
TG_MODS, _________________ADJUST_L3_________________, _______, _______, _______, _______, _______, _______, _________________ADJUST_R3_________________, KC_MPLY TG_MODS, _________________ADJUST_L3_________________, _______, _______, _______, _______, _______, _______, _________________ADJUST_R3_________________, KC_MPLY
) )

View File

@ -27,3 +27,5 @@
#define RGBLIGHT_EFFECT_KNIGHT #define RGBLIGHT_EFFECT_KNIGHT
#define RGBLIGHT_EFFECT_TWINKLE #define RGBLIGHT_EFFECT_TWINKLE
#define RGBLIGHT_SLEEP #define RGBLIGHT_SLEEP
#define MOUSE_EXT_REPORT

View File

@ -23,7 +23,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(/* Base */ [0] = LAYOUT(/* Base */
C(KC_C), KC_BTN1, KC_BTN3, KC_BTN2, MO(1), KC_BTN4, KC_BTN5, DPI_CONFIG), C(KC_C), KC_BTN1, KC_BTN3, KC_BTN2, MO(1), KC_BTN4, KC_BTN5, DPI_CONFIG),
[1] = LAYOUT(/* Base */ [1] = LAYOUT(/* Base */
RGB_HUI, RGB_MOD, RGB_TOG, RGB_RMOD, MO(1), KC_VOLU, KC_VOLD, RESET) RGB_HUI, RGB_MOD, RGB_TOG, RGB_RMOD, MO(1), KC_VOLU, KC_VOLD, QK_BOOT)
}; };

View File

@ -46,5 +46,4 @@
#define BOOTMAGIC_LITE_ROW_RIGHT 4 #define BOOTMAGIC_LITE_ROW_RIGHT 4
#define BOOTMAGIC_LITE_COLUMN_RIGHT 7 #define BOOTMAGIC_LITE_COLUMN_RIGHT 7
#define I2C1_CLOCK_SPEED 400000 #define SERIAL_USART_SPEED 921600
#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2

View File

@ -90,10 +90,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
), ),
[_ADJUST] = LAYOUT_wrapper( [_ADJUST] = LAYOUT_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RESET, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
UC_MOD, _________________ADJUST_L3_________________, HPT_TOG, HPT_FBK, MG_NKRO, UC_MOD, _________________ADJUST_R3_________________, TG_MODS, UC_MOD, _________________ADJUST_L3_________________, HPT_TOG, HPT_FBK, MG_NKRO, UC_MOD, _________________ADJUST_R3_________________, TG_MODS,
REBOOT, _______, KEYLOCK, KC_NUKE, _______, _______, _______, _______, _______, AUTO_CTN QK_RBT, _______, KEYLOCK, KC_NUKE, _______, _______, _______, _______, _______, AUTO_CTN
), ),
// [_LAYERINDEX] = LAYOUT_wrapper( // [_LAYERINDEX] = LAYOUT_wrapper(
// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, // _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
@ -105,7 +105,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
#ifdef ENCODER_MAP_ENABLE #ifdef ENCODER_MAP_ENABLE
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = { const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
[_DEFAULT_LAYER_1] = { { KC_DOWN, KC_UP }, { KC_VOLD, KC_VOLU } }, [_DEFAULT_LAYER_1] = { { KC_VOLD, KC_VOLU }, { KC_WH_D, KC_WH_U } },
[_DEFAULT_LAYER_2] = { { _______, _______ }, { _______, _______ } }, [_DEFAULT_LAYER_2] = { { _______, _______ }, { _______, _______ } },
[_DEFAULT_LAYER_3] = { { _______, _______ }, { _______, _______ } }, [_DEFAULT_LAYER_3] = { { _______, _______ }, { _______, _______ } },
[_DEFAULT_LAYER_4] = { { _______, _______ }, { _______, _______ } }, [_DEFAULT_LAYER_4] = { { _______, _______ }, { _______, _______ } },
@ -129,9 +129,9 @@ oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
#endif #endif
} }
void oled_render_large_display(void) { void oled_render_large_display(bool side) {
if (is_keyboard_left()) { if (side) {
render_wpm_graph(54, 64); render_wpm_graph(56, 64);
} else { } else {
static const char PROGMEM kyria_logo[] = { static const char PROGMEM kyria_logo[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,192,224,240,112,120, 56, 60, 28, 30, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 30, 28, 60, 56,120,112,240,224,192,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,192,224,240,112,120, 56, 60, 28, 30, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 30, 28, 60, 56,120,112,240,224,192,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -149,27 +149,6 @@ void oled_render_large_display(void) {
} }
#endif #endif
#ifdef ENCODER_ENABLE
bool encoder_update_user(uint8_t index, bool clockwise) {
if (index == 0) {
// Volume control
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
} else if (index == 1) {
// Page up/Page down
if (clockwise) {
tap_code(KC_PGDN);
} else {
tap_code(KC_PGUP);
}
}
return true;
}
#endif
#ifdef RGBLIGHT_LAYERS #ifdef RGBLIGHT_LAYERS
const rgblight_segment_t PROGMEM shift_layers[] = RGBLIGHT_LAYER_SEGMENTS({8, 1, 120, 255, 255}, {18, 1, 120, 255, 255}); const rgblight_segment_t PROGMEM shift_layers[] = RGBLIGHT_LAYER_SEGMENTS({8, 1, 120, 255, 255}, {18, 1, 120, 255, 255});
const rgblight_segment_t PROGMEM control_layers[] = RGBLIGHT_LAYER_SEGMENTS({6, 1, 0, 255, 255}, {16, 1, 0, 255, 255}); const rgblight_segment_t PROGMEM control_layers[] = RGBLIGHT_LAYER_SEGMENTS({6, 1, 0, 255, 255}, {16, 1, 0, 255, 255});
@ -188,3 +167,12 @@ void matrix_scan_keymap(void) {
rgblight_set_layer_state(3, mods & MOD_MASK_GUI); rgblight_set_layer_state(3, mods & MOD_MASK_GUI);
} }
#endif #endif
#ifdef KEYBOARD_splitkb_kyria_rev1_proton_c
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
for (int32_t i = 0; i < 40; i++) {
__asm__ volatile("nop" ::: "memory");
}
}
#endif

View File

@ -17,11 +17,10 @@ ifeq ($(strip $(KEYBOARD)), splitkb/kyria/rev1/proton_c)
TAP_DANCE_ENABLE = yes TAP_DANCE_ENABLE = yes
SWAP_HANDS_ENABLE = yes SWAP_HANDS_ENABLE = yes
LTO_ENABLE = no LTO_ENABLE = no
CTPC = yes ENCODER_MAP_ENABLE = yes
AUTOCORRECTION_ENABLE = yes AUTOCORRECTION_ENABLE = yes
CAPS_WORD_ENABLE = yes CAPS_WORD_ENABLE = yes
OLED_DRIVER = custom OLED_DRIVER = custom
DEBUG_MATRIX_SCAN_RATE_ENABLE = api
else else
LTO_ENABLE = yes LTO_ENABLE = yes
BOOTLOADER = qmk-hid BOOTLOADER = qmk-hid

View File

@ -30,7 +30,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_P1, KC_P2, KC_P3 KC_P1, KC_P2, KC_P3
), ),
[1] = LAYOUT_ortho_4x3( /* Layer 1 */ [1] = LAYOUT_ortho_4x3( /* Layer 1 */
RESET, _______, XXXXXXX, QK_BOOT, _______, XXXXXXX,
AU_ON, AU_OFF, XXXXXXX, AU_ON, AU_OFF, XXXXXXX,
CK_TOGG, XXXXXXX, CK_UP, CK_TOGG, XXXXXXX, CK_UP,
CK_RST, XXXXXXX, CK_DOWN CK_RST, XXXXXXX, CK_DOWN

View File

@ -83,8 +83,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_wrapper( [_ADJUST] = LAYOUT_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RST, _______, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT, _______,
VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
_______, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL, _______, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL,
KEYLOCK, _______, _______, _______, _______, KC_NUKE, _______, _______, _______, _______, _______, TG_MODS KEYLOCK, _______, _______, _______, _______, KC_NUKE, _______, _______, _______, _______, _______, TG_MODS
) )

View File

@ -167,8 +167,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_ergodox_pretty_wrapper( [_ADJUST] = LAYOUT_ergodox_pretty_wrapper(
KC_MAKE, _______, _______, _______, _______, _______, UC_MOD, KC_NUKE, _________________ADJUST_R1_________________, KC_RST, QK_MAKE, _______, _______, _______, _______, _______, UC_MOD, KC_NUKE, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L1_________________, _______, _______, _________________ADJUST_R1_________________, EEP_RST, VRSN, _________________ADJUST_L1_________________, _______, _______, _________________ADJUST_R1_________________, EE_CLR,
_______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, RGB_IDL, _______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, RGB_IDL,
KEYLOCK, _________________ADJUST_L3_________________, _______, _______, _________________ADJUST_R3_________________, TG_MODS, KEYLOCK, _________________ADJUST_L3_________________, _______, _______, _________________ADJUST_R3_________________, TG_MODS,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,

View File

@ -29,7 +29,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_GAMEPAD] = LAYOUT_numpad_5x6( [_GAMEPAD] = LAYOUT_numpad_5x6(
RGB_TOG, _______, _______, EEP_RST, KC_MAKE, RESET, RGB_TOG, _______, _______, EE_CLR, QK_MAKE, QK_BOOT,
RGB_MOD, RGB_RMOD, _______, _______, _______, RGB_MOD, RGB_RMOD, _______, _______, _______,
RGB_HUI, RGB_HUD, _______, _______, _______, _______, RGB_HUI, RGB_HUD, _______, _______, _______, _______,
RGB_SAI, RGB_SAD, _______, _______, _______, RGB_SAI, RGB_SAD, _______, _______, _______,

View File

@ -103,10 +103,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_ortho_4x12_wrapper( [_ADJUST] = LAYOUT_ortho_4x12_wrapper(
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RST, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
TH_LVL, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL, TH_LVL, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL,
KEYLOCK, _______, _______, REBOOT, _______, KC_NUKE, _______, _______, AUTO_CTN,_______, _______, TG_MODS KEYLOCK, _______, _______, QK_RBT, _______, KC_NUKE, _______, _______, AUTO_CTN,_______, _______, TG_MODS
) )
}; };

View File

@ -121,8 +121,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------' * `-----------------------------------------------------------------------------------'
*/ */
[_ADJUST] = LAYOUT_ortho_5x12_wrapper( \ [_ADJUST] = LAYOUT_ortho_5x12_wrapper( \
KC_MAKE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RST, QK_MAKE, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, QK_BOOT,
VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EEP_RST, VRSN, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, EE_CLR,
_______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, RGB_IDL, _______, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, RGB_IDL,
KEYLOCK, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS, KEYLOCK, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, TG_MODS,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______

View File

@ -87,10 +87,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
), ),
[_ADJUST] = LAYOUT_split_3x6_3_wrapper( \ [_ADJUST] = LAYOUT_split_3x6_3_wrapper( \
KC_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, KC_RESET, QK_MAKE, _________________ADJUST_L1_________________, _________________ADJUST_R1_________________, QK_BOOT,
VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EEP_RST, VRSN, _________________ADJUST_L2_________________, _________________ADJUST_R2_________________, EE_CLR,
KEYLOCK, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL, KEYLOCK, _________________ADJUST_L3_________________, _________________ADJUST_R3_________________, RGB_IDL,
REBOOT, KC_NUKE, _______, _______, TG_MODS, AUTO_CTN QK_RBT, KC_NUKE, _______, _______, TG_MODS, AUTO_CTN
) )
}; };
// clang-format on // clang-format on
@ -120,7 +120,9 @@ uint32_t anim_frame_duration = 500;
uint8_t current_sleep_frame = 0; uint8_t current_sleep_frame = 0;
uint8_t current_wake_frame = 0; // uncomment if WAKE_FRAMES >1 uint8_t current_wake_frame = 0; // uncomment if WAKE_FRAMES >1
uint8_t current_kaki_frame = 0; uint8_t current_kaki_frame = 0;
#ifdef SWAP_HANDS_ENABLE
uint8_t current_rtogi_frame = 0; uint8_t current_rtogi_frame = 0;
#endif
// uint8_t current_ltogi_frame = 0; // uint8_t current_ltogi_frame = 0;
// clang-format off // clang-format off
void render_small_kitty(void) { void render_small_kitty(void) {
@ -171,6 +173,7 @@ void render_small_kitty(void) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x0a, 0x0e, 0x1d, 0x95, 0x24, 0x24, 0x27, 0x13, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x0a, 0x0e, 0x1d, 0x95, 0x24, 0x24, 0x27, 0x13, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x14, 0x08,
}}; }};
#ifdef SWAP_HANDS_ENABLE
static const char PROGMEM rtogi[KAKI_FRAMES][ANIM_SIZE] = {{ static const char PROGMEM rtogi[KAKI_FRAMES][ANIM_SIZE] = {{
// 'rtogi1', 32x32px // 'rtogi1', 32x32px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x90, 0x10, 0x20, 0xf0, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x90, 0x10, 0x20, 0xf0, 0xf8, 0xf8,
@ -184,15 +187,20 @@ void render_small_kitty(void) {
0x0f, 0x11, 0x22, 0x44, 0x48, 0x4c, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x06, 0x01, 0x0f, 0x11, 0x22, 0x44, 0x48, 0x4c, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x06, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}}; }};
#endif
// assumes 1 frame prep stage // assumes 1 frame prep stage
#ifdef SWAP_HANDS_ENABLE
extern bool swap_hands; extern bool swap_hands;
#endif
void animation_phase(void) { void animation_phase(void) {
#ifdef SWAP_HANDS_ENABLE
if (swap_hands) { if (swap_hands) {
anim_frame_duration = 300; anim_frame_duration = 300;
current_rtogi_frame = (current_rtogi_frame + 1) % RTOGI_FRAMES; current_rtogi_frame = (current_rtogi_frame + 1) % RTOGI_FRAMES;
oled_write_raw_P(rtogi[abs((RTOGI_FRAMES - 1) - current_rtogi_frame)], ANIM_SIZE); oled_write_raw_P(rtogi[abs((RTOGI_FRAMES - 1) - current_rtogi_frame)], ANIM_SIZE);
} else { } else
#endif
{
if (get_current_wpm() <= SLEEP_SPEED) { if (get_current_wpm() <= SLEEP_SPEED) {
anim_frame_duration = 500; anim_frame_duration = 500;
current_sleep_frame = (current_sleep_frame + 1) % SLEEP_FRAMES; current_sleep_frame = (current_sleep_frame + 1) % SLEEP_FRAMES;

View File

@ -14,13 +14,21 @@ UNICODE_ENABLE = no # Unicode
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight.
SWAP_HANDS_ENABLE = no # Enable one-hand typing SWAP_HANDS_ENABLE = no # Enable one-hand typing
ifeq ($(strip $(KEYBOARD)), crkbd/rev1) USE_ARM_CONFIG ?= no
OLED_ENABLE = yes ifeq ($(strip $(CONVERT_TO)), proton_c)
RGB_MATRIX_ENABLE = yes USE_ARM_CONFIG = yes
HAPTIC_ENABLE = no endif
ifeq ($(strip $(CTPC)), yes)
USE_ARM_CONFIG = yes
endif
ifeq ($(strip $(MCU)), STM32F303)
USE_ARM_CONFIG = yes
endif
ifeq ($(strip $(MCU)), STM32F401)
USE_ARM_CONFIG = yes
endif endif
ifeq ($(strip $(CTPC)), yes) ifeq ($(strip $(USE_ARM_CONFIG)), yes)
HAPTIC_ENABLE = no HAPTIC_ENABLE = no
WS2812_DRIVER = pwm # won't work without a patch to the ctpc mk file WS2812_DRIVER = pwm # won't work without a patch to the ctpc mk file
SERIAL_DRIVER = usart SERIAL_DRIVER = usart
@ -33,3 +41,13 @@ else
BOOTLOADER = qmk-hid BOOTLOADER = qmk-hid
BOOTLOADER_SIZE = 512 BOOTLOADER_SIZE = 512
endif endif
ifeq ($(strip $(KEYBOARD)), crkbd/rev1)
OLED_ENABLE = yes
RGB_MATRIX_ENABLE = yes
HAPTIC_ENABLE = no
endif
ifeq ($(strip $(KEYBOARD)), cantor)
SWAP_HANDS_ENABLE = no
endif

View File

@ -0,0 +1,5 @@
#if __has_include("../qmk_secrets/autocorrection_data.h")
# include "../qmk_secrets/autocorrection_data.h"
#else
# include "autocorrect_data_default.h"
#endif

View File

@ -87,6 +87,9 @@ void suspend_power_down_user(void) {
__attribute__((weak)) void suspend_wakeup_init_keymap(void) {} __attribute__((weak)) void suspend_wakeup_init_keymap(void) {}
void suspend_wakeup_init_user(void) { void suspend_wakeup_init_user(void) {
#ifdef OLED_ENABLE
oled_timer_reset();
#endif
suspend_wakeup_init_keymap(); suspend_wakeup_init_keymap();
} }

View File

@ -23,6 +23,3 @@ void matrix_init_unicode(void);
#ifdef SPLIT_KEYBOARD #ifdef SPLIT_KEYBOARD
void matrix_slave_scan_keymap(void); void matrix_slave_scan_keymap(void);
#endif #endif
#ifdef CAPS_WORD_ENABLE
# include "keyrecords/caps_word.h"
#endif

View File

@ -37,9 +37,9 @@
// # define WPM_LAUNCH_CONTROL // # define WPM_LAUNCH_CONTROL
// # define WPM_ALLOW_COUNT_REGRESSOIN // # define WPM_ALLOW_COUNT_REGRESSOIN
// # define WPM_UNFILTERED // # define WPM_UNFILTERED
# define WPM_SAMPLE_SECONDS 6 # define WPM_SAMPLE_SECONDS 10
# define WPM_SAMPLE_PERIODS 50 # define WPM_SAMPLE_PERIODS 50
# define WPM_ESTIMATED_WORD_SIZE 6 # define WPM_ESTIMATED_WORD_SIZE 5
#endif #endif
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
@ -291,6 +291,12 @@
# ifndef OLED_BRIGHTNESS # ifndef OLED_BRIGHTNESS
# define OLED_BRIGHTNESS 50 # define OLED_BRIGHTNESS 50
# endif # endif
# undef OLED_UPDATE_INTERVAL # if !defined(STM32F4XX)
# define OLED_UPDATE_INTERVAL 100 # undef OLED_UPDATE_INTERVAL
# define OLED_UPDATE_INTERVAL 75
# endif
#endif #endif
#define ENABLE_COMPILE_KEYCODE
#define BOTH_SHIFTS_TURNS_ON_CAPS_WORD

View File

@ -10,6 +10,13 @@
# pragma GCC push_options # pragma GCC push_options
# pragma GCC optimize("O0") # pragma GCC optimize("O0")
# include "autocorrection_data.h" # include "autocorrection_data.h"
# ifndef AUTOCORRECTION_MIN_LENGTH
# define AUTOCORRECTION_MIN_LENGTH AUTOCORRECT_MIN_LENGTH
# endif
# ifndef AUTOCORRECTION_MAX_LENGTH
# define AUTOCORRECTION_MAX_LENGTH AUTOCORRECT_MAX_LENGTH
# endif
# define autocorrection_data autocorrect_data
# if AUTOCORRECTION_MIN_LENGTH < 4 # if AUTOCORRECTION_MIN_LENGTH < 4
# error Minimum Length is too short and may cause overflows # error Minimum Length is too short and may cause overflows
# endif # endif
@ -17,6 +24,138 @@
# error Dictionary size excees maximum size permitted # error Dictionary size excees maximum size permitted
# endif # endif
static uint8_t typo_buffer[AUTOCORRECT_MAX_LENGTH] = {KC_SPC};
static uint8_t typo_buffer_size = 1;
/**
* @brief function for querying the enabled state of autocorrect
*
* @return true if enabled
* @return false if disabled
*/
bool autocorrect_is_enabled(void) {
return userspace_config.autocorrection;
}
/**
* @brief Enables autocorrect and saves state to eeprom
*
*/
void autocorrect_enable(void) {
userspace_config.autocorrection = true;
eeconfig_update_user(userspace_config.raw);
}
/**
* @brief Disables autocorrect and saves state to eeprom
*
*/
void autocorrect_disable(void) {
userspace_config.autocorrection = false;
typo_buffer_size = 0;
eeconfig_update_user(userspace_config.raw);
}
/**
* @brief Toggles autocorrect's status and save state to eeprom
*
*/
void autocorrect_toggle(void) {
userspace_config.autocorrection = !userspace_config.autocorrection;
typo_buffer_size = 0;
eeconfig_update_user(userspace_config.raw);
}
/**
* @brief handler for determining if autocorrect should process keypress
*
* @param keycode Keycode registered by matrix press, per keymap
* @param record keyrecord_t structure
* @param typo_buffer_size passed along to allow resetting of autocorrect buffer
* @param mods allow processing of mod status
* @return true Allow autocorection
* @return false Stop processing and escape from autocorrect.
*/
__attribute__((weak)) bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) {
// See quantum_keycodes.h for reference on these matched ranges.
switch (*keycode) {
// Exclude these keycodes from processing.
case KC_LSFT:
case KC_RSFT:
case KC_CAPS:
case QK_TO ... QK_ONE_SHOT_LAYER_MAX:
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_MOD_MAX:
case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
return false;
// Mask for base keycode from shifted keys.
case QK_LSFT ... QK_LSFT + 255:
case QK_RSFT ... QK_RSFT + 255:
if (*keycode >= QK_LSFT && *keycode <= (QK_LSFT + 255)) {
*mods |= MOD_LSFT;
} else {
*mods |= MOD_RSFT;
}
*keycode &= 0xFF; // Get the basic keycode.
return true;
#ifndef NO_ACTION_TAPPING
// Exclude tap-hold keys when they are held down
// and mask for base keycode when they are tapped.
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
# ifdef NO_ACTION_LAYER
// Exclude Layer Tap, if layers are disabled
// but action tapping is still enabled.
return false;
# endif
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
// Exclude hold keycode
if (!record->tap.count) {
return false;
}
*keycode &= 0xFF;
break;
#else
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
// Exclude if disabled
return false;
#endif
// Exclude swap hands keys when they are held down
// and mask for base keycode when they are tapped.
case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
#ifdef SWAP_HANDS_ENABLE
if (*keycode >= 0x56F0 || !record->tap.count) {
return false;
}
*keycode &= 0xFF;
break;
#else
// Exclude if disabled
return false;
#endif
}
// Disable autocorrect while a mod other than shift is active.
if ((*mods & ~MOD_MASK_SHIFT) != 0) {
*typo_buffer_size = 0;
return false;
}
return true;
}
/**
* @brief handling for when autocorrection has been triggered
*
* @param backspaces number of characters to remove
* @param str pointer to PROGMEM string to replace mistyped seletion with
* @return true apply correction
* @return false user handled replacement
*/
__attribute__((weak)) bool apply_autocorrect(uint8_t backspaces, const char *str) {
return true;
}
/** /**
* @brief Process handler for autocorrect feature * @brief Process handler for autocorrect feature
* *
@ -25,131 +164,124 @@
* @return true Continue processing keycodes, and send to host * @return true Continue processing keycodes, and send to host
* @return false Stop processing keycodes, and don't send to host * @return false Stop processing keycodes, and don't send to host
*/ */
bool process_autocorrection(uint16_t keycode, keyrecord_t* record) { bool process_autocorrection(uint16_t keycode, keyrecord_t *record) {
static uint8_t typo_buffer[AUTOCORRECTION_MAX_LENGTH] = {KC_SPC}; uint8_t mods = get_mods();
static uint8_t typo_buffer_size = 1; #ifndef NO_ACTION_ONESHOT
mods |= get_oneshot_mods();
#endif
if (keycode == AUTO_CTN) { if ((keycode >= AUTOCORRECT_ON && keycode <= AUTOCORRECT_TOGGLE) && record->event.pressed) {
if (record->event.pressed) { if (keycode == AUTOCORRECT_ON) {
typo_buffer_size = 0; autocorrect_enable();
userspace_config.autocorrection ^= 1; } else if (keycode == AUTOCORRECT_OFF) {
eeconfig_update_user(userspace_config.raw); autocorrect_disable();
} else if (keycode == AUTOCORRECT_TOGGLE) {
autocorrect_toggle();
} else {
return true;
} }
return false; return false;
} }
if (!userspace_config.autocorrection) { if (!autocorrect_is_enabled()) {
typo_buffer_size = 0; typo_buffer_size = 0;
return true; return true;
} }
switch (keycode) { if (!record->event.pressed) {
case KC_LSFT: return true;
case KC_RSFT:
return true;
# ifndef NO_ACTION_TAPPING
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
if (((keycode >> 8) & 0xF) == MOD_LSFT) {
return true;
}
# ifndef NO_ACTION_LAYER
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
# endif
if (record->event.pressed || !record->tap.count) {
return true;
}
keycode &= 0xFF;
break;
# endif
# ifdef SWAP_HANDS_ENABLE
case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
if (keycode >= 0x56F0 || record->event.pressed || !record->tap.count) {
return true;
}
keycode &= 0xFF;
break;
# endif
# ifndef NO_ACTION_ONESHOT
case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
if ((keycode & 0xF) == MOD_LSFT) {
return true;
}
# endif
default:
// Disable autocorrection while a mod other than shift is active.
if (((get_mods() | get_oneshot_mods()) & ~MOD_MASK_SHIFT) != 0) {
typo_buffer_size = 0;
return true;
}
if (!record->event.pressed) {
return true;
}
} }
// Subtract buffer for Backspace key, reset for other non-alpha. // autocorrect keycode verification and extraction
if (!(KC_A <= keycode && keycode <= KC_Z)) { if (!process_autocorrect_user(&keycode, record, &typo_buffer_size, &mods)) {
if (keycode == KC_BSPC) { return true;
}
// keycode buffer check
switch (keycode) {
case KC_A ... KC_Z:
// process normally
break;
case KC_1 ... KC_0:
case KC_TAB ... KC_SEMICOLON:
case KC_GRAVE ... KC_SLASH:
// Set a word boundary if space, period, digit, etc. is pressed.
keycode = KC_SPC;
break;
case KC_ENTER:
// Behave more conservatively for the enter key. Reset, so that enter
// can't be used on a word ending.
typo_buffer_size = 0;
keycode = KC_SPC;
break;
case KC_BSPC:
// Remove last character from the buffer. // Remove last character from the buffer.
if (typo_buffer_size > 0) { if (typo_buffer_size > 0) {
--typo_buffer_size; --typo_buffer_size;
} }
return true; return true;
} else if (KC_1 <= keycode && keycode <= KC_SLSH && keycode != KC_ESC) { case KC_QUOTE:
// Set a word boundary if space, period, digit, etc. is pressed. // Treat " (shifted ') as a word boundary.
// Behave more conservatively for the enter key. Reset, so that enter if ((mods & MOD_MASK_SHIFT) != 0) {
// can't be used on a word ending. keycode = KC_SPC;
if (keycode == KC_ENT || (keycode == KC_MINUS && (get_mods() | get_oneshot_mods()) & MOD_MASK_SHIFT)) {
typo_buffer_size = 0;
} }
keycode = KC_SPC; break;
} else { default:
// Clear state if some other non-alpha key is pressed. // Clear state if some other non-alpha key is pressed.
typo_buffer_size = 0; typo_buffer_size = 0;
return true; return true;
}
} }
// Rotate oldest character if buffer is full. // Rotate oldest character if buffer is full.
if (typo_buffer_size >= AUTOCORRECTION_MAX_LENGTH) { if (typo_buffer_size >= AUTOCORRECT_MAX_LENGTH) {
memmove(typo_buffer, typo_buffer + 1, AUTOCORRECTION_MAX_LENGTH - 1); memmove(typo_buffer, typo_buffer + 1, AUTOCORRECT_MAX_LENGTH - 1);
typo_buffer_size = AUTOCORRECTION_MAX_LENGTH - 1; typo_buffer_size = AUTOCORRECT_MAX_LENGTH - 1;
} }
// Append `keycode` to buffer. // Append `keycode` to buffer.
typo_buffer[typo_buffer_size++] = keycode; typo_buffer[typo_buffer_size++] = keycode;
// Return if buffer is smaller than the shortest word. // Return if buffer is smaller than the shortest word.
if (typo_buffer_size < AUTOCORRECTION_MIN_LENGTH) { if (typo_buffer_size < AUTOCORRECT_MIN_LENGTH) {
return true; return true;
} }
// Check for typo in buffer using a trie stored in `autocorrection_data`. // Check for typo in buffer using a trie stored in `autocorrect_data`.
uint16_t state = 0; uint16_t state = 0;
uint8_t code = pgm_read_byte(autocorrection_data + state); uint8_t code = pgm_read_byte(autocorrect_data + state);
for (uint8_t i = typo_buffer_size - 1; i >= 0; --i) { for (int8_t i = typo_buffer_size - 1; i >= 0; --i) {
uint8_t const key_i = typo_buffer[i]; uint8_t const key_i = typo_buffer[i];
if (code & 64) { // Check for match in node with multiple children. if (code & 64) { // Check for match in node with multiple children.
code &= 63; code &= 63;
for (; code != key_i; code = pgm_read_byte(autocorrection_data + (state += 3))) { for (; code != key_i; code = pgm_read_byte(autocorrect_data + (state += 3))) {
if (!code) return true; if (!code) return true;
} }
// Follow link to child node. // Follow link to child node.
state = (pgm_read_byte(autocorrection_data + state + 1) | pgm_read_byte(autocorrection_data + state + 2) << 8); state = (pgm_read_byte(autocorrect_data + state + 1) | pgm_read_byte(autocorrect_data + state + 2) << 8);
// Check for match in node with single child. // Check for match in node with single child.
} else if (code != key_i) { } else if (code != key_i) {
return true; return true;
} else if (!(code = pgm_read_byte(autocorrection_data + (++state)))) { } else if (!(code = pgm_read_byte(autocorrect_data + (++state)))) {
++state; ++state;
} }
code = pgm_read_byte(autocorrection_data + state); // Stop if `state` becomes an invalid index. This should not normally
// happen, it is a safeguard in case of a bug, data corruption, etc.
if (state >= DICTIONARY_SIZE) {
return true;
}
if (code & 128) { // A typo was found! Apply autocorrection. code = pgm_read_byte(autocorrect_data + state);
const uint8_t backspaces = code & 63;
for (uint8_t i = 0; i < backspaces; ++i) { if (code & 128) { // A typo was found! Apply autocorrect.
tap_code(KC_BSPC); const uint8_t backspaces = (code & 63) + !record->event.pressed;
if (apply_autocorrect(backspaces, (char const *)(autocorrect_data + state + 1))) {
for (uint8_t i = 0; i < backspaces; ++i) {
tap_code(KC_BSPC);
}
send_string_P((char const *)(autocorrect_data + state + 1));
} }
send_string_P((char const*)(autocorrection_data + state + 1));
if (keycode == KC_SPC) { if (keycode == KC_SPC) {
typo_buffer[0] = KC_SPC; typo_buffer[0] = KC_SPC;
@ -166,5 +298,7 @@ bool process_autocorrection(uint16_t keycode, keyrecord_t* record) {
# pragma GCC pop_options # pragma GCC pop_options
#else #else
# pragma message "Warning!!! Autocorrect is not corretly setup!" # pragma message "Warning!!! Autocorrect is not corretly setup!"
bool process_autocorrection(uint16_t keycode, keyrecord_t* record) { return true; } bool process_autocorrection(uint16_t keycode, keyrecord_t* record) {
return true;
}
#endif #endif

View File

@ -7,4 +7,11 @@
#include "drashna.h" #include "drashna.h"
bool process_autocorrection(uint16_t keycode, keyrecord_t* record); bool process_autocorrection(uint16_t keycode, keyrecord_t *record);
bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods);
bool apply_autocorrect(uint8_t backspaces, const char *str);
bool autocorrect_is_enabled(void);
void autocorrect_enable(void);
void autocorrect_disable(void);
void autocorrect_toggle(void);

View File

@ -1,4 +1,4 @@
# Copyright 2021 Google LLC # Copyright 2021-2022 Google LLC
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -29,6 +29,7 @@ Each line of the dict file defines one typo and its correction with the syntax
Example: Example:
:thier -> their :thier -> their
dosen't -> doesn't
fitler -> filter fitler -> filter
lenght -> length lenght -> length
ouput -> output ouput -> output
@ -42,7 +43,7 @@ https://getreuer.info/posts/keyboards/autocorrection
import sys import sys
import textwrap import textwrap
from typing import Any, Dict, List, Tuple from typing import Any, Dict, Iterator, List, Tuple
try: try:
from english_words import english_words_lower_alpha_set as CORRECT_WORDS from english_words import english_words_lower_alpha_set as CORRECT_WORDS
@ -51,85 +52,67 @@ except ImportError:
'correctly spelled word. To check for this, install the english_words ' 'correctly spelled word. To check for this, install the english_words '
'package and rerun this script:\n\n pip install english_words\n') 'package and rerun this script:\n\n pip install english_words\n')
# Use a minimal word list as a fallback. # Use a minimal word list as a fallback.
CORRECT_WORDS = ('information', 'available', 'international', 'language', CORRECT_WORDS = ('apparent', 'association', 'available', 'classification',
'loosest', 'reference', 'wealthier', 'entertainment', 'effect', 'entertainment', 'fantastic', 'information',
'association', 'provides', 'technology', 'statehood') 'integrate', 'international', 'language', 'loosest',
'manual', 'nothing', 'provides', 'reference', 'statehood',
'technology', 'virtually', 'wealthier', 'wonderful')
KC_A = 4 KC_A = 4
KC_SPC = 0x2c KC_SPC = 0x2c
KC_QUOT = 0x34
TYPO_CHARS = dict(
[
("'", KC_QUOT),
(':', KC_SPC), # "Word break" character.
] +
# Characters a-z.
[(chr(c), c + KC_A - ord('a')) for c in range(ord('a'), ord('z') + 1)]
)
def parse_file(file_name: str) -> List[Tuple[str, str]]: def parse_file(file_name: str) -> List[Tuple[str, str]]:
"""Parses autocorrections dictionary file. """Parses autocorrections dictionary file.
Each line of the file defines one typo and its correction with the syntax Each line of the file defines one typo and its correction with the syntax
"typo -> correction". Blank lines or lines starting with '#' are ignored. The "typo -> correction". Blank lines or lines starting with '#' are ignored. The
function validates that typos only have characters a-z and that typos are not function validates that typos only have characters in TYPO_CHARS, that
substrings of other typos, otherwise the longer typo would never trigger. typos are not substrings of other typos, and checking that typos don't trigger
on CORRECT_WORDS.
Args: Args:
file_name: String, path of the autocorrections dictionary. file_name: String, path of the autocorrections dictionary.
Returns: Returns:
List of (typo, correction) tuples. List of (typo, correction) tuples.
""" """
correct_words = ('information', 'available', 'international', 'language', 'loosest', 'reference', 'wealthier', 'entertainment', 'association', 'provides', 'technology', 'statehood')
autocorrections = [] autocorrections = []
typos = set() typos = set()
line_number = 0 for line_number, typo, correction in parse_file_lines(file_name):
for line in open(file_name, 'rt'): if typo in typos:
line_number += 1 print(f'Warning:{line_number}: Ignoring duplicate typo: "{typo}"')
line = line.strip() continue
if line and line[0] != '#':
# Parse syntax "typo -> correction", using strip to ignore indenting. # Check that `typo` is valid.
tokens = [token.strip() for token in line.split('->', 1)] if not(all([c in TYPO_CHARS for c in typo])):
if len(tokens) != 2 or not tokens[0]: print(f'Error:{line_number}: Typo "{typo}" has '
print(f'Error:{line_number}: Invalid syntax: "{line}"') 'characters other than ' + ''.join(TYPO_CHARS.keys()))
sys.exit(1)
for other_typo in typos:
if typo in other_typo or other_typo in typo:
print(f'Error:{line_number}: Typos may not be substrings of one '
f'another, otherwise the longer typo would never trigger: '
f'"{typo}" vs. "{other_typo}".')
sys.exit(1) sys.exit(1)
if len(typo) < 5:
print(f'Warning:{line_number}: It is suggested that typos are at '
f'least 5 characters long to avoid false triggers: "{typo}"')
typo, correction = tokens check_typo_against_dictionary(typo, line_number, correct_words)
typo = typo.lower() # Force typos to lowercase.
typo = typo.replace(' ', ':')
if typo in typos: autocorrections.append((typo, correction))
print(f'Warning:{line_number}: Ignoring duplicate typo: "{typo}"') typos.add(typo)
continue
# Check that `typo` is valid.
if not(all([ord('a') <= ord(c) <= ord('z') or c == ':' for c in typo])):
print(f'Error:{line_number}: Typo "{typo}" has '
'characters other than a-z and :.')
sys.exit(1)
for other_typo in typos:
if typo in other_typo or other_typo in typo:
print(f'Error:{line_number}: Typos may not be substrings of one '
f'another, otherwise the longer typo would never trigger: '
f'"{typo}" vs. "{other_typo}".')
sys.exit(1)
if len(typo) < 5:
print(f'Warning:{line_number}: It is suggested that typos are at '
f'least 5 characters long to avoid false triggers: "{typo}"')
if typo.startswith(':') and typo.endswith(':'):
if typo[1:-1] in CORRECT_WORDS:
print(f'Warning:{line_number}: Typo "{typo}" is a correctly spelled '
'dictionary word.')
elif typo.startswith(':') and not typo.endswith(':'):
for word in CORRECT_WORDS:
if word.startswith(typo[1:]):
print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger '
f'on correctly spelled word "{word}".')
elif not typo.startswith(':') and typo.endswith(':'):
for word in CORRECT_WORDS:
if word.endswith(typo[:-1]):
print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger '
f'on correctly spelled word "{word}".')
elif not typo.startswith(':') and not typo.endswith(':'):
for word in CORRECT_WORDS:
if typo in word:
print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger '
f'on correctly spelled word "{word}".')
autocorrections.append((typo, correction))
typos.add(typo)
return autocorrections return autocorrections
@ -152,6 +135,47 @@ def make_trie(autocorrections: List[Tuple[str, str]]) -> Dict[str, Any]:
return trie return trie
def parse_file_lines(file_name: str) -> Iterator[Tuple[int, str, str]]:
"""Parses lines read from `file_name` into typo-correction pairs."""
line_number = 0
for line in open(file_name, 'rt'):
line_number += 1
line = line.strip()
if line and line[0] != '#':
# Parse syntax "typo -> correction", using strip to ignore indenting.
tokens = [token.strip() for token in line.split('->', 1)]
if len(tokens) != 2 or not tokens[0]:
print(f'Error:{line_number}: Invalid syntax: "{line}"')
sys.exit(1)
typo, correction = tokens
typo = typo.lower() # Force typos to lowercase.
typo = typo.replace(' ', ':')
yield line_number, typo, correction
def check_typo_against_dictionary(typo: str, line_number: int, correct_words) -> None:
"""Checks `typo` against English dictionary words."""
if typo.startswith(':') and typo.endswith(':'):
if typo[1:-1] in correct_words:
print(f'Warning:{line_number}: Typo "{typo}" is a correctly spelled dictionary word.')
elif typo.startswith(':') and not typo.endswith(':'):
for word in correct_words:
if word.startswith(typo[1:]):
print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger on correctly spelled word "{word}".')
elif not typo.startswith(':') and typo.endswith(':'):
for word in correct_words:
if word.endswith(typo[:-1]):
print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger on correctly spelled word "{word}".')
elif not typo.startswith(':') and not typo.endswith(':'):
for word in correct_words:
if typo in word:
print(f'Warning:{line_number}: Typo "{typo}" would falsely trigger on correctly spelled word "{word}".')
def serialize_trie(autocorrections: List[Tuple[str, str]], def serialize_trie(autocorrections: List[Tuple[str, str]],
trie: Dict[str, Any]) -> List[int]: trie: Dict[str, Any]) -> List[int]:
"""Serializes trie and correction data in a form readable by the C code. """Serializes trie and correction data in a form readable by the C code.
@ -165,7 +189,7 @@ def serialize_trie(autocorrections: List[Tuple[str, str]],
table = [] table = []
# Traverse trie in depth first order. # Traverse trie in depth first order.
def traverse(trie_node): def traverse(trie_node: Dict[str, Any]) -> Dict[str, Any]:
if 'LEAF' in trie_node: # Handle a leaf trie node. if 'LEAF' in trie_node: # Handle a leaf trie node.
typo, correction = trie_node['LEAF'] typo, correction = trie_node['LEAF']
word_boundary_ending = typo[-1] == ':' word_boundary_ending = typo[-1] == ':'
@ -200,37 +224,35 @@ def serialize_trie(autocorrections: List[Tuple[str, str]],
traverse(trie) traverse(trie)
def serialize(e): def serialize(e: Dict[str, Any]) -> List[int]:
def kc_code(c):
if ord('a') <= ord(c) <= ord('z'):
return ord(c) - ord('a') + KC_A
elif c == ':':
return KC_SPC
else:
raise ValueError(f'Invalid character: {c}')
encode_link = lambda link: [link['byte_offset'] & 255,
link['byte_offset'] >> 8]
if not e['links']: # Handle a leaf table entry. if not e['links']: # Handle a leaf table entry.
return e['data'] return e['data']
elif len(e['links']) == 1: # Handle a chain table entry. elif len(e['links']) == 1: # Handle a chain table entry.
return list(map(kc_code, e['chars'])) + [0] #+ encode_link(e['links'][0])) return [TYPO_CHARS[c] for c in e['chars']] + [0]
else: # Handle a branch table entry. else: # Handle a branch table entry.
data = [] data = []
for c, link in zip(e['chars'], e['links']): for c, link in zip(e['chars'], e['links']):
data += [kc_code(c) | (0 if data else 64)] + encode_link(link) data += [TYPO_CHARS[c] | (0 if data else 64)] + encode_link(link)
return data + [0] return data + [0]
byte_offset = 0 byte_offset = 0
for e in table: # To encode links, first compute byte offset of each entry. for e in table: # To encode links, first compute byte offset of each entry.
e['byte_offset'] = byte_offset e['byte_offset'] = byte_offset
byte_offset += len(serialize(e)) byte_offset += len(serialize(e))
assert 0 <= byte_offset <= 0xffff
return [b for e in table for b in serialize(e)] # Serialize final table. return [b for e in table for b in serialize(e)] # Serialize final table.
def encode_link(link: Dict[str, Any]) -> List[int]:
"""Encodes a node link as two bytes."""
byte_offset = link['byte_offset']
if not (0 <= byte_offset <= 0xffff):
print('Error: The autocorrection table is too large, a node link exceeds '
'64KB limit. Try reducing the autocorrection dict to fewer entries.')
sys.exit(1)
return [byte_offset & 255, byte_offset >> 8]
def write_generated_code(autocorrections: List[Tuple[str, str]], def write_generated_code(autocorrections: List[Tuple[str, str]],
data: List[int], data: List[int],
file_name: str) -> None: file_name: str) -> None:
@ -242,7 +264,10 @@ def write_generated_code(autocorrections: List[Tuple[str, str]],
file_name: String, path of the output C file. file_name: String, path of the output C file.
""" """
assert all(0 <= b <= 255 for b in data) assert all(0 <= b <= 255 for b in data)
typo_len = lambda e: len(e[0])
def typo_len(e: Tuple[str, str]) -> int:
return len(e[0])
min_typo = min(autocorrections, key=typo_len)[0] min_typo = min(autocorrections, key=typo_len)[0]
max_typo = max(autocorrections, key=typo_len)[0] max_typo = max(autocorrections, key=typo_len)[0]
generated_code = ''.join([ generated_code = ''.join([
@ -252,9 +277,8 @@ def write_generated_code(autocorrections: List[Tuple[str, str]],
for typo, correction in autocorrections)), for typo, correction in autocorrections)),
f'\n#define AUTOCORRECTION_MIN_LENGTH {len(min_typo)} // "{min_typo}"\n', f'\n#define AUTOCORRECTION_MIN_LENGTH {len(min_typo)} // "{min_typo}"\n',
f'#define AUTOCORRECTION_MAX_LENGTH {len(max_typo)} // "{max_typo}"\n\n', f'#define AUTOCORRECTION_MAX_LENGTH {len(max_typo)} // "{max_typo}"\n\n',
f'#define DICTIONARY_SIZE {len(data)}\n\n', textwrap.fill('static const uint8_t autocorrection_data[%d] PROGMEM = {%s};' % (
textwrap.fill('static const uint8_t autocorrection_data[DICTIONARY_SIZE] PROGMEM = {%s};' % ( len(data), ', '.join(map(str, data))), width=80, subsequent_indent=' '),
', '.join(map(str, data))), width=120, subsequent_indent=' '),
'\n\n']) '\n\n'])
with open(file_name, 'wt') as f: with open(file_name, 'wt') as f:

View File

@ -1,139 +0,0 @@
#include "caps_word.h"
static bool caps_word_active = false;
#if CAPS_WORD_IDLE_TIMEOUT > 0
# if CAPS_WORD_IDLE_TIMEOUT < 100 || CAPS_WORD_IDLE_TIMEOUT > 30000
// Constrain timeout to a sensible range. With the 16-bit timer, the longest
// representable timeout is 32768 ms, rounded here to 30000 ms = half a minute.
# error "caps_word: CAPS_WORD_IDLE_TIMEOUT must be between 100 and 30000 ms"
# endif
static uint16_t idle_timer = 0;
void caps_word_task(void) {
if (caps_word_active && timer_expired(timer_read(), idle_timer)) {
caps_word_set(false);
}
}
#endif // CAPS_WORD_IDLE_TIMEOUT > 0
bool process_caps_word(uint16_t keycode, keyrecord_t* record) {
#ifndef NO_ACTION_ONESHOT
const uint8_t mods = get_mods() | get_oneshot_mods();
#else
const uint8_t mods = get_mods();
#endif // NO_ACTION_ONESHOT
if (!caps_word_active) {
// Pressing both shift keys at the same time enables caps word.
if ((mods & MOD_MASK_SHIFT) == MOD_MASK_SHIFT) {
caps_word_set(true); // Activate Caps Word.
return false;
}
return true;
} else {
#if CAPS_WORD_IDLE_TIMEOUT > 0
idle_timer = record->event.time + CAPS_WORD_IDLE_TIMEOUT;
#endif // CAPS_WORD_IDLE_TIMEOUT > 0
}
if (!record->event.pressed) {
return true;
}
if (!(mods & ~MOD_MASK_SHIFT)) {
switch (keycode) {
// Ignore MO, TO, TG, TT, and OSL layer switch keys.
case QK_MOMENTARY ... QK_MOMENTARY_MAX:
case QK_TO ... QK_TO_MAX:
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
return true;
#ifndef NO_ACTION_TAPPING
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
if (record->tap.count == 0) {
// Deactivate if a mod becomes active through holding a mod-tap key.
caps_word_set(false);
return true;
}
keycode &= 0xff;
break;
# ifndef NO_ACTION_LAYER
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
# endif // NO_ACTION_LAYER
if (record->tap.count == 0) {
return true;
}
keycode &= 0xff;
break;
#endif // NO_ACTION_TAPPING
#ifdef SWAP_HANDS_ENABLE
case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX:
if (keycode > 0x56F0 || record->tap.count == 0) {
return true;
}
keycode &= 0xff;
break;
#endif // SWAP_HANDS_ENABLE
}
if (caps_word_press_user(keycode)) {
return true;
}
}
caps_word_set(false); // Deactivate Caps Word.
return true;
}
void caps_word_set(bool active) {
if (active != caps_word_active) {
if (active) {
clear_mods();
#ifndef NO_ACTION_ONESHOT
clear_oneshot_mods();
#endif // NO_ACTION_ONESHOT
#if CAPS_WORD_IDLE_TIMEOUT > 0
idle_timer = timer_read() + CAPS_WORD_IDLE_TIMEOUT;
#endif // CAPS_WORD_IDLE_TIMEOUT > 0
} else if ((get_weak_mods() & MOD_BIT(KC_LSFT)) != 0) {
// If the weak shift mod is still on, turn it off and send an update to
// the host computer.
del_weak_mods(MOD_BIT(KC_LSFT));
send_keyboard_report();
}
caps_word_active = active;
caps_word_set_user(active);
}
}
bool caps_word_get(void) {
return caps_word_active;
}
__attribute__((weak)) void caps_word_set_user(bool active) {}
__attribute__((weak)) bool caps_word_press_user(uint16_t keycode) {
switch (keycode) {
// Keycodes that continue Caps Word, with shift applied.
case KC_A ... KC_Z:
add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key.
return true;
// Keycodes that continue Caps Word, without shifting.
case KC_1 ... KC_0:
case KC_BSPC:
case KC_MINS:
case KC_UNDS:
return true;
default:
return false; // Deactivate Caps Word.
}
}

View File

@ -1,85 +0,0 @@
// Copyright 2021 Google LLC.
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "drashna.h"
// Call this function from `process_record_user()` to implement Caps Word.
bool process_caps_word(uint16_t keycode, keyrecord_t* record);
// If CAPS_WORD_IDLE_TIMEOUT is set, call `caps_word_task()` from
// `matrix_scan_user()` as described above.
//
// If CAPS_WORD_IDLE_TIMEOUT isn't set, calling this function has no effect (but
// will still compile).
#if CAPS_WORD_IDLE_TIMEOUT > 0
void caps_word_task(void);
#else
static inline void caps_word_task(void) {}
#endif
// Activates or deactivates Caps Word. For instance activate Caps Word with a
// combo by defining a `COMBO_ACTION` that calls `caps_word_set(true)`:
//
// void process_combo_event(uint16_t combo_index, bool pressed) {
// switch(combo_index) {
// case CAPS_COMBO:
// if (pressed) {
// caps_word_set(true); // Activate Caps Word.
// }
// break;
//
// // Other combos...
// }
// }
void caps_word_set(bool active);
// Returns whether Caps Word is currently active.
bool caps_word_get(void);
// An optional callback that gets called when Caps Word turns on or off. This is
// useful to represent the current Caps Word state, e.g. by setting an LED or
// playing a sound. In your keymap, define
//
// void caps_word_set_user(bool active) {
// if (active) {
// // Do something when Caps Word activates.
// } else {
// // Do something when Caps Word deactivates.
// }
// }
void caps_word_set_user(bool active);
// An optional callback which is called on every key press while Caps Word is
// active. When the key should be shifted (that is, a letter key), the callback
// should call `add_weak_mods(MOD_BIT(KC_LSFT))` to shift the key. The callback
// also determines whether the key should continue Caps Word. Returning true
// continues the current "word", while returning false is "word breaking" and
// deactivates Caps Word. The default callback is
//
// bool caps_word_press_user(uint16_t keycode) {
// switch (keycode) {
// // Keycodes that continue Caps Word, with shift applied.
// case KC_A ... KC_Z:
// add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to the next key.
// return true;
//
// // Keycodes that continue Caps Word, without shifting.
// case KC_1 ... KC_0:
// case KC_BSPC:
// case KC_MINS:
// case KC_UNDS:
// return true;
//
// default:
// return false; // Deactivate Caps Word.
// }
// }
//
// To customize, copy the above function into your keymap and add/remove
// keycodes to the above cases.
//
// NOTE: Outside of this callback, you can use `caps_word_set(false)` to
// deactivate Caps Word.
bool caps_word_press_user(uint16_t keycode);

View File

@ -5,14 +5,9 @@ Keycodes are defined in the `process_record.h` file and need to be included in t
A bunch of macros are present and are only included on boards that are not the Ergodox EZ or Orthodox, as they are not needed for those boards. A bunch of macros are present and are only included on boards that are not the Ergodox EZ or Orthodox, as they are not needed for those boards.
* `KC_MAKE` - outputs `qmk compile -kb (keyboard) -km (keymap)` and enter, to start compiling the currenct keyboard. This uses generated variables to always use the current keyboard and keymap. Will work with any keyboard and any keymap.
* If you are holding shift, it will use `qmk flash` instead of `qmk compile`.
* If `MAKE_BOOTLOADER` is defined, it will always use `qmk flash` instead of `qmk compile`.
* `DEFAULT_LAYER_1` ... `DEFAULT_LAYER_4` - This sets layer 0-3 as the default layer, and writes that to eeprom, and plays a chime. * `DEFAULT_LAYER_1` ... `DEFAULT_LAYER_4` - This sets layer 0-3 as the default layer, and writes that to eeprom, and plays a chime.
* `VRSN`, outputs the keyboard, keymap, commit and date info. Eg: * `VRSN`, outputs the keyboard, keymap, commit and date info. Eg:
* `handwired/tractyl_manuform/5x6_right/f411/drashna @ 0.15.9-162-g087d08, Built on: 2021-12-19-21:10:26` * `handwired/tractyl_manuform/5x6_right/f411/drashna @ 0.15.9-162-g087d08, Built on: 2021-12-19-21:10:26`
* `KC_DIABLO_CLEAR` - clears the diablo tapdance status. * `KC_DIABLO_CLEAR` - clears the diablo tapdance status.
* `KC_CCCV` - Copy on hold, paste on tap. * `KC_CCCV` - Copy on hold, paste on tap.
* `KEYLOCK` - This unloads the host driver, and prevents any data from being sent to the host. Hitting it again loads the driver, back. * `KEYLOCK` - This unloads the host driver, and prevents any data from being sent to the host. Hitting it again loads the driver, back.
* `REBOOT` - Uses watchdog timer on AVR, and `NVIC_SystemReset()` on ChibiOS to reset the board, without jumping to the bootloader.
* `EEP_RST` - Overrides the default behavior, disables EEPROM (which will trigger a reset on init), and reboots the keyboard as per `REBOOT` keycode.

View File

@ -3,9 +3,6 @@
#include "drashna.h" #include "drashna.h"
#include "version.h" #include "version.h"
#ifdef CAPS_WORD_ENABLE
# include "caps_word.h"
#endif
#ifdef AUTOCORRECTION_ENABLE #ifdef AUTOCORRECTION_ENABLE
# include "autocorrection/autocorrection.h" # include "autocorrection/autocorrection.h"
#endif #endif
@ -37,6 +34,15 @@ __attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t
* @return false Stop process keycode and do not send to host * @return false Stop process keycode and do not send to host
*/ */
bool process_record_user(uint16_t keycode, keyrecord_t *record) { bool process_record_user(uint16_t keycode, keyrecord_t *record) {
#ifdef ENCODER_ENABLE // some debouncing for weird issues
if (IS_ENCODEREVENT(record->event)) {
static bool ignore_first = true;
if (ignore_first) {
ignore_first = false;
return false;
}
}
#endif
// If console is enabled, it will print the matrix position and status of each key pressed // If console is enabled, it will print the matrix position and status of each key pressed
#ifdef KEYLOGGER_ENABLE #ifdef KEYLOGGER_ENABLE
uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count); uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
@ -58,9 +64,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
#if defined(CUSTOM_POINTING_DEVICE) #if defined(CUSTOM_POINTING_DEVICE)
&& process_record_pointing(keycode, record) && process_record_pointing(keycode, record)
#endif #endif
#ifdef CAPS_WORD_ENABLE
&& process_caps_word(keycode, record)
#endif
#ifdef AUTOCORRECTION_ENABLE #ifdef AUTOCORRECTION_ENABLE
&& process_autocorrection(keycode, record) && process_autocorrection(keycode, record)
#endif #endif
@ -87,33 +90,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
} }
break; break;
case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
if (!record->event.pressed) {
#ifndef MAKE_BOOTLOADER
uint8_t temp_mod = mod_config(get_mods());
uint8_t temp_osm = mod_config(get_oneshot_mods());
clear_mods();
clear_oneshot_mods();
#endif
send_string_with_delay_P(PSTR("qmk"), TAP_CODE_DELAY);
#ifndef MAKE_BOOTLOADER
if ((temp_mod | temp_osm) & MOD_MASK_SHIFT)
#endif
{
send_string_with_delay_P(PSTR(" flash "), TAP_CODE_DELAY);
#ifndef MAKE_BOOTLOADER
} else {
send_string_with_delay_P(PSTR(" compile "), TAP_CODE_DELAY);
#endif
}
send_string_with_delay_P(PSTR("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP), TAP_CODE_DELAY);
#ifdef CONVERT_TO_PROTON_C
send_string_with_delay_P(PSTR(" -e CTPC=yes"), TAP_CODE_DELAY);
#endif
send_string_with_delay_P(PSTR(SS_TAP(X_ENTER)), TAP_CODE_DELAY);
}
break;
case VRSN: // Prints firmware version case VRSN: // Prints firmware version
if (record->event.pressed) { if (record->event.pressed) {
send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY); send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
@ -148,13 +124,19 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
dprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change); dprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
eeconfig_update_user(userspace_config.raw); eeconfig_update_user(userspace_config.raw);
if (userspace_config.rgb_layer_change) { if (userspace_config.rgb_layer_change) {
# if defined(CUSTOM_RGBLIGHT) && defined(CUSTOM_RGB_MATRIX) # if defined(CUSTOM_RGB_MATRIX)
rgb_matrix_set_flags(LED_FLAG_UNDERGLOW | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR);
# if defined(CUSTOM_RGBLIGHT)
rgblight_enable_noeeprom(); rgblight_enable_noeeprom();
# endif
# endif # endif
layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better) layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
# if defined(CUSTOM_RGBLIGHT) && defined(CUSTOM_RGB_MATRIX) # if defined(CUSTOM_RGB_MATRIX)
} else { } else {
rgb_matrix_set_flags(LED_FLAG_ALL);
# if defined(CUSTOM_RGBLIGHT)
rgblight_disable_noeeprom(); rgblight_disable_noeeprom();
# endif
# endif # endif
} }
} }
@ -218,23 +200,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
} }
break; break;
} }
case EEP_RST: }
if (record->event.pressed) {
eeconfig_disable();
shutdown_user();
#ifdef __AVR__
wdt_enable(WDTO_250MS);
#else
NVIC_SystemReset();
#endif
}
return false;
case REBOOT:
if (record->event.pressed) {
software_reset();
}
return false;
}
return true; return true;
} }

View File

@ -21,7 +21,6 @@ enum userspace_custom_keycodes {
KC_DVORAK, // Sets default layer to DVORAK KC_DVORAK, // Sets default layer to DVORAK
LAST_DEFAULT_LAYER_KEYCODE = KC_DVORAK, // Sets default layer to WORKMAN LAST_DEFAULT_LAYER_KEYCODE = KC_DVORAK, // Sets default layer to WORKMAN
KC_DIABLO_CLEAR, // Clears all Diablo Timers KC_DIABLO_CLEAR, // Clears all Diablo Timers
KC_MAKE, // Run keyboard's customized make command
KC_RGB_T, // Toggles RGB Layer Indication mode KC_RGB_T, // Toggles RGB Layer Indication mode
RGB_IDL, // RGB Idling animations RGB_IDL, // RGB Idling animations
KC_SECRET_1, // test1 KC_SECRET_1, // test1
@ -46,8 +45,9 @@ enum userspace_custom_keycodes {
KC_AUSSIE, KC_AUSSIE,
KC_ZALGO, KC_ZALGO,
KC_ACCEL, KC_ACCEL,
AUTO_CTN, // Toggle Autocorrect status AUTOCORRECT_ON,
REBOOT, AUTOCORRECT_OFF,
AUTOCORRECT_TOGGLE,
NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes NEW_SAFE_RANGE // use "NEWPLACEHOLDER for keymap specific codes
}; };
@ -95,9 +95,6 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
# endif # endif
#endif #endif
#define KC_RESET RESET
#define KC_RST KC_RESET
#ifdef SWAP_HANDS_ENABLE #ifdef SWAP_HANDS_ENABLE
# define KC_C1R3 SH_T(KC_TAB) # define KC_C1R3 SH_T(KC_TAB)
#elif defined(DRASHNA_LP) #elif defined(DRASHNA_LP)
@ -130,7 +127,7 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
#define MG_NKRO MAGIC_TOGGLE_NKRO #define MG_NKRO MAGIC_TOGGLE_NKRO
#define AUTO_CTN AUTOCORRECT_TOGGLE
/* /*
Custom Keycodes for Diablo 3 layer Custom Keycodes for Diablo 3 layer
But since TD() doesn't work when tap dance is disabled But since TD() doesn't work when tap dance is disabled

View File

@ -24,14 +24,12 @@ secrets.h
Here is the magic. This handles including the "secrets", and adding the custom macros to send them. Here is the magic. This handles including the "secrets", and adding the custom macros to send them.
```c ```c
#include "drashna.h" // replace with your keymap's "h" file, or whatever file stores the keycodes #include QMK_KEYBOARD_H
#if (__has_include("secrets.h") && !defined(NO_SECRETS)) #if (__has_include("secrets.h") && !defined(NO_SECRETS))
#include "secrets.h" #include "secrets.h"
#else #else
// `PROGMEM const char secret[][x]` may work better, but it takes up more space in the firmware static const char * const secrets[] = {
// And I'm not familiar enough to know which is better or why...
static const char * const secret[] = {
"test1", "test1",
"test2", "test2",
"test3", "test3",
@ -43,9 +41,10 @@ static const char * const secret[] = {
bool process_record_secrets(uint16_t keycode, keyrecord_t *record) { bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
switch (keycode) { switch (keycode) {
case KC_SECRET_1 ... KC_SECRET_5: // Secrets! Externally defined strings, not stored in repo case KC_SECRET_1 ... KC_SECRET_5: // Secrets! Externally defined strings, not stored in repo
if (!record->event.pressed) { if (record->event.pressed) {
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); clear_mods();
send_string_with_delay(secret[keycode - KC_SECRET_1], MACRO_TIMER); clear_oneshot_mods();
send_string_with_delay(secrets[keycode - KC_SECRET_1], MACRO_TIMER);
} }
return false; return false;
break; break;
@ -59,7 +58,7 @@ bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
Now, for the actual secrets! The file needs to look like Now, for the actual secrets! The file needs to look like
```c ```c
static const char * secrets[] = { static const char * secrets[] = {
"secret1", "secret1",
"secret2", "secret2",
"secret3", "secret3",
@ -96,7 +95,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
Here, you want your `/users/<name>/rules.mk` file to "detect" the existence of the `secrets.c` file, and only add it if the file exists. Here, you want your `/users/<name>/rules.mk` file to "detect" the existence of the `secrets.c` file, and only add it if the file exists.
Additionally, to ensure that it's not added or processed in any way, it checks to see if `NO_SECRETS` is set. This way, if you run `make keyboard:name NO_SECRETS=yes`, it will remove the feature altogether. Additionally, to ensure that it's not added or processed in any way, it checks to see if `NO_SECRETS` is set. This way, if you run `qmk compile -kb keyboard -km name -e NO_SECRETS=yes`, it will remove the feature altogether.
```make ```make
ifneq ($(strip $(NO_SECRETS)), yes) ifneq ($(strip $(NO_SECRETS)), yes)

View File

@ -4,9 +4,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "drashna.h" #include "drashna.h"
#include "unicode.h"
#include "process_unicode_common.h" #include "process_unicode_common.h"
uint16_t typing_mode = KC_NOMODE; uint8_t typing_mode = UCTM_NO_MODE;
/** /**
* @brief Registers the unicode keystrokes based on desired unicode * @brief Registers the unicode keystrokes based on desired unicode
@ -242,10 +243,10 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
break; break;
case KC_NOMODE ... KC_ZALGO: case KC_NOMODE ... KC_ZALGO:
if (record->event.pressed) { if (record->event.pressed) {
if (typing_mode != keycode) { if (typing_mode != keycode - KC_NOMODE) {
typing_mode = keycode; typing_mode = keycode - KC_NOMODE;
} else { } else {
typing_mode = KC_NOMODE; typing_mode = UCTM_NO_MODE;
} }
} }
break; break;
@ -259,19 +260,19 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
keycode &= 0xFF; keycode &= 0xFF;
} }
if (typing_mode == KC_WIDE) { if (typing_mode == UCTM_WIDE) {
if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
return process_record_glyph_replacement(keycode, record, unicode_range_translator_wide); return process_record_glyph_replacement(keycode, record, unicode_range_translator_wide);
} }
} else if (typing_mode == KC_SCRIPT) { } else if (typing_mode == UCTM_SCRIPT) {
if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
return process_record_glyph_replacement(keycode, record, unicode_range_translator_script); return process_record_glyph_replacement(keycode, record, unicode_range_translator_script);
} }
} else if (typing_mode == KC_BLOCKS) { } else if (typing_mode == UCTM_BLOCKS) {
if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
return process_record_glyph_replacement(keycode, record, unicode_range_translator_boxes); return process_record_glyph_replacement(keycode, record, unicode_range_translator_boxes);
} }
} else if (typing_mode == KC_REGIONAL) { } else if (typing_mode == UCTM_REGIONAL) {
if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) { if (((KC_A <= keycode) && (keycode <= KC_0)) || keycode == KC_SPACE) {
if (!process_record_glyph_replacement(keycode, record, unicode_range_translator_regional)) { if (!process_record_glyph_replacement(keycode, record, unicode_range_translator_regional)) {
wait_us(500); wait_us(500);
@ -279,9 +280,9 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
return false; return false;
} }
} }
} else if (typing_mode == KC_AUSSIE) { } else if (typing_mode == UCTM_AUSSIE) {
return process_record_aussie(keycode, record); return process_record_aussie(keycode, record);
} else if (typing_mode == KC_ZALGO) { } else if (typing_mode == UCTM_ZALGO) {
return process_record_zalgo(keycode, record); return process_record_zalgo(keycode, record);
} }
return true; return true;

View File

@ -0,0 +1,16 @@
// Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
enum unicode_typing_mode {
UCTM_NO_MODE,
UCTM_WIDE,
UCTM_SCRIPT,
UCTM_BLOCKS,
UCTM_REGIONAL,
UCTM_AUSSIE,
UCTM_ZALGO,
};
extern uint8_t typing_mode;

View File

@ -18,19 +18,23 @@
#include "drashna.h" #include "drashna.h"
#ifdef UNICODE_COMMON_ENABLE #ifdef UNICODE_COMMON_ENABLE
# include "process_unicode_common.h" # include "process_unicode_common.h"
# include "keyrecords/unicode.h"
#endif
#ifdef AUDIO_CLICKY
# include "process_clicky.h"
#endif
#if defined(AUTOCORRECTION_ENABLE)
# include "keyrecords/autocorrection/autocorrection.h"
#endif #endif
# ifdef AUDIO_CLICKY
# include "process_clicky.h"
# endif
#include <string.h> #include <string.h>
extern bool host_driver_disabled; extern bool host_driver_disabled;
uint32_t oled_timer = 0; uint32_t oled_timer = 0;
char keylog_str[OLED_KEYLOGGER_LENGTH] = {0}; char keylog_str[OLED_KEYLOGGER_LENGTH] = {0};
static uint16_t log_timer = 0; static uint16_t log_timer = 0;
#ifdef OLED_DISPLAY_VERBOSE #ifdef OLED_DISPLAY_VERBOSE
static const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0}; static const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0};
#endif #endif
deferred_token kittoken; deferred_token kittoken;
@ -100,12 +104,15 @@ void add_keylog(uint16_t keycode, keyrecord_t *record) {
*/ */
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) { bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) { if (record->event.pressed) {
oled_timer = timer_read32(); oled_timer_reset();
add_keylog(keycode, record); add_keylog(keycode, record);
} }
return true; return true;
} }
void oled_timer_reset(void) {
oled_timer = timer_read32();
}
/** /**
* @brief Renders keylogger buffer to oled * @brief Renders keylogger buffer to oled
* *
@ -262,9 +269,8 @@ void render_layer_state(void) {
} }
}; };
// clang-format on // clang-format on
uint8_t layer_is[4] = { 0, 4, 4, 4}; uint8_t layer_is[4] = {0, 4, 4, 4};
if (layer_state_is(_ADJUST)) { if (layer_state_is(_ADJUST)) {
layer_is[0] = 3; layer_is[0] = 3;
} else if (layer_state_is(_RAISE)) { } else if (layer_state_is(_RAISE)) {
@ -280,7 +286,6 @@ void render_layer_state(void) {
layer_is[2] = 5; layer_is[2] = 5;
} }
oled_set_cursor(1, 2); oled_set_cursor(1, 2);
oled_write_raw_P(tri_layer_image[layer_is[0]][0], sizeof(tri_layer_image[0][0])); oled_write_raw_P(tri_layer_image[layer_is[0]][0], sizeof(tri_layer_image[0][0]));
oled_set_cursor(5, 2); oled_set_cursor(5, 2);
@ -322,7 +327,7 @@ void render_layer_state(void) {
* *
* @param led_usb_state Current keyboard led state * @param led_usb_state Current keyboard led state
*/ */
void render_keylock_status(uint8_t led_usb_state) { void render_keylock_status(led_t led_usb_state) {
#if defined(OLED_DISPLAY_VERBOSE) #if defined(OLED_DISPLAY_VERBOSE)
oled_set_cursor(1, 6); oled_set_cursor(1, 6);
#endif #endif
@ -330,12 +335,12 @@ void render_keylock_status(uint8_t led_usb_state) {
#if !defined(OLED_DISPLAY_VERBOSE) #if !defined(OLED_DISPLAY_VERBOSE)
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
#endif #endif
oled_write_P(PSTR(OLED_RENDER_LOCK_NUML), led_usb_state & (1 << USB_LED_NUM_LOCK)); oled_write_P(PSTR(OLED_RENDER_LOCK_NUML), led_usb_state.num_lock);
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
oled_write_P(PSTR(OLED_RENDER_LOCK_CAPS), led_usb_state & (1 << USB_LED_CAPS_LOCK)); oled_write_P(PSTR(OLED_RENDER_LOCK_CAPS), led_usb_state.caps_lock);
#if defined(OLED_DISPLAY_VERBOSE) #if defined(OLED_DISPLAY_VERBOSE)
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
oled_write_P(PSTR(OLED_RENDER_LOCK_SCLK), led_usb_state & (1 << USB_LED_SCROLL_LOCK)); oled_write_P(PSTR(OLED_RENDER_LOCK_SCLK), led_usb_state.scroll_lock);
#endif #endif
} }
@ -417,15 +422,14 @@ void render_bootmagic_status(void) {
oled_write_P(logo[0][0], !is_bootmagic_on); oled_write_P(logo[0][0], !is_bootmagic_on);
} }
#ifndef OLED_DISPLAY_VERBOSE #ifndef OLED_DISPLAY_VERBOSE
oled_write_P(PSTR(" "), false);
oled_write_P(logo[1][1], is_bootmagic_on); oled_write_P(logo[1][1], is_bootmagic_on);
oled_write_P(logo[0][1], !is_bootmagic_on); oled_write_P(logo[0][1], !is_bootmagic_on);
#endif #endif
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NKRO), keymap_config.nkro); oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NKRO), keymap_config.nkro);
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
#ifdef AUTOCORRECTION_ENABLE #if defined(AUTOCORRECTION_ENABLE) || defined(AUTOCORRECT_ENABLE)
oled_write_P(PSTR("CRCT"), userspace_config.autocorrection); oled_write_P(PSTR("CRCT"), autocorrect_is_enabled());
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
#else #else
oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NOGUI), keymap_config.no_gui); oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_NOGUI), keymap_config.no_gui);
@ -439,7 +443,7 @@ void render_bootmagic_status(void) {
} }
#endif #endif
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_ONESHOT), !is_oneshot_enabled()); oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_ONESHOT), is_oneshot_enabled());
#ifdef SWAP_HANDS_ENABLE #ifdef SWAP_HANDS_ENABLE
oled_write_P(PSTR(" "), false); oled_write_P(PSTR(" "), false);
oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_SWAP), swap_hands); oled_write_P(PSTR(OLED_RENDER_BOOTMAGIC_SWAP), swap_hands);
@ -461,7 +465,7 @@ void render_user_status(void) {
l_is_clicky_on = user_state.audio_clicky_enable; l_is_clicky_on = user_state.audio_clicky_enable;
# endif # endif
# else # else
is_audio_on = is_audio_on(); is_audio_on = is_audio_on();
# ifdef AUDIO_CLICKY # ifdef AUDIO_CLICKY
l_is_clicky_on = is_clicky_on(); l_is_clicky_on = is_clicky_on();
# endif # endif
@ -501,7 +505,7 @@ void render_user_status(void) {
static const char PROGMEM cat_mode[2][3] = {{0xF8, 0xF9, 0}, {0xF6, 0xF7, 0}}; static const char PROGMEM cat_mode[2][3] = {{0xF8, 0xF9, 0}, {0xF6, 0xF7, 0}};
oled_write_P(cat_mode[0], host_driver_disabled); oled_write_P(cat_mode[0], host_driver_disabled);
#if defined(UNICODE_COMMON_ENABLE) #if defined(UNICODE_COMMON_ENABLE)
static const char PROGMEM uc_mod_status[5][3] = {{0xEC, 0xED, 0}, {0x20, 0x20, 0}, {0x20, 0x20, 0}, {0x20, 0x20, 0}, {0xEA, 0xEB, 0}}; static const char PROGMEM uc_mod_status[5][3] = {{0xEC, 0xED, 0}, {0x20, 0x20, 0}, {0x20, 0x20, 0}, {0x20, 0x20, 0}, {0xEA, 0xEB, 0}};
oled_write_P(uc_mod_status[get_unicode_input_mode()], false); oled_write_P(uc_mod_status[get_unicode_input_mode()], false);
#endif #endif
if (userspace_config.nuke_switch) { if (userspace_config.nuke_switch) {
@ -549,9 +553,9 @@ void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset) {
uint8_t currwpm = get_current_wpm(); uint8_t currwpm = get_current_wpm();
float max_wpm = OLED_WPM_GRAPH_MAX_WPM; float max_wpm = OLED_WPM_GRAPH_MAX_WPM;
if (timer_elapsed(timer) > OLED_WPM_GRAPH_REFRESH_INTERVAL) { // check if it's been long enough before refreshing graph if (timer_elapsed(timer) > OLED_WPM_GRAPH_REFRESH_INTERVAL) { // check if it's been long enough before refreshing graph
x = (max_lines_graph - 1) - ((currwpm / max_wpm) * (max_lines_graph - 1)); // main calculation to plot graph line x = (max_lines_graph - 1) - ((currwpm / max_wpm) * (max_lines_graph - 1)); // main calculation to plot graph line
for (uint8_t i = 0; i <= OLED_WPM_GRAPH_GRAPH_LINE_THICKNESS - 1; i++) { // first draw actual value line for (uint8_t i = 0; i <= OLED_WPM_GRAPH_GRAPH_LINE_THICKNESS - 1; i++) { // first draw actual value line
oled_write_pixel(3, x + i + vertical_offset, true); oled_write_pixel(3, x + i + vertical_offset, true);
} }
# ifdef OLED_WPM_GRAPH_VERTICAL_LINE # ifdef OLED_WPM_GRAPH_VERTICAL_LINE
@ -577,20 +581,11 @@ void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset) {
} }
} }
# endif # endif
oled_pan(false); // then move the entire graph one pixel to the right # include <math.h>
static const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0}; uint8_t y_start = ceil(vertical_offset / 8);
for (uint8_t i = 0; i < 7; i++) { uint8_t y_length = y_start + ceil(max_lines_graph / 8);
oled_set_cursor(0, i + 8); oled_pan_section(false, y_start, y_length, 3, 125); // then move the entire graph one pixel to the right
oled_write_raw_P(display_border, sizeof(display_border)); timer = timer_read(); // refresh the timer for the next iteration
oled_set_cursor(21, i + 8);
oled_write_raw_P(display_border, sizeof(display_border));
}
static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
oled_set_cursor(0, 15);
oled_write_raw_P(footer_image, sizeof(footer_image));
timer = timer_read(); // refresh the timer for the next iteration
} }
#endif #endif
} }
@ -617,13 +612,13 @@ __attribute__((weak)) void oled_driver_render_logo_right(void) {
// WPM-responsive animation stuff here // WPM-responsive animation stuff here
#define OLED_SLEEP_FRAMES 2 #define OLED_SLEEP_FRAMES 2
#define OLED_SLEEP_SPEED 10 // below this wpm value your animation will idle #define OLED_SLEEP_SPEED 10 // below this wpm value your animation will idle
#define OLED_WAKE_FRAMES 2 // uncomment if >1 #define OLED_WAKE_FRAMES 2 // uncomment if >1
#define OLED_WAKE_SPEED OLED_SLEEP_SPEED // below this wpm value your animation will idle #define OLED_WAKE_SPEED OLED_SLEEP_SPEED // below this wpm value your animation will idle
#define OLED_KAKI_FRAMES 3 #define OLED_KAKI_FRAMES 3
#define OLED_KAKI_SPEED 40 // above this wpm value typing animation to triggere #define OLED_KAKI_SPEED 40 // above this wpm value typing animation to triggere
#define OLED_RTOGI_FRAMES 2 #define OLED_RTOGI_FRAMES 2
//#define OLED_LTOGI_FRAMES 2 //#define OLED_LTOGI_FRAMES 2
@ -781,25 +776,13 @@ void oled_driver_render_logo_left(void) {
# if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE) # if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE)
render_pointing_dpi_status(charybdis_get_pointer_sniping_enabled() ? charybdis_get_pointer_sniping_dpi() : charybdis_get_pointer_default_dpi(), 1); render_pointing_dpi_status(charybdis_get_pointer_sniping_enabled() ? charybdis_get_pointer_sniping_dpi() : charybdis_get_pointer_default_dpi(), 1);
// credit and thanks to jaspertandy on discord for these images // credit and thanks to jaspertandy on discord for these images
static const char PROGMEM mouse_logo[3][2][16] = { static const char PROGMEM mouse_logo[3][2][16] = {// mouse icon
// mouse icon {{0, 0, 0, 252, 2, 2, 2, 58, 2, 2, 2, 252, 0, 0, 0, 0}, {0, 0, 63, 96, 64, 64, 64, 64, 64, 64, 64, 96, 63, 0, 0, 0}},
{ // crosshair icon
{ 0, 0, 0, 252, 2, 2, 2, 58, 2, 2, 2, 252, 0, 0, 0, 0 }, {{128, 240, 136, 228, 146, 138, 202, 127, 202, 138, 146, 228, 136, 240, 128, 0}, {0, 7, 8, 19, 36, 40, 41, 127, 41, 40, 36, 19, 8, 7, 0, 0}},
{ 0, 0, 63, 96, 64, 64, 64, 64, 64, 64, 64, 96, 63, 0, 0, 0 } // dragscroll icon
}, {{0, 0, 112, 136, 156, 2, 15, 1, 15, 2, 140, 68, 56, 0, 0, 0}, {0, 0, 2, 6, 15, 28, 60, 124, 60, 28, 15, 6, 2, 0, 0, 0}}};
// crosshair icon
{
{ 128, 240, 136, 228, 146, 138, 202, 127, 202, 138, 146, 228, 136, 240, 128, 0 },
{ 0, 7, 8, 19, 36, 40, 41, 127, 41, 40, 36, 19, 8, 7, 0, 0 }
},
// dragscroll icon
{
{ 0, 0, 112, 136, 156, 2, 15, 1, 15, 2, 140, 68, 56, 0, 0, 0 },
{ 0, 0, 2, 6, 15, 28, 60, 124, 60, 28, 15, 6, 2, 0, 0, 0 }
}
};
uint8_t image_index = 0; uint8_t image_index = 0;
# ifdef OLED_DISPLAY_TEST # ifdef OLED_DISPLAY_TEST
@ -847,7 +830,7 @@ void render_status_right(void) {
#if !defined(OLED_DISPLAY_VERBOSE) && defined(WPM_ENABLE) && !defined(CONVERT_TO_PROTON_C) #if !defined(OLED_DISPLAY_VERBOSE) && defined(WPM_ENABLE) && !defined(CONVERT_TO_PROTON_C)
render_wpm(2); render_wpm(2);
#endif #endif
render_keylock_status(host_keyboard_leds()); render_keylock_status(host_keyboard_led_state());
} }
void render_status_left(void) { void render_status_left(void) {
@ -860,9 +843,11 @@ void render_status_left(void) {
render_keylogger_status(); render_keylogger_status();
} }
__attribute__((weak)) void oled_render_large_display(void) {} __attribute__((weak)) void oled_render_large_display(bool side) {}
__attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) { return rotation; } __attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation) {
return rotation;
}
oled_rotation_t oled_init_user(oled_rotation_t rotation) { oled_rotation_t oled_init_user(oled_rotation_t rotation) {
if (is_keyboard_master()) { if (is_keyboard_master()) {
@ -876,10 +861,11 @@ oled_rotation_t oled_init_user(oled_rotation_t rotation) {
return oled_init_keymap(rotation); return oled_init_keymap(rotation);
} }
__attribute__((weak)) bool oled_task_keymap(void) { return true; } __attribute__((weak)) bool oled_task_keymap(void) {
return true;
}
bool oled_task_user(void) { bool oled_task_user(void) {
if (is_keyboard_master()) { if (is_keyboard_master()) {
#ifndef OLED_DISPLAY_TEST #ifndef OLED_DISPLAY_TEST
if (timer_elapsed32(oled_timer) > 60000) { if (timer_elapsed32(oled_timer) > 60000) {
@ -896,29 +882,29 @@ bool oled_task_user(void) {
return false; return false;
} }
#if defined(OLED_DISPLAY_128X128)
oled_set_cursor(0, 7);
oled_render_large_display();
#endif
#if defined(OLED_DISPLAY_VERBOSE) #if defined(OLED_DISPLAY_VERBOSE)
static const char PROGMEM header_image[] = { static const char PROGMEM header_image[] = {
0, 192, 32, 16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 7, 15, 31, 63, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 63, 31, 15, 7, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 192, 0, 0, 192, 32, 16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 7, 15, 31, 63, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 63, 31, 15, 7, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 192, 0,
// 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0 // 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0
}; };
static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
oled_set_cursor(0, 0);
oled_write_raw_P(header_image, sizeof(header_image)); oled_write_raw_P(header_image, sizeof(header_image));
oled_set_cursor(0, 1);
#endif #endif
#ifndef OLED_DISPLAY_TEST #ifndef OLED_DISPLAY_TEST
if (is_keyboard_left()) { if (is_keyboard_left()) {
#endif #endif
render_status_left(); render_status_left();
#if defined(OLED_DISPLAY_128X128)
oled_set_cursor(0, 7);
oled_render_large_display(true);
#endif
#ifndef OLED_DISPLAY_TEST #ifndef OLED_DISPLAY_TEST
} else { } else {
render_status_right(); render_status_right();
# if defined(OLED_DISPLAY_128X128)
oled_set_cursor(0, 7);
oled_render_large_display(false);
# endif
} }
#endif #endif
@ -936,6 +922,7 @@ bool oled_task_user(void) {
oled_write_raw_P(display_border, sizeof(display_border)); oled_write_raw_P(display_border, sizeof(display_border));
} }
static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
oled_set_cursor(0, num_of_rows); oled_set_cursor(0, num_of_rows);
oled_write_raw_P(footer_image, sizeof(footer_image)); oled_write_raw_P(footer_image, sizeof(footer_image));
#endif #endif

View File

@ -23,11 +23,11 @@ extern deferred_token kittoken;
void oled_driver_render_logo(void); void oled_driver_render_logo(void);
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record); bool process_record_user_oled(uint16_t keycode, keyrecord_t *record);
oled_rotation_t oled_init_keymap(oled_rotation_t rotation); oled_rotation_t oled_init_keymap(oled_rotation_t rotation);
extern uint32_t oled_timer; void oled_timer_reset(void);
void render_keylogger_status(void); void render_keylogger_status(void);
void render_default_layer_state(void); void render_default_layer_state(void);
void render_layer_state(void); void render_layer_state(void);
void render_keylock_status(uint8_t led_usb_state); void render_keylock_status(led_t led_usb_state);
void render_matrix_scan_rate(uint8_t padding); void render_matrix_scan_rate(uint8_t padding);
void render_mod_status(uint8_t modifiers); void render_mod_status(uint8_t modifiers);
void render_bootmagic_status(void); void render_bootmagic_status(void);
@ -37,9 +37,12 @@ void render_wpm(uint8_t padding);
void render_pointing_dpi_status(uint16_t cpi, uint8_t padding); void render_pointing_dpi_status(uint16_t cpi, uint8_t padding);
void oled_driver_render_logo_left(void); void oled_driver_render_logo_left(void);
void oled_driver_render_logo_right(void); void oled_driver_render_logo_right(void);
void oled_render_large_display(void); void oled_render_large_display(bool side);
void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset); void render_wpm_graph(uint8_t max_lines_graph, uint8_t vertical_offset);
void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end);
#if defined(OLED_DISPLAY_128X128) || defined(OLED_DISPLAY_128X64) #if defined(OLED_DISPLAY_128X128) || defined(OLED_DISPLAY_128X64)
# define OLED_DISPLAY_VERBOSE # define OLED_DISPLAY_VERBOSE

View File

@ -521,6 +521,25 @@ void oled_pan(bool left) {
oled_dirty = OLED_ALL_BLOCKS_MASK; oled_dirty = OLED_ALL_BLOCKS_MASK;
} }
void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end) {
uint16_t i = 0;
for (uint16_t y = y_start; y < y_end; y++) {
if (left) {
for (uint16_t x = x_start; x < x_end - 1; x++) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i + 1];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
} else {
for (uint16_t x = x_end - 1; x > 0; x--) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i - 1];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
}
}
}
oled_buffer_reader_t oled_read_raw(uint16_t start_index) { oled_buffer_reader_t oled_read_raw(uint16_t start_index) {
if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE; if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE;
oled_buffer_reader_t ret_reader; oled_buffer_reader_t ret_reader;

View File

@ -29,7 +29,7 @@ report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
if (x != 0 && y != 0) { if (x != 0 && y != 0) {
mouse_timer = timer_read(); mouse_timer = timer_read();
#ifdef OLED_ENABLE #ifdef OLED_ENABLE
oled_timer = timer_read32(); oled_timer_reset();
#endif #endif
if (timer_elapsed(mouse_debounce_timer) > TAP_CHECK) { if (timer_elapsed(mouse_debounce_timer) > TAP_CHECK) {
if (enable_acceleration) { if (enable_acceleration) {
@ -94,8 +94,10 @@ bool process_record_pointing(uint16_t keycode, keyrecord_t* record) {
record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--; record->event.pressed ? mouse_keycode_tracker++ : mouse_keycode_tracker--;
mouse_timer = timer_read(); mouse_timer = timer_read();
break; break;
#if 0
case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:
break; break;
#endif
case QK_MOD_TAP ... QK_MOD_TAP_MAX: case QK_MOD_TAP ... QK_MOD_TAP_MAX:
if (record->event.pressed || !record->tap.count) { if (record->event.pressed || !record->tap.count) {
break; break;

View File

@ -57,6 +57,9 @@ void keyboard_post_init_rgb_matrix(void) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE); rgb_matrix_mode_noeeprom(RGB_MATRIX_REST_MODE);
} }
#endif #endif
if (userspace_config.rgb_layer_change) {
rgb_matrix_set_flags(LED_FLAG_UNDERGLOW | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR);
}
} }
bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) { bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {

View File

@ -13,8 +13,9 @@ GRAVE_ESC_ENABLE = no
# DEBUG_MATRIX_SCAN_RATE_ENABLE = api # DEBUG_MATRIX_SCAN_RATE_ENABLE = api
ifneq ($(strip $(NO_SECRETS)), yes) ifneq ($(strip $(NO_SECRETS)), yes)
ifneq ("$(wildcard $(USER_PATH)/keyrecords/secrets.c)","") ifneq ("$(wildcard $(USER_PATH)/../../../qmk_secrets/secrets.c)","")
SRC += $(USER_PATH)/keyrecords/secrets.c SRC += $(USER_PATH)/../../../qmk_secrets/secrets.c
SECURE_ENABLE = yes
endif endif
ifeq ($(strip $(NO_SECRETS)), lite) ifeq ($(strip $(NO_SECRETS)), lite)
OPT_DEFS += -DNO_SECRETS OPT_DEFS += -DNO_SECRETS
@ -102,6 +103,7 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
ifeq ($(strip $(CUSTOM_POINTING_DEVICE)), yes) ifeq ($(strip $(CUSTOM_POINTING_DEVICE)), yes)
SRC += $(USER_PATH)/pointing/pointing.c SRC += $(USER_PATH)/pointing/pointing.c
OPT_DEFS += -DCUSTOM_POINTING_DEVICE OPT_DEFS += -DCUSTOM_POINTING_DEVICE
OPT_DEFS += -DMOUSE_EXT_REPORT
endif endif
endif endif
@ -119,9 +121,3 @@ ifeq ($(strip $(AUTOCORRECTION_ENABLE)), yes)
SRC += $(USER_PATH)/keyrecords/autocorrection/autocorrection.c SRC += $(USER_PATH)/keyrecords/autocorrection/autocorrection.c
OPT_DEFS += -DAUTOCORRECTION_ENABLE OPT_DEFS += -DAUTOCORRECTION_ENABLE
endif endif
CAPS_WORD_ENABLE ?= no
ifeq ($(strip $(CAPS_WORD_ENABLE)), yes)
SRC += $(USER_PATH)/keyrecords/caps_word.c
OPT_DEFS += -DCAPS_WORD_ENABLE
endif

View File

@ -11,6 +11,7 @@
#ifdef UNICODE_COMMON_ENABLE #ifdef UNICODE_COMMON_ENABLE
# include "process_unicode_common.h" # include "process_unicode_common.h"
extern unicode_config_t unicode_config; extern unicode_config_t unicode_config;
# include "keyrecords/unicode.h"
#endif #endif
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
# include "audio.h" # include "audio.h"
@ -97,6 +98,7 @@ void user_transport_update(void) {
#endif #endif
#ifdef UNICODE_COMMON_ENABLE #ifdef UNICODE_COMMON_ENABLE
user_state.unicode_mode = unicode_config.input_mode; user_state.unicode_mode = unicode_config.input_mode;
user_state.unicode_typing_mode = typing_mode;
#endif #endif
#ifdef SWAP_HANDS_ENABLE #ifdef SWAP_HANDS_ENABLE
user_state.swap_hands = swap_hands; user_state.swap_hands = swap_hands;
@ -110,6 +112,7 @@ void user_transport_update(void) {
user_state.raw = transport_user_state; user_state.raw = transport_user_state;
#ifdef UNICODE_COMMON_ENABLE #ifdef UNICODE_COMMON_ENABLE
unicode_config.input_mode = user_state.unicode_mode; unicode_config.input_mode = user_state.unicode_mode;
typing_mode = user_state.unicode_typing_mode;
#endif #endif
#if defined(CUSTOM_POINTING_DEVICE) #if defined(CUSTOM_POINTING_DEVICE)
tap_toggling = user_state.tap_toggling; tap_toggling = user_state.tap_toggling;

View File

@ -12,12 +12,13 @@ extern char keylog_str[OLED_KEYLOGGER_LENGTH];
typedef union { typedef union {
uint32_t raw; uint32_t raw;
struct { struct {
bool audio_enable :1; bool audio_enable :1;
bool audio_clicky_enable :1; bool audio_clicky_enable :1;
bool tap_toggling :1; bool tap_toggling :1;
uint8_t unicode_mode :3; uint8_t unicode_mode :3;
bool swap_hands :1; bool swap_hands :1;
bool host_driver_disabled :1; bool host_driver_disabled :1;
uint8_t unicode_typing_mode :3;
}; };
} user_runtime_config_t; } user_runtime_config_t;

View File

@ -25,21 +25,6 @@ __attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *
// And use "NEWPLACEHOLDER" for new safe range // And use "NEWPLACEHOLDER" for new safe range
bool process_record_user(uint16_t keycode, keyrecord_t *record) { bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) { switch (keycode) {
case KC_MAKE:
if (!record->event.pressed) {
SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
#if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
":dfu"
#elif defined(BOOTLOADER_HALFKAY)
":teensy"
#elif defined(BOOTLOADER_CATERINA)
":avrdude"
#endif
SS_TAP(X_ENTER));
}
return false;
break;
case VRSN: case VRSN:
if (record->event.pressed) { if (record->event.pressed) {
SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION); SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);

View File

@ -12,7 +12,7 @@
enum custom_keycodes { enum custom_keycodes {
VRSN = SAFE_RANGE, // can always be here VRSN = SAFE_RANGE, // can always be here
KC_MAKE, QK_MAKE,
KC_RESET, QK_BOOT,
NEWPLACEHOLDER // use "NEWPLACEHOLDER for keymap specific codes NEWPLACEHOLDER // use "NEWPLACEHOLDER for keymap specific codes
}; };