From d9be6dea3a545da8d6f3d3ace14b6df7e9b6f30e Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Tue, 19 Oct 2021 08:29:27 +1100 Subject: [PATCH 0001/1136] Fix builds for ChibiOS + Cortex-M0[+] (#14879) --- tmk_core/chibios.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index cae840fa4ff5..ad0ffa762d92 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk @@ -330,7 +330,7 @@ ifeq ($(strip $(MCU)), risc-v) endif endif endif - + # Default to compiling with picolibc for RISC-V targets if available, # which is available by default on current (bullseye) debian based systems. ifeq ($(shell $(TOOLCHAIN)gcc --specs=picolibc.specs -E - 2>/dev/null >/dev/null Date: Tue, 19 Oct 2021 16:26:59 +0200 Subject: [PATCH 0002/1136] [DOCS] Fix the STENO_COMBINEDMAP table (#14883) --- docs/feature_stenography.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/feature_stenography.md b/docs/feature_stenography.md index af4754ed7833..8d66034d4b5b 100644 --- a/docs/feature_stenography.md +++ b/docs/feature_stenography.md @@ -129,7 +129,8 @@ As defined in `keymap_steno.h`. |`STN_RES2`||(GeminiPR only)| |`STN_PWR`||(GeminiPR only)| -If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file +If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file. + |Combined key | Key1 | Key 2 | |---------------|--------|----------| |STN_S3 | STN_S1 | STN_S2 | From c9562ebfde8bab54c83215c4970163d19ce199b1 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Wed, 20 Oct 2021 04:48:01 +0300 Subject: [PATCH 0003/1136] Make the MAGIC_TOGGLE_GUI keycode work (#14886) --- quantum/process_keycode/process_magic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c index 01f2fb92892b..d5cff4f12aa9 100644 --- a/quantum/process_keycode/process_magic.c +++ b/quantum/process_keycode/process_magic.c @@ -43,6 +43,7 @@ bool process_magic(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI: case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT: + case MAGIC_TOGGLE_GUI: /* keymap config */ keymap_config.raw = eeconfig_read_keymap(); switch (keycode) { From 0fd45d59845d71e435f36975d9ba8a54dfb2a87d Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Tue, 19 Oct 2021 20:50:44 -0700 Subject: [PATCH 0004/1136] Fix type of Tap Dance max index variable (#14887) --- quantum/process_keycode/process_tap_dance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 225b36cd5fd6..c707fdea308e 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -20,7 +20,7 @@ uint8_t get_oneshot_mods(void); #endif static uint16_t last_td; -static int8_t highest_td = -1; +static int16_t highest_td = -1; void qk_tap_dance_pair_on_each_tap(qk_tap_dance_state_t *state, void *user_data) { qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; From 84d5198ef9b4106fe61530211b5b5bb1a2fc52c8 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 20 Oct 2021 20:07:40 +0100 Subject: [PATCH 0005/1136] Align PS/2 GPIO defines (#14745) * Align PS/2 GPIO * Align PS/2 GPIO * refactor more keyboards * Remove more defines * Put back avr/chibios split * format --- docs/feature_ps2_mouse.md | 34 +++---------- docs/ja/feature_ps2_mouse.md | 31 +++--------- keyboards/converter/ibm_terminal/config.h | 33 +++---------- .../evyd13/gh80_3700/keymaps/ps2/config.h | 10 +--- .../handwired/108key_trackpoint/config.h | 10 +--- keyboards/handwired/promethium/config.h | 30 +++--------- keyboards/handwired/trackpoint/config.h | 10 +--- keyboards/kapcave/paladin64/config.h | 20 ++------ tmk_core/protocol/ps2_interrupt.c | 18 +++---- tmk_core/protocol/ps2_io_avr.c | 49 ++++++++----------- tmk_core/protocol/ps2_io_chibios.c | 28 +++++------ tmk_core/protocol/ps2_usart.c | 13 +++++ 12 files changed, 94 insertions(+), 192 deletions(-) diff --git a/docs/feature_ps2_mouse.md b/docs/feature_ps2_mouse.md index 433a47fa9b89..c980705ae7f9 100644 --- a/docs/feature_ps2_mouse.md +++ b/docs/feature_ps2_mouse.md @@ -39,14 +39,8 @@ In your keyboard config.h: ```c #ifdef PS2_USE_BUSYWAIT -# define PS2_CLOCK_PORT PORTD -# define PS2_CLOCK_PIN PIND -# define PS2_CLOCK_DDR DDRD -# define PS2_CLOCK_BIT 1 -# define PS2_DATA_PORT PORTD -# define PS2_DATA_PIN PIND -# define PS2_DATA_DDR DDRD -# define PS2_DATA_BIT 2 +# define PS2_CLOCK_PIN D1 +# define PS2_DATA_PIN D2 #endif ``` @@ -65,14 +59,8 @@ In your keyboard config.h: ```c #ifdef PS2_USE_INT -#define PS2_CLOCK_PORT PORTD -#define PS2_CLOCK_PIN PIND -#define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 2 -#define PS2_DATA_PORT PORTD -#define PS2_DATA_PIN PIND -#define PS2_DATA_DDR DDRD -#define PS2_DATA_BIT 5 +#define PS2_CLOCK_PIN D2 +#define PS2_DATA_PIN D5 #define PS2_INT_INIT() do { \ EICRA |= ((1<. */ #ifdef PS2_USE_USART /* XCK for clock line */ -#define PS2_CLOCK_PORT PORTD -#define PS2_CLOCK_PIN PIND -#define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 5 -/* RXD for data line */ -#define PS2_DATA_PORT PORTD -#define PS2_DATA_PIN PIND -#define PS2_DATA_DDR DDRD -#define PS2_DATA_BIT 2 +#define PS2_CLOCK_PIN D5 +#define PS2_DATA_PIN D2 /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ /* set DDR of CLOCK as input to be slave */ @@ -93,15 +86,8 @@ along with this program. If not, see . */ #ifdef PS2_USE_INT /* uses INT1 for clock line(ATMega32U4) */ -#define PS2_CLOCK_PORT PORTD -#define PS2_CLOCK_PIN PIND -#define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 1 - -#define PS2_DATA_PORT PORTD -#define PS2_DATA_PIN PIND -#define PS2_DATA_DDR DDRD -#define PS2_DATA_BIT 0 +#define PS2_CLOCK_PIN D1 +#define PS2_DATA_PIN D0 #define PS2_INT_INIT() do { \ EICRA |= ((1<. * PS/2 Busywait configuration */ #ifdef PS2_USE_BUSYWAIT -#define PS2_CLOCK_PORT PORTD -#define PS2_CLOCK_PIN PIND -#define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 1 - -#define PS2_DATA_PORT PORTD -#define PS2_DATA_PIN PIND -#define PS2_DATA_DDR DDRD -#define PS2_DATA_BIT 0 +#define PS2_CLOCK_PIN D1 +#define PS2_DATA_PIN D0 #endif diff --git a/keyboards/evyd13/gh80_3700/keymaps/ps2/config.h b/keyboards/evyd13/gh80_3700/keymaps/ps2/config.h index 44ac7dcd034c..b77ac95d7d47 100644 --- a/keyboards/evyd13/gh80_3700/keymaps/ps2/config.h +++ b/keyboards/evyd13/gh80_3700/keymaps/ps2/config.h @@ -17,14 +17,8 @@ #pragma once #ifdef PS2_USE_USART -#define PS2_CLOCK_PORT PORTD -#define PS2_CLOCK_PIN PIND -#define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 5 -#define PS2_DATA_PORT PORTD -#define PS2_DATA_PIN PIND -#define PS2_DATA_DDR DDRD -#define PS2_DATA_BIT 2 +#define PS2_CLOCK_PIN D5 +#define PS2_DATA_PIN D2 /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ /* set DDR of CLOCK as input to be slave */ diff --git a/keyboards/handwired/108key_trackpoint/config.h b/keyboards/handwired/108key_trackpoint/config.h index b1ac790d7639..b5bf98271afb 100644 --- a/keyboards/handwired/108key_trackpoint/config.h +++ b/keyboards/handwired/108key_trackpoint/config.h @@ -12,14 +12,8 @@ #define MATRIX_COLS 23 #ifdef PS2_USE_USART - #define PS2_CLOCK_PORT PORTD - #define PS2_CLOCK_PIN PIND - #define PS2_CLOCK_DDR DDRD - #define PS2_CLOCK_BIT 5 - #define PS2_DATA_PORT PORTD - #define PS2_DATA_PIN PIND - #define PS2_DATA_DDR DDRD - #define PS2_DATA_BIT 2 +#define PS2_CLOCK_PIN D5 +#define PS2_DATA_PIN D2 /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ /* set DDR of CLOCK as input to be slave */ diff --git a/keyboards/handwired/promethium/config.h b/keyboards/handwired/promethium/config.h index b146767d65de..612675c63a07 100644 --- a/keyboards/handwired/promethium/config.h +++ b/keyboards/handwired/promethium/config.h @@ -224,27 +224,15 @@ enum led_sequence { /* PS/2 mouse */ #ifdef PS2_USE_BUSYWAIT -# define PS2_CLOCK_PORT PORTD -# define PS2_CLOCK_PIN PIND -# define PS2_CLOCK_DDR DDRD -# define PS2_CLOCK_BIT 3 -# define PS2_DATA_PORT PORTD -# define PS2_DATA_PIN PIND -# define PS2_DATA_DDR DDRD -# define PS2_DATA_BIT 2 +# define PS2_CLOCK_PIN D3 +# define PS2_DATA_PIN D2 #endif /* PS/2 mouse interrupt version */ #ifdef PS2_USE_INT /* uses INT1 for clock line(ATMega32U4) */ -# define PS2_CLOCK_PORT PORTD -# define PS2_CLOCK_PIN PIND -# define PS2_CLOCK_DDR DDRD -# define PS2_CLOCK_BIT 3 -# define PS2_DATA_PORT PORTD -# define PS2_DATA_PIN PIND -# define PS2_DATA_DDR DDRD -# define PS2_DATA_BIT 2 +# define PS2_CLOCK_PIN D3 +# define PS2_DATA_PIN D2 # define PS2_INT_INIT() \ do { \ @@ -264,14 +252,8 @@ enum led_sequence { /* PS/2 mouse USART version */ #ifdef PS2_USE_USART /* XCK for clock line and RXD for data line */ -# define PS2_CLOCK_PORT PORTD -# define PS2_CLOCK_PIN PIND -# define PS2_CLOCK_DDR DDRD -# define PS2_CLOCK_BIT 5 -# define PS2_DATA_PORT PORTD -# define PS2_DATA_PIN PIND -# define PS2_DATA_DDR DDRD -# define PS2_DATA_BIT 2 +#define PS2_CLOCK_PIN D5 +#define PS2_DATA_PIN D2 /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ /* set DDR of CLOCK as input to be slave */ diff --git a/keyboards/handwired/trackpoint/config.h b/keyboards/handwired/trackpoint/config.h index 1429136f403d..cf8b5605f43a 100644 --- a/keyboards/handwired/trackpoint/config.h +++ b/keyboards/handwired/trackpoint/config.h @@ -12,14 +12,8 @@ #define MATRIX_COLS 3 #ifdef PS2_USE_USART - #define PS2_CLOCK_PORT PORTD - #define PS2_CLOCK_PIN PIND - #define PS2_CLOCK_DDR DDRD - #define PS2_CLOCK_BIT 5 - #define PS2_DATA_PORT PORTD - #define PS2_DATA_PIN PIND - #define PS2_DATA_DDR DDRD - #define PS2_DATA_BIT 2 +#define PS2_CLOCK_PIN D5 +#define PS2_DATA_PIN D2 /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */ /* set DDR of CLOCK as input to be slave */ diff --git a/keyboards/kapcave/paladin64/config.h b/keyboards/kapcave/paladin64/config.h index 2685be96cf86..7c3d1a0fa111 100755 --- a/keyboards/kapcave/paladin64/config.h +++ b/keyboards/kapcave/paladin64/config.h @@ -34,14 +34,8 @@ along with this program. If not, see . /* Only required if you add in a trackpoint hardware to the pcb */ #ifdef PS2_USE_USART - #define PS2_CLOCK_PORT PORTD - #define PS2_CLOCK_PIN PIND - #define PS2_CLOCK_DDR DDRD - #define PS2_CLOCK_BIT 5 - #define PS2_DATA_PORT PORTD - #define PS2_DATA_PIN PIND - #define PS2_DATA_DDR DDRD - #define PS2_DATA_BIT 2 +#define PS2_CLOCK_PIN D5 +#define PS2_DATA_PIN D2 /* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling * edge */ @@ -77,14 +71,8 @@ along with this program. If not, see . #endif #ifdef PS2_USE_INT -#define PS2_CLOCK_PORT PORTD -#define PS2_CLOCK_PIN PIND -#define PS2_CLOCK_DDR DDRD -#define PS2_CLOCK_BIT 2 -#define PS2_DATA_PORT PORTD -#define PS2_DATA_PIN PIND -#define PS2_DATA_DDR DDRD -#define PS2_DATA_BIT 5 +#define PS2_CLOCK_PIN D2 +#define PS2_DATA_PIN D5 #define PS2_INT_INIT() do { \ EICRA |= ((1< -#include -#include +#include "ps2_io.h" +#include "gpio.h" +#include "wait.h" /* Check port settings for clock and data line */ -#if !(defined(PS2_CLOCK_PORT) && defined(PS2_CLOCK_PIN) && defined(PS2_CLOCK_DDR) && defined(PS2_CLOCK_BIT)) -# error "PS/2 clock port setting is required in config.h" +#if !(defined(PS2_CLOCK_PIN)) +# error "PS/2 clock setting is required in config.h" #endif -#if !(defined(PS2_DATA_PORT) && defined(PS2_DATA_PIN) && defined(PS2_DATA_DDR) && defined(PS2_DATA_BIT)) -# error "PS/2 data port setting is required in config.h" +#if !(defined(PS2_DATA_PIN)) +# error "PS/2 data setting is required in config.h" #endif /* @@ -17,21 +18,17 @@ void clock_init(void) {} void clock_lo(void) { - PS2_CLOCK_PORT &= ~(1 << PS2_CLOCK_BIT); - PS2_CLOCK_DDR |= (1 << PS2_CLOCK_BIT); + // Transition from input with pull-up to output low via Hi-Z instead of output high + writePinLow(PS2_CLOCK_PIN); + setPinOutput(PS2_CLOCK_PIN); } -void clock_hi(void) { - /* input with pull up */ - PS2_CLOCK_DDR &= ~(1 << PS2_CLOCK_BIT); - PS2_CLOCK_PORT |= (1 << PS2_CLOCK_BIT); -} +void clock_hi(void) { setPinInputHigh(PS2_CLOCK_PIN); } bool clock_in(void) { - PS2_CLOCK_DDR &= ~(1 << PS2_CLOCK_BIT); - PS2_CLOCK_PORT |= (1 << PS2_CLOCK_BIT); - _delay_us(1); - return PS2_CLOCK_PIN & (1 << PS2_CLOCK_BIT); + setPinInputHigh(PS2_CLOCK_PIN); + wait_us(1); + return readPin(PS2_CLOCK_PIN); } /* @@ -40,19 +37,15 @@ bool clock_in(void) { void data_init(void) {} void data_lo(void) { - PS2_DATA_PORT &= ~(1 << PS2_DATA_BIT); - PS2_DATA_DDR |= (1 << PS2_DATA_BIT); + // Transition from input with pull-up to output low via Hi-Z instead of output high + writePinLow(PS2_DATA_PIN); + setPinOutput(PS2_DATA_PIN); } -void data_hi(void) { - /* input with pull up */ - PS2_DATA_DDR &= ~(1 << PS2_DATA_BIT); - PS2_DATA_PORT |= (1 << PS2_DATA_BIT); -} +void data_hi(void) { setPinInputHigh(PS2_DATA_PIN); } bool data_in(void) { - PS2_DATA_DDR &= ~(1 << PS2_DATA_BIT); - PS2_DATA_PORT |= (1 << PS2_DATA_BIT); - _delay_us(1); - return PS2_DATA_PIN & (1 << PS2_DATA_BIT); + setPinInputHigh(PS2_DATA_PIN); + wait_us(1); + return readPin(PS2_DATA_PIN); } diff --git a/tmk_core/protocol/ps2_io_chibios.c b/tmk_core/protocol/ps2_io_chibios.c index b672bd1f47fa..906d85d84840 100644 --- a/tmk_core/protocol/ps2_io_chibios.c +++ b/tmk_core/protocol/ps2_io_chibios.c @@ -6,11 +6,11 @@ #include "hal.h" /* Check port settings for clock and data line */ -#if !(defined(PS2_CLOCK)) +#if !(defined(PS2_CLOCK_PIN)) # error "PS/2 clock setting is required in config.h" #endif -#if !(defined(PS2_DATA)) +#if !(defined(PS2_DATA_PIN)) # error "PS/2 data setting is required in config.h" #endif @@ -20,18 +20,18 @@ void clock_init(void) {} void clock_lo(void) { - palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN); - palWriteLine(PS2_CLOCK, PAL_LOW); + palSetLineMode(PS2_CLOCK_PIN, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_CLOCK_PIN, PAL_LOW); } void clock_hi(void) { - palSetLineMode(PS2_CLOCK, PAL_MODE_OUTPUT_OPENDRAIN); - palWriteLine(PS2_CLOCK, PAL_HIGH); + palSetLineMode(PS2_CLOCK_PIN, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_CLOCK_PIN, PAL_HIGH); } bool clock_in(void) { - palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); - return palReadLine(PS2_CLOCK); + palSetLineMode(PS2_CLOCK_PIN, PAL_MODE_INPUT); + return palReadLine(PS2_CLOCK_PIN); } /* @@ -40,16 +40,16 @@ bool clock_in(void) { void data_init(void) {} void data_lo(void) { - palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN); - palWriteLine(PS2_DATA, PAL_LOW); + palSetLineMode(PS2_DATA_PIN, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_DATA_PIN, PAL_LOW); } void data_hi(void) { - palSetLineMode(PS2_DATA, PAL_MODE_OUTPUT_OPENDRAIN); - palWriteLine(PS2_DATA, PAL_HIGH); + palSetLineMode(PS2_DATA_PIN, PAL_MODE_OUTPUT_OPENDRAIN); + palWriteLine(PS2_DATA_PIN, PAL_HIGH); } bool data_in(void) { - palSetLineMode(PS2_DATA, PAL_MODE_INPUT); - return palReadLine(PS2_DATA); + palSetLineMode(PS2_DATA_PIN, PAL_MODE_INPUT); + return palReadLine(PS2_DATA_PIN); } diff --git a/tmk_core/protocol/ps2_usart.c b/tmk_core/protocol/ps2_usart.c index 6a66dc4a1e73..5f70083698fa 100644 --- a/tmk_core/protocol/ps2_usart.c +++ b/tmk_core/protocol/ps2_usart.c @@ -46,6 +46,19 @@ POSSIBILITY OF SUCH DAMAGE. #include "ps2_io.h" #include "print.h" +#ifndef PS2_CLOCK_DDR +# define PS2_CLOCK_DDR PORTx_ADDRESS(PS2_CLOCK_PIN) +#endif +#ifndef PS2_CLOCK_BIT +# define PS2_CLOCK_BIT (PS2_CLOCK_PIN & 0xF) +#endif +#ifndef PS2_DATA_DDR +# define PS2_DATA_DDR PORTx_ADDRESS(PS2_DATA_PIN) +#endif +#ifndef PS2_DATA_BIT +# define PS2_DATA_BIT (PS2_DATA_PIN & 0xF) +#endif + #define WAIT(stat, us, err) \ do { \ if (!wait_##stat(us)) { \ From 5500c428dd41348243e8a1695986b0da070e2ffa Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 20 Oct 2021 21:04:23 +0100 Subject: [PATCH 0006/1136] Rename platform SRC variable (#14894) --- build_keyboard.mk | 8 ++++---- tmk_core/chibios.mk | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/build_keyboard.mk b/build_keyboard.mk index 36807911d85d..e5edacfd8a6f 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -435,15 +435,15 @@ ALL_CONFIGS := $(PROJECT_CONFIG) $(CONFIG_H) OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT) $(KEYMAP_OUTPUT)_SRC := $(SRC) -$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) $(GFXDEFS) \ +$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) \ -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYBOARD_H=\"$(QMK_KEYBOARD_H)\" \ -DQMK_KEYMAP=\"$(KEYMAP)\" -DQMK_KEYMAP_H=\"$(KEYMAP).h\" -DQMK_KEYMAP_CONFIG_H=\"$(KEYMAP_PATH)/config.h\" \ -DQMK_SUBPROJECT -DQMK_SUBPROJECT_H -DQMK_SUBPROJECT_CONFIG_H $(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS) $(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H) -$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC) $(GFXSRC) -$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) $(GFXDEFS) -$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(GFXINC) +$(KEYBOARD_OUTPUT)_SRC := $(PLATFORM_SRC) +$(KEYBOARD_OUTPUT)_DEFS := $(PROJECT_DEFS) +$(KEYBOARD_OUTPUT)_INC := $(PROJECT_INC) $(KEYBOARD_OUTPUT)_CONFIG := $(PROJECT_CONFIG) # Default target. diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index ad0ffa762d92..c520d6025b76 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk @@ -232,7 +232,8 @@ include $(CHIBIOS)/os/rt/rt.mk # Other files (optional). include $(CHIBIOS)/os/hal/lib/streams/streams.mk -CHIBISRC = $(STARTUPSRC) \ +PLATFORM_SRC = \ + $(STARTUPSRC) \ $(KERNSRC) \ $(PORTSRC) \ $(OSALSRC) \ @@ -247,7 +248,7 @@ CHIBISRC = $(STARTUPSRC) \ # Ensure the ASM files are not subjected to LTO -- it'll strip out interrupt handlers otherwise. QUANTUM_LIB_SRC += $(STARTUPASM) $(PORTASM) $(OSALASM) $(PLATFORMASM) -CHIBISRC := $(patsubst $(TOP_DIR)/%,%,$(CHIBISRC)) +PLATFORM_SRC := $(patsubst $(TOP_DIR)/%,%,$(PLATFORM_SRC)) EXTRAINCDIRS += $(CHIBIOS)/os/license $(CHIBIOS)/os/oslib/include \ $(TOP_DIR)/platforms/chibios/boards/$(BOARD)/configs \ @@ -278,7 +279,7 @@ endif ifeq ($(strip $(USE_CHIBIOS_CONTRIB)),yes) include $(CHIBIOS_CONTRIB)/os/hal/hal.mk - CHIBISRC += $(PLATFORMSRC_CONTRIB) $(HALSRC_CONTRIB) + PLATFORM_SRC += $(PLATFORMSRC_CONTRIB) $(HALSRC_CONTRIB) EXTRAINCDIRS += $(PLATFORMINC_CONTRIB) $(HALINC_CONTRIB) $(CHIBIOS_CONTRIB)/os/various endif From d4be4b67a251ecc046d857c5cd00cfb37c394ab7 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 20 Oct 2021 21:18:49 +0100 Subject: [PATCH 0007/1136] Relocate PS2 code (#14895) * Relocate ps2 protocol code * clang * Move makefile logic --- common_features.mk | 34 +++++++++++++++++++ {tmk_core/protocol => drivers/ps2}/ps2.h | 0 .../protocol => drivers/ps2}/ps2_busywait.c | 0 .../protocol => drivers/ps2}/ps2_interrupt.c | 0 {tmk_core/protocol => drivers/ps2}/ps2_io.h | 0 .../protocol => drivers/ps2}/ps2_mouse.c | 10 ++---- .../protocol => drivers/ps2}/ps2_mouse.h | 0 .../avr/drivers/ps2/ps2_io.c | 0 .../avr/drivers/ps2}/ps2_usart.c | 1 + .../chibios/drivers/ps2/ps2_io.c | 0 tmk_core/protocol.mk | 25 -------------- 11 files changed, 38 insertions(+), 32 deletions(-) rename {tmk_core/protocol => drivers/ps2}/ps2.h (100%) rename {tmk_core/protocol => drivers/ps2}/ps2_busywait.c (100%) rename {tmk_core/protocol => drivers/ps2}/ps2_interrupt.c (100%) rename {tmk_core/protocol => drivers/ps2}/ps2_io.h (100%) rename {tmk_core/protocol => drivers/ps2}/ps2_mouse.c (98%) rename {tmk_core/protocol => drivers/ps2}/ps2_mouse.h (100%) rename tmk_core/protocol/ps2_io_avr.c => platforms/avr/drivers/ps2/ps2_io.c (100%) rename {tmk_core/protocol => platforms/avr/drivers/ps2}/ps2_usart.c (99%) rename tmk_core/protocol/ps2_io_chibios.c => platforms/chibios/drivers/ps2/ps2_io.c (100%) diff --git a/common_features.mk b/common_features.mk index 9b9425dc33cd..083aa4aaa4f5 100644 --- a/common_features.mk +++ b/common_features.mk @@ -576,6 +576,40 @@ ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes) endif endif +ifeq ($(strip $(PS2_MOUSE_ENABLE)), yes) + PS2_ENABLE := yes + SRC += ps2_mouse.c + OPT_DEFS += -DPS2_MOUSE_ENABLE + OPT_DEFS += -DMOUSE_ENABLE +endif + +ifeq ($(strip $(PS2_USE_BUSYWAIT)), yes) + PS2_ENABLE := yes + SRC += ps2_busywait.c + SRC += ps2_io_avr.c + OPT_DEFS += -DPS2_USE_BUSYWAIT +endif + +ifeq ($(strip $(PS2_USE_INT)), yes) + PS2_ENABLE := yes + SRC += ps2_interrupt.c + SRC += ps2_io.c + OPT_DEFS += -DPS2_USE_INT +endif + +ifeq ($(strip $(PS2_USE_USART)), yes) + PS2_ENABLE := yes + SRC += ps2_usart.c + SRC += ps2_io.c + OPT_DEFS += -DPS2_USE_USART +endif + +ifeq ($(strip $(PS2_ENABLE)), yes) + COMMON_VPATH += $(DRIVER_PATH)/ps2 + COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/ps2 + OPT_DEFS += -DPS2_ENABLE +endif + JOYSTICK_ENABLE ?= no VALID_JOYSTICK_TYPES := analog digital JOYSTICK_DRIVER ?= analog diff --git a/tmk_core/protocol/ps2.h b/drivers/ps2/ps2.h similarity index 100% rename from tmk_core/protocol/ps2.h rename to drivers/ps2/ps2.h diff --git a/tmk_core/protocol/ps2_busywait.c b/drivers/ps2/ps2_busywait.c similarity index 100% rename from tmk_core/protocol/ps2_busywait.c rename to drivers/ps2/ps2_busywait.c diff --git a/tmk_core/protocol/ps2_interrupt.c b/drivers/ps2/ps2_interrupt.c similarity index 100% rename from tmk_core/protocol/ps2_interrupt.c rename to drivers/ps2/ps2_interrupt.c diff --git a/tmk_core/protocol/ps2_io.h b/drivers/ps2/ps2_io.h similarity index 100% rename from tmk_core/protocol/ps2_io.h rename to drivers/ps2/ps2_io.h diff --git a/tmk_core/protocol/ps2_mouse.c b/drivers/ps2/ps2_mouse.c similarity index 98% rename from tmk_core/protocol/ps2_mouse.c rename to drivers/ps2/ps2_mouse.c index 39251a643437..8a6668b41069 100644 --- a/tmk_core/protocol/ps2_mouse.c +++ b/drivers/ps2/ps2_mouse.c @@ -16,13 +16,9 @@ along with this program. If not, see . */ #include - -#if defined(__AVR__) -# include -#endif - #include "ps2_mouse.h" #include "wait.h" +#include "gpio.h" #include "host.h" #include "timer.h" #include "print.h" @@ -158,8 +154,8 @@ static inline void ps2_mouse_convert_report_to_hid(report_mouse_t *mouse_report) #ifdef PS2_MOUSE_INVERT_BUTTONS // swap left & right buttons - uint8_t needs_left = mouse_report->buttons & PS2_MOUSE_BTN_RIGHT; - uint8_t needs_right = mouse_report->buttons & PS2_MOUSE_BTN_LEFT; + uint8_t needs_left = mouse_report->buttons & PS2_MOUSE_BTN_RIGHT; + uint8_t needs_right = mouse_report->buttons & PS2_MOUSE_BTN_LEFT; mouse_report->buttons = (mouse_report->buttons & ~(PS2_MOUSE_BTN_MASK)) | (needs_left ? PS2_MOUSE_BTN_LEFT : 0) | (needs_right ? PS2_MOUSE_BTN_RIGHT : 0); #else // remove sign and overflow flags diff --git a/tmk_core/protocol/ps2_mouse.h b/drivers/ps2/ps2_mouse.h similarity index 100% rename from tmk_core/protocol/ps2_mouse.h rename to drivers/ps2/ps2_mouse.h diff --git a/tmk_core/protocol/ps2_io_avr.c b/platforms/avr/drivers/ps2/ps2_io.c similarity index 100% rename from tmk_core/protocol/ps2_io_avr.c rename to platforms/avr/drivers/ps2/ps2_io.c diff --git a/tmk_core/protocol/ps2_usart.c b/platforms/avr/drivers/ps2/ps2_usart.c similarity index 99% rename from tmk_core/protocol/ps2_usart.c rename to platforms/avr/drivers/ps2/ps2_usart.c index 5f70083698fa..151cfcd68f3a 100644 --- a/tmk_core/protocol/ps2_usart.c +++ b/platforms/avr/drivers/ps2/ps2_usart.c @@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include "gpio.h" #include "ps2.h" #include "ps2_io.h" #include "print.h" diff --git a/tmk_core/protocol/ps2_io_chibios.c b/platforms/chibios/drivers/ps2/ps2_io.c similarity index 100% rename from tmk_core/protocol/ps2_io_chibios.c rename to platforms/chibios/drivers/ps2/ps2_io.c diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index 30c87a0f124a..8aa063c9116c 100644 --- a/tmk_core/protocol.mk +++ b/tmk_core/protocol.mk @@ -1,30 +1,5 @@ PROTOCOL_DIR = protocol -ifeq ($(strip $(PS2_MOUSE_ENABLE)), yes) - SRC += $(PROTOCOL_DIR)/ps2_mouse.c - OPT_DEFS += -DPS2_MOUSE_ENABLE - OPT_DEFS += -DMOUSE_ENABLE -endif - -ifeq ($(strip $(PS2_USE_BUSYWAIT)), yes) - SRC += protocol/ps2_busywait.c - SRC += protocol/ps2_io_avr.c - OPT_DEFS += -DPS2_USE_BUSYWAIT -endif - -ifeq ($(strip $(PS2_USE_INT)), yes) - SRC += protocol/ps2_interrupt.c - SRC += protocol/ps2_io_$(PLATFORM_KEY).c - OPT_DEFS += -DPS2_USE_INT -endif - -ifeq ($(strip $(PS2_USE_USART)), yes) - SRC += protocol/ps2_usart.c - SRC += protocol/ps2_io_$(PLATFORM_KEY).c - OPT_DEFS += -DPS2_USE_USART -endif - - ifeq ($(strip $(SERIAL_MOUSE_MICROSOFT_ENABLE)), yes) SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \ From 1816006121de991581d50d0bc6b5a653e2b3ccd2 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 20 Oct 2021 21:27:46 +0100 Subject: [PATCH 0008/1136] Tidy up LCD_ENABLE/visualizer references (#14855) * Tidy up LCD_ENABLE/visualizer references * Fix up my (333fred) ergodox keymap with new LCD driver Co-authored-by: Fredric Silberberg --- common_features.mk | 4 - .../keymaps/dudeofawesome/config.h | 2 - .../keymaps/dudeofawesome/keymap.c | 4 +- .../keymaps/dudeofawesome/simple_visualizer.h | 123 ------ .../keymaps/dudeofawesome/visualizer.c | 79 ---- .../keymaps/dudeofawesome/visualizer.h | 35 -- .../keymaps/halfkeyboard/visualizer.c | 384 ------------------ .../keymaps/halfkeyboard/visualizer.h | 125 ------ layouts/community/ergodox/333fred/keymap.c | 40 ++ layouts/community/ergodox/333fred/rules.mk | 3 - .../community/ergodox/333fred/visualizer.c | 39 -- .../community/ergodox/adnw_p_u_q/visualizer.c | 34 -- layouts/community/ergodox/belak/keymap.c | 35 +- layouts/community/ergodox/belak/visualizer.c | 49 --- .../ergodox/choromanski/visualizer.c | 62 --- .../ergodox/drashna/visualizer.c_old | 77 ---- .../community/ergodox/osx_neo2/visualizer.c | 47 --- show_options.mk | 1 - users/talljoe/visualizer.c | 21 - 19 files changed, 57 insertions(+), 1107 deletions(-) delete mode 100644 keyboards/ergodox_infinity/keymaps/dudeofawesome/simple_visualizer.h delete mode 100644 keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.c delete mode 100644 keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.h delete mode 100644 keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.c delete mode 100644 keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.h delete mode 100644 layouts/community/ergodox/333fred/visualizer.c delete mode 100644 layouts/community/ergodox/adnw_p_u_q/visualizer.c delete mode 100644 layouts/community/ergodox/belak/visualizer.c delete mode 100644 layouts/community/ergodox/choromanski/visualizer.c delete mode 100644 layouts/community/ergodox/drashna/visualizer.c_old delete mode 100644 layouts/community/ergodox/osx_neo2/visualizer.c delete mode 100644 users/talljoe/visualizer.c diff --git a/common_features.mk b/common_features.mk index 083aa4aaa4f5..af538b696f71 100644 --- a/common_features.mk +++ b/common_features.mk @@ -326,10 +326,6 @@ ifneq ($(strip $(VARIABLE_TRACE)),no) endif endif -ifeq ($(strip $(LCD_ENABLE)), yes) - CIE1931_CURVE := yes -endif - VALID_BACKLIGHT_TYPES := pwm timer software custom BACKLIGHT_ENABLE ?= no diff --git a/keyboards/ergodox_infinity/keymaps/dudeofawesome/config.h b/keyboards/ergodox_infinity/keymaps/dudeofawesome/config.h index 161958233e28..9dcf8a7f43e6 100644 --- a/keyboards/ergodox_infinity/keymaps/dudeofawesome/config.h +++ b/keyboards/ergodox_infinity/keymaps/dudeofawesome/config.h @@ -6,6 +6,4 @@ #include "../../config.h" #include "dudeofawesome.h" -#include "./visualizer.h" - #endif diff --git a/keyboards/ergodox_infinity/keymaps/dudeofawesome/keymap.c b/keyboards/ergodox_infinity/keymaps/dudeofawesome/keymap.c index c3ea48654da4..675b56edec77 100644 --- a/keyboards/ergodox_infinity/keymaps/dudeofawesome/keymap.c +++ b/keyboards/ergodox_infinity/keymaps/dudeofawesome/keymap.c @@ -471,8 +471,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { }; void matrix_init_user() { - backlight_enable(); - backlight_level(BACKLIGHT_LEVELS); + led_matrix_enable_noeeprom(); + led_matrix_set_val_noeeprom(UINT8_MAX); } bool process_record_user(uint16_t keycode, keyrecord_t *record) { diff --git a/keyboards/ergodox_infinity/keymaps/dudeofawesome/simple_visualizer.h b/keyboards/ergodox_infinity/keymaps/dudeofawesome/simple_visualizer.h deleted file mode 100644 index 9213e99f4289..000000000000 --- a/keyboards/ergodox_infinity/keymaps/dudeofawesome/simple_visualizer.h +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * 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 . - */ - -#ifndef KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ -#define KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ - -// Currently we are assuming that both the backlight and LCD are enabled -// But it's entirely possible to write a custom visualizer that use only -// one of them -#ifndef LCD_BACKLIGHT_ENABLE -#error This visualizer needs that LCD backlight is enabled -#endif - -#ifndef LCD_ENABLE -#error This visualizer needs that LCD is enabled -#endif - -#include "visualizer.h" -#include "visualizer_keyframes.h" -#include "lcd_keyframes.h" -#include "lcd_backlight_keyframes.h" -#include "system/serial_link.h" -#include "led.h" -#include "default_animations.h" - -static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); -static const uint32_t initial_color = LCD_COLOR(0, 0, 0); - -static bool initial_update = true; - -// Feel free to modify the animations below, or even add new ones if needed - -static keyframe_animation_t lcd_layer_display = { - .num_frames = 1, - .loop = false, - .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {lcd_keyframe_display_layer_and_led_states} -}; - -// The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, - .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {gfxMillisecondsToTicks(1), gfxMillisecondsToTicks(5)}, - .frame_functions = {keyframe_no_operation, lcd_backlight_keyframe_animate_color}, -}; - -void initialize_user_visualizer(visualizer_state_t* state) { - // The brightness will be dynamically adjustable in the future - // But for now, change it here. - lcd_backlight_brightness(130); - state->current_lcd_color = initial_color; - state->target_lcd_color = logo_background_color; - initial_update = true; - start_keyframe_animation(&default_startup_animation); -} - - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state); - -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { - // Add more tests, change the colors and layer texts here - // Usually you want to check the high bits (higher layers first) - // because that's the order layers are processed for keypresses - // You can for check for example: - // state->status.layer - // state->status.default_layer - // state->status.leds (see led.h for available statuses) - - uint32_t prev_color = state->target_lcd_color; - const char* prev_layer_text = state->layer_text; - - get_visualizer_layer_and_color(state); - - if (initial_update || prev_color != state->target_lcd_color) { - start_keyframe_animation(&color_animation); - } - - if (initial_update || prev_layer_text != state->layer_text) { - start_keyframe_animation(&lcd_layer_display); - } - // You can also stop existing animations, and start your custom ones here - // remember that you should normally have only one animation for the LCD - // and one for the background. But you can also combine them if you want. -} - -void user_visualizer_suspend(visualizer_state_t* state) { - state->layer_text = "Suspending..."; - uint8_t hue = LCD_HUE(state->current_lcd_color); - uint8_t sat = LCD_SAT(state->current_lcd_color); - state->target_lcd_color = LCD_COLOR(hue, sat, 0); - start_keyframe_animation(&default_suspend_animation); -} - -void user_visualizer_resume(visualizer_state_t* state) { - state->current_lcd_color = initial_color; - state->target_lcd_color = logo_background_color; - initial_update = true; - start_keyframe_animation(&default_startup_animation); -} - -#endif /* KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ */ diff --git a/keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.c b/keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.c deleted file mode 100644 index 54fc2363c76c..000000000000 --- a/keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.c +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 2017 Fred Sundvik - -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 . -*/ - -#include "./simple_visualizer.h" -#include "util.h" -#include "layers.h" - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - switch(biton32(default_layer_state)) { - case _QWERTY: - state->layer_text = "QWERTY"; - state->target_lcd_color = LCD_COLOR(0, 255, 128); - break; - case _WORKMAN: - state->layer_text = "Workman"; - state->target_lcd_color = LCD_COLOR(80, 255, 128); - break; - case _DVORAK: - state->layer_text = "Dvorak"; - state->target_lcd_color = LCD_COLOR(194, 255, 128); - break; - case _COLEMAK: - state->layer_text = "Colemak"; - state->target_lcd_color = LCD_COLOR(18, 255, 128); - break; - } - - switch(biton32(state->status.layer)) { - case _LOWER: - state->layer_text = "Lower"; - state->target_lcd_color = LCD_COLOR(141, 255, 255); - break; - case _RAISE: - state->layer_text = "Raise"; - state->target_lcd_color = LCD_COLOR(18, 255, 255); - break; - case _ADJUST: - state->layer_text = "Adjust"; - state->target_lcd_color = LCD_COLOR(194, 255, 255); - break; - case _NUM: - state->layer_text = "Numpad"; - state->target_lcd_color = LCD_COLOR(80, 255, 255); - break; - case _MOUSE: - state->layer_text = "Mouse"; - state->target_lcd_color = LCD_COLOR(300, 255, 255); - break; - case _GAME: - state->layer_text = "Game"; - state->target_lcd_color = LCD_COLOR(300, 255, 255); - break; - case _QWERTY: case _WORKMAN: case _DVORAK: case _COLEMAK: - break; - default: - state->layer_text = "NONE"; - state->target_lcd_color = LCD_COLOR(0, 255, 255); - break; - } -} diff --git a/keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.h b/keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.h deleted file mode 100644 index 740a951ec887..000000000000 --- a/keyboards/ergodox_infinity/keymaps/dudeofawesome/visualizer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * 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 . - */ - -#ifndef VISUALIZER_H_ -#define VISUALIZER_H_ - -#include "visualizer.h" -#include "led.h" - -void ergodox_led_lower_on (void); -void ergodox_led_raise_on (void); -void ergodox_led_adjust_on (void); - -void ergodox_led_lower_off (void); -void ergodox_led_raise_off (void); -void ergodox_led_adjust_off (void); - -void ergodox_led_lower_set (uint8_t n); -void ergodox_led_raise_set (uint8_t n); -void ergodox_led_adjust_set (uint8_t n); - -#endif /* VISUALIZER_H_ */ diff --git a/keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.c b/keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.c deleted file mode 100644 index 61a724c63f50..000000000000 --- a/keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.c +++ /dev/null @@ -1,384 +0,0 @@ -/* -Copyright 2017 Fred Sundvik -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 . -*/ - -#include "visualizer.h" -#include "gfx.h" -#include "math.h" -#include "default_animations.h" -#include "led_backlight_keyframes.h" - -#define NUM_ROWS LED_HEIGHT -#define NUM_COLS LED_WIDTH - -#define ONESIDESCAN 10 -#define BOTHSIDESCAN 20 -#define FULL_ON LUMA2COLOR(255) -#define THREE_QUARTER LUMA2COLOR(200) -#define HALF_ON LUMA2COLOR(150) -#define ONE_QUARTER LUMA2COLOR(50) - -#define CROSSFADE_TIME 500 -#define GRADIENT_TIME 3000 -bool led_backlight_keyframe_one_period_sweep(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_half_period_sweep_to_on(keyframe_animation_t* animation, visualizer_state_t* state); -bool led_backlight_keyframe_half_period_sweep_to_off(keyframe_animation_t* animation, visualizer_state_t* state); -keyframe_animation_t Fade_in_all_leds = { - .num_frames = 1, - .loop = false, - .frame_lengths = { - CROSSFADE_TIME, - }, - .frame_functions = { - led_backlight_keyframe_fade_in_all, - }, -}; -keyframe_animation_t decreasing_gradient = { - .num_frames = 8, - .loop = true, - .frame_lengths = { - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - 0, // normal leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - 0, // normal leds - }, - .frame_functions = { - led_backlight_keyframe_one_period_sweep, - led_backlight_keyframe_mirror_orientation, - keyframe_no_operation, - keyframe_no_operation, - keyframe_no_operation, - keyframe_no_operation, - led_backlight_keyframe_one_period_sweep, - led_backlight_keyframe_normal_orientation, - - }, -}; - - - -static uint8_t off_on_off_gradient(float t, float index, float num) { - const float two_pi = M_PI * 2.0f; - float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; - float x = t * two_pi + normalized_index-M_PI; - if((1*M_PI) < x && x < (3*M_PI)) - { - float v = 0.5 * (cosf(x) + 1.0f); - return (uint8_t)(255.0f * v); - } - else - { - return 0; - } -} -static uint8_t off_on_gradient(float t, float index, float num) { - const float two_pi = M_PI * 2.0f; - float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; - float x = t * two_pi + normalized_index-M_PI; - float v; - if((1*M_PI) < x && x < (2*M_PI)) - { - v = 0.5 * (cosf(x) + 1.0f); - } - else if(x >= (2*M_PI)) - { - v = 1; - } - else - { - v = 0; - } - return (uint8_t)(255.0f * v); -} -static uint8_t on_off_gradient(float t, float index, float num) { - const float two_pi = M_PI * 2.0f; - float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; - float x = t * two_pi + normalized_index-M_PI; - float v; - if((2*M_PI) < x && x < (3*M_PI)) - { - v = 0.5 * (cosf(x) + 1.0f); - - } - else if(x >= (3*M_PI)) - { - v = 0; - } - else - { - v = 1; - } - return (uint8_t)(255.0f * v); -} - -bool led_backlight_keyframe_one_period_sweep(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)state; - float frame_length = animation->frame_lengths[animation->current_frame]; - float current_pos = frame_length - animation->time_left_in_frame; - float t = current_pos / frame_length; - for (int i=0; i< NUM_COLS; i++) { - uint8_t color = off_on_off_gradient(t*2, i, NUM_COLS); - gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); - } - return true; -} - -bool led_backlight_keyframe_half_period_sweep_to_on(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)state; - float frame_length = animation->frame_lengths[animation->current_frame]; - float current_pos = frame_length - animation->time_left_in_frame; - float t = current_pos / frame_length; - for (int i=0; i< NUM_COLS; i++) { - uint8_t color = off_on_gradient(t*2, i, NUM_COLS); - gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); - } - return true; -} -bool led_backlight_keyframe_half_period_sweep_to_off(keyframe_animation_t* animation, visualizer_state_t* state) { - (void)state; - float frame_length = animation->frame_lengths[animation->current_frame]; - float current_pos = frame_length - animation->time_left_in_frame; - float t = current_pos / frame_length; - for (int i=0; i< NUM_COLS; i++) { - uint8_t color = on_off_gradient(t*2, i, NUM_COLS); - gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); - } - return true; -} - - -/* - +---+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+ -| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | phase | -+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+ -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | -| 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | -| 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | -| 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | -| 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | -| 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | -| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | -| 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | -| 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 9 | -| 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 10 | -| 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 11 | -| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 12 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 13 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 14 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 15 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 16 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 17 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 18 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 19 | -| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 20 | -+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+ -*/ - -#ifdef MASTER_IS_ON_RIGHT /*right side*/ -keyframe_animation_t sweep_on_sweep_off_left_and_right = { - .num_frames = 12, - .loop = true, - .frame_lengths = { - 0, - 1, - gfxMillisecondsToTicks(GRADIENT_TIME), // left on - gfxMillisecondsToTicks(GRADIENT_TIME), // right on - gfxMillisecondsToTicks(GRADIENT_TIME), // left off - gfxMillisecondsToTicks(GRADIENT_TIME), // right off - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // right on - gfxMillisecondsToTicks(GRADIENT_TIME), // left on - gfxMillisecondsToTicks(GRADIENT_TIME), // right off - gfxMillisecondsToTicks(GRADIENT_TIME), // left off - 0, // normal leds - }, - .frame_functions = { - led_backlight_keyframe_mirror_orientation, - led_backlight_keyframe_fade_out_all, - keyframe_no_operation, - led_backlight_keyframe_half_period_sweep_to_on, - keyframe_no_operation, - led_backlight_keyframe_half_period_sweep_to_off, - led_backlight_keyframe_normal_orientation, - led_backlight_keyframe_half_period_sweep_to_on, - keyframe_no_operation, - led_backlight_keyframe_half_period_sweep_to_off, - keyframe_no_operation, - led_backlight_keyframe_mirror_orientation, - - }, -}; -keyframe_animation_t both_sides_fade_across = { - .num_frames = 10, - .loop = true, - .frame_lengths = { - 0, - 1, - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - 0, // normal leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - 0, // normal leds - }, - .frame_functions = { - led_backlight_keyframe_mirror_orientation, - led_backlight_keyframe_fade_out_all, - keyframe_no_operation, - keyframe_no_operation, - led_backlight_keyframe_one_period_sweep, - led_backlight_keyframe_normal_orientation, - led_backlight_keyframe_one_period_sweep, - led_backlight_keyframe_mirror_orientation, - keyframe_no_operation, - keyframe_no_operation, - }, -}; - -#else /*left side*/ -keyframe_animation_t sweep_on_sweep_off_left_and_right = { - .num_frames = 10, - .loop = true, - .frame_lengths = { - gfxMillisecondsToTicks(GRADIENT_TIME), // left on - gfxMillisecondsToTicks(GRADIENT_TIME), // right on - gfxMillisecondsToTicks(GRADIENT_TIME), // left off - gfxMillisecondsToTicks(GRADIENT_TIME), // right off - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // right on - gfxMillisecondsToTicks(GRADIENT_TIME), // left on - gfxMillisecondsToTicks(GRADIENT_TIME), // right off - gfxMillisecondsToTicks(GRADIENT_TIME), // left off - 0, // normal leds - }, - .frame_functions = { - led_backlight_keyframe_half_period_sweep_to_on, - keyframe_no_operation, - led_backlight_keyframe_half_period_sweep_to_off, - keyframe_no_operation, - led_backlight_keyframe_mirror_orientation, - keyframe_no_operation, - led_backlight_keyframe_half_period_sweep_to_on, - keyframe_no_operation, - led_backlight_keyframe_half_period_sweep_to_off, - led_backlight_keyframe_normal_orientation, - - }, -}; -keyframe_animation_t both_sides_fade_across = { - .num_frames = 8, - .loop = true, - .frame_lengths = { - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - 0, // normal leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) - 0, // mirror leds - gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) - 0, // normal leds - }, - .frame_functions = { - led_backlight_keyframe_one_period_sweep, - led_backlight_keyframe_mirror_orientation, - keyframe_no_operation, - keyframe_no_operation, - keyframe_no_operation, - keyframe_no_operation, - led_backlight_keyframe_one_period_sweep, - led_backlight_keyframe_normal_orientation, - - }, -}; - - -#endif - -#define RED 0 -#define ORANGE 21 -#define YELLOW 42 -#define SPRING_GREEN 64 -#define GREEN 85 -#define TURQUOISE 107 -#define CYAN 127 -#define OCEAN 149 -#define BLUE 170 -#define VIOLET 192 -#define MAGENTA 212 -#define RASPBERRY 234 - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - uint8_t saturation = 255; - /* if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { - saturation = 255; - } */ - - if (state->status.layer & 0x400) { - state->target_lcd_color = LCD_COLOR(OCEAN, saturation, 0xFF); - state->layer_text = "STENOGRAPHY"; - } - else if (state->status.layer & 0x200) { - state->target_lcd_color = LCD_COLOR(GREEN, saturation, 0xFF); - state->layer_text = "FUNCTION"; - } - else if (state->status.layer & 0x100) { - state->target_lcd_color = LCD_COLOR(MAGENTA, saturation, 0xFF); - state->layer_text = "Shortcuts Layer"; - stop_keyframe_animation(&sweep_on_sweep_off_left_and_right); - start_keyframe_animation(&led_test_animation); - } - else if (state->status.layer & 0x80) { - state->target_lcd_color = LCD_COLOR(VIOLET, saturation, 0xFF); - state->layer_text = "Plover"; - } - else if (state->status.layer & 0x40) { - state->target_lcd_color = LCD_COLOR(RASPBERRY, saturation, 0xFF); - state->layer_text = "Mirrored Symbols"; - } - else if (state->status.layer & 0x20) { - state->target_lcd_color = LCD_COLOR(RED, saturation, 0xFF); - state->layer_text = "Symbols"; - } - else if (state->status.layer & 0x8) { - state->target_lcd_color = LCD_COLOR(OCEAN, saturation, 0xFF); - state->layer_text = "Mirrored Dvorak"; - } - else if (state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(BLUE, saturation, 0xFF); - state->layer_text = "Dvorak"; - stop_keyframe_animation(&led_test_animation); - start_keyframe_animation(&sweep_on_sweep_off_left_and_right); - } - else if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(ORANGE, saturation, 0xFF); - state->layer_text = "Mirrored Qwerty"; - } - else { - state->target_lcd_color = LCD_COLOR(YELLOW, saturation, 0xFF); - state->layer_text = "Qwerty"; - stop_keyframe_animation(&led_test_animation); - start_keyframe_animation(&Fade_in_all_leds); - } -} diff --git a/keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.h b/keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.h deleted file mode 100644 index c97a7a22a583..000000000000 --- a/keyboards/ergodox_infinity/keymaps/halfkeyboard/visualizer.h +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * 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 . - */ - -#ifndef VISUALIZER_H_ -#define VISUALIZER_H_ - -// Currently we are assuming that both the backlight and LCD are enabled -// But it's entirely possible to write a custom visualizer that use only -// one of them -#ifndef LCD_BACKLIGHT_ENABLE -#error This visualizer needs that LCD backlight is enabled -#endif - -#ifndef LCD_ENABLE -#error This visualizer needs that LCD is enabled -#endif - -#include "visualizer.h" -#include "visualizer_keyframes.h" -#include "lcd_keyframes.h" -#include "lcd_backlight_keyframes.h" -#include "system/serial_link.h" -#include "led.h" -#include "default_animations.h" - -static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); -static const uint32_t initial_color = LCD_COLOR(0, 0, 0); - -static bool initial_update = true; - -// Feel free to modify the animations below, or even add new ones if needed -extern keyframe_animation_t KITT_Scanner_animation; - -static keyframe_animation_t lcd_layer_display = { - .num_frames = 1, - .loop = false, - .frame_lengths = {gfxMillisecondsToTicks(0)}, - .frame_functions = {lcd_keyframe_display_layer_and_led_states} -}; - -// The color animation animates the LCD color when you change layers -static keyframe_animation_t color_animation = { - .num_frames = 2, - .loop = false, - // Note that there's a 200 ms no-operation frame, - // this prevents the color from changing when activating the layer - // momentarily - .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, - .frame_functions = {keyframe_no_operation, lcd_backlight_keyframe_animate_color}, -}; - -void initialize_user_visualizer(visualizer_state_t* state) { - // The brightness will be dynamically adjustable in the future - // But for now, change it here. - lcd_backlight_brightness(130); - state->current_lcd_color = initial_color; - state->target_lcd_color = logo_background_color; - initial_update = true; - start_keyframe_animation(&default_startup_animation); -} - - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state); - -void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { - // Add more tests, change the colors and layer texts here - // Usually you want to check the high bits (higher layers first) - // because that's the order layers are processed for keypresses - // You can for check for example: - // state->status.layer - // state->status.default_layer - // state->status.leds (see led.h for available statuses) - - uint32_t prev_color = state->target_lcd_color; - const char* prev_layer_text = state->layer_text; - - get_visualizer_layer_and_color(state); - - if (initial_update || prev_color != state->target_lcd_color) { - start_keyframe_animation(&color_animation); - } - - if (initial_update || prev_layer_text != state->layer_text) { - start_keyframe_animation(&lcd_layer_display); - } - // You can also stop existing animations, and start your custom ones here - // remember that you should normally have only one animation for the LCD - // and one for the background. But you can also combine them if you want. - -} - -void user_visualizer_suspend(visualizer_state_t* state) { - state->layer_text = "Suspending..."; - uint8_t hue = LCD_HUE(state->current_lcd_color); - uint8_t sat = LCD_SAT(state->current_lcd_color); - state->target_lcd_color = LCD_COLOR(hue, sat, 0); - start_keyframe_animation(&default_suspend_animation); -} - -void user_visualizer_resume(visualizer_state_t* state) { - state->current_lcd_color = initial_color; - state->target_lcd_color = logo_background_color; - initial_update = true; - start_keyframe_animation(&default_startup_animation); -} - -#endif /* VISUALIZER_H_ */ diff --git a/layouts/community/ergodox/333fred/keymap.c b/layouts/community/ergodox/333fred/keymap.c index b9aefd929309..5dee9a1e3f68 100644 --- a/layouts/community/ergodox/333fred/keymap.c +++ b/layouts/community/ergodox/333fred/keymap.c @@ -272,3 +272,43 @@ void matrix_scan_user(void) { ergodox_led_all_on(); } +#ifdef ST7565_ENABLE + +void st7565_task_user(void) { + // The colors will need to be ported over to the quantum painter API when + // https://github.com/qmk/qmk_firmware/pull/10174 is merged. + + st7565_clear(); + switch (get_highest_layer(layer_state)) { + case BASE: + //state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); + st7565_write_P(PSTR("Default\n"), false); + break; + case CODEFLOW: + //state->target_lcd_color = LCD_COLOR(216, 90, 0xFF); + st7565_write_P(PSTR("Code\n"), false); + break; + case SYMB: + //state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF); + st7565_write_P(PSTR("Symbol\n"), false); + break; + case MDIA: + //state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF); + st7565_write_P(PSTR("Media\n"), false); + break; + case VIM: + //state->target_lcd_color = LCD_COLOR(140, 100, 60); + st7565_write_P(PSTR("Movement\n"), false); + break; + case GAME: + //state->target_lcd_color = LCD_COLOR(0, 255, 60); + st7565_write_P(PSTR("Game\n"), false); + break; + case GAME_ARROW: + //state->target_lcd_color = LCD_COLOR(0, 255, 60); + st7565_write_P(PSTR("Game Arrow\n"), false); + break; + } +} + +#endif diff --git a/layouts/community/ergodox/333fred/rules.mk b/layouts/community/ergodox/333fred/rules.mk index f6c71feb4627..9a3e2b97e594 100644 --- a/layouts/community/ergodox/333fred/rules.mk +++ b/layouts/community/ergodox/333fred/rules.mk @@ -1,5 +1,2 @@ -LCD_BACKLIGHT_ENABLE = yes -LCD_ENABLE = yes -BACKLIGHT_ENABLE = yes KEY_LOCK_ENABLE = yes CONSOLE_ENABLE = no diff --git a/layouts/community/ergodox/333fred/visualizer.c b/layouts/community/ergodox/333fred/visualizer.c deleted file mode 100644 index d13b3cd79477..000000000000 --- a/layouts/community/ergodox/333fred/visualizer.c +++ /dev/null @@ -1,39 +0,0 @@ -/* -Note: this is a modified copy of ../default/visualizer.c, originally licensed GPL. -*/ - -#include "simple_visualizer.h" - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - uint8_t saturation = 60; - if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { - saturation = 255; - } - if (state->status.layer & 0x80) { - state->target_lcd_color = LCD_COLOR(0, 255, 60); - state->layer_text = "Game Arrow"; - } else if (state->status.layer & 0x40) { - state->target_lcd_color = LCD_COLOR(0, 255, 60); - state->layer_text = "Game"; - } else if (state->status.layer & 0x20) { - state->target_lcd_color = LCD_COLOR(140, 100, 60); - state->layer_text = "Movement"; - } else if (state->status.layer & 0x10) { - state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF); - state->layer_text = "Media"; - } else if (state->status.layer & 0x8) { - state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF); - state->layer_text = "Symbol"; - } else if (state->status.layer & 0x2 || state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(216, 90, 0xFF); - state->layer_text = "Code"; - } else { - state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); - state->layer_text = "Default"; - } -} diff --git a/layouts/community/ergodox/adnw_p_u_q/visualizer.c b/layouts/community/ergodox/adnw_p_u_q/visualizer.c deleted file mode 100644 index 9a4d485387d4..000000000000 --- a/layouts/community/ergodox/adnw_p_u_q/visualizer.c +++ /dev/null @@ -1,34 +0,0 @@ -/* -Note: this is a modified copy of ../default/visualizer.c, originally licensed GPL. -*/ - -#include "simple_visualizer.h" - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - - if (state->status.layer & 0x20) { - state->target_lcd_color = LCD_COLOR(127, 0xFF, 0xFF); - state->layer_text = "Mouse"; - } else if (state->status.layer & 0x10) { - state->target_lcd_color = LCD_COLOR(85, 0xFF, 0xFF); - state->layer_text = "Symbol"; - } else if (state->status.layer & 0x8) { - state->target_lcd_color = LCD_COLOR(64, 0xFF, 0xFF); - state->layer_text = "Brackets"; - } else if (state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(42, 0xFF, 0xFF); - state->layer_text = "Diak"; - } else if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(21, 0xFF, 0xFF); - state->layer_text = "Terminal"; - } else { - state->target_lcd_color = LCD_COLOR(192, 0xFF, 0xFF); - state->layer_text = "Vim"; - } -} - diff --git a/layouts/community/ergodox/belak/keymap.c b/layouts/community/ergodox/belak/keymap.c index bca0dec913fd..de0fe1b1aef3 100644 --- a/layouts/community/ergodox/belak/keymap.c +++ b/layouts/community/ergodox/belak/keymap.c @@ -33,11 +33,6 @@ enum belak_keycodes { E_TSET, }; -inline void tap(uint16_t keycode) { - register_code(keycode); - unregister_code(keycode); -}; - // TODO: Add LED support to the tap dance by using the advanced macro #define LTOGGLE TD(TD_LAYER_TOGGLE) @@ -273,17 +268,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { case E_SHRUG: // ¯\_(ツ)_/¯ if (record->event.pressed) { process_unicode((0x00AF|QK_UNICODE), record); // Hand - tap(KC_BSLS); // Arm + tap_code16(KC_BSLS); // Arm register_code(KC_RSFT); - tap(KC_UNDS); // Arm - tap(KC_LPRN); // Head + tap_code16(KC_UNDS); // Arm + tap_code16(KC_LPRN); // Head unregister_code(KC_RSFT); process_unicode((0x30C4|QK_UNICODE), record); // Face register_code(KC_RSFT); - tap(KC_RPRN); // Head - tap(KC_UNDS); // Arm + tap_code16(KC_RPRN); // Head + tap_code16(KC_UNDS); // Arm unregister_code(KC_RSFT); - tap(KC_SLSH); // Arm + tap_code16(KC_SLSH); // Arm process_unicode((0x00AF|QK_UNICODE), record); // Hand } return false; @@ -291,19 +286,19 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { case E_TFLIP: // (╯°□°)╯ ︵ ┻━┻ if (record->event.pressed) { register_code(KC_RSFT); - tap(KC_9); + tap_code16(KC_9); unregister_code(KC_RSFT); process_unicode((0x256F|QK_UNICODE), record); // Arm process_unicode((0x00B0|QK_UNICODE), record); // Eye process_unicode((0x25A1|QK_UNICODE), record); // Mouth process_unicode((0x00B0|QK_UNICODE), record); // Eye register_code(KC_RSFT); - tap(KC_0); + tap_code16(KC_0); unregister_code(KC_RSFT); process_unicode((0x256F|QK_UNICODE), record); // Arm - tap(KC_SPC); + tap_code16(KC_SPC); process_unicode((0x0361|QK_UNICODE), record); // Flippy - tap(KC_SPC); + tap_code16(KC_SPC); process_unicode((0x253B|QK_UNICODE), record); // Table process_unicode((0x2501|QK_UNICODE), record); // Table process_unicode((0x253B|QK_UNICODE), record); // Table @@ -316,18 +311,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { process_unicode((0x2500|QK_UNICODE), record); // Table process_unicode((0x2500|QK_UNICODE), record); // Table process_unicode((0x252C|QK_UNICODE), record); // Table - tap(KC_SPC); + tap_code16(KC_SPC); process_unicode((0x30CE|QK_UNICODE), record); // Arm register_code(KC_RSFT); - tap(KC_9); + tap_code16(KC_9); unregister_code(KC_RSFT); - tap(KC_SPC); + tap_code16(KC_SPC); process_unicode((0x309C|QK_UNICODE), record); // Eye - tap(KC_MINS); + tap_code16(KC_MINS); process_unicode((0x309C|QK_UNICODE), record); // Eye process_unicode((0x30CE|QK_UNICODE), record); // Arm register_code(KC_RSFT); - tap(KC_0); + tap_code16(KC_0); unregister_code(KC_RSFT); } return false; diff --git a/layouts/community/ergodox/belak/visualizer.c b/layouts/community/ergodox/belak/visualizer.c deleted file mode 100644 index b92890a668a3..000000000000 --- a/layouts/community/ergodox/belak/visualizer.c +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2017 Fred Sundvik - -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 . -*/ - -// Currently we are assuming that both the backlight and LCD are enabled -// But it's entirely possible to write a custom visualizer that use only -// one of them -#ifndef LCD_BACKLIGHT_ENABLE -#error This visualizer needs that LCD backlight is enabled -#endif - -#ifndef LCD_ENABLE -#error This visualizer needs that LCD is enabled -#endif - -#include "simple_visualizer.h" - -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - uint8_t saturation = 60; - if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { - saturation = 255; - } - - if (state->status.layer & 0x4) { - state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF); - state->layer_text = "Media"; - } - else if (state->status.layer & 0x2) { - state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF); - state->layer_text = "Symbols"; - } - else { - state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); - state->layer_text = "Base"; - } -} diff --git a/layouts/community/ergodox/choromanski/visualizer.c b/layouts/community/ergodox/choromanski/visualizer.c deleted file mode 100644 index e207c66822e0..000000000000 --- a/layouts/community/ergodox/choromanski/visualizer.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2017 Fred Sundvik - -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 . -*/ - -#include "simple_visualizer.h" - -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - - if (state->status.layer & 0x20) { - //GREEN - state->target_lcd_color = LCD_COLOR(85, 255, 128); - state->layer_text = "Gaming"; - } - else if (state->status.layer & 0x10) { - //ORANGE - state->target_lcd_color = LCD_COLOR(28, 255, 230); - state->layer_text = "Numpad & Mouse"; - } - else if (state->status.layer & 0x8) { - //YELLOW - state->target_lcd_color = LCD_COLOR(38, 255, 230); - state->layer_text = "Symbols"; - } - else if (state->status.layer & 0x4) { - //RED - state->target_lcd_color = LCD_COLOR(0, 255, 95); - if (state->status.layer & 0x2){ - state->layer_text = "Qwerty - Fn"; - }else{ - state->layer_text = "Colemak - Fn"; - } - } - else if (state->status.layer & 0x2) { - //BLUE - state->target_lcd_color = LCD_COLOR(149, 255, 192); - state->layer_text = "Qwerty"; - } - else { - //PURPLE - state->target_lcd_color = LCD_COLOR(200, 255, 192); - state->layer_text = "Colemak"; - } -} - diff --git a/layouts/community/ergodox/drashna/visualizer.c_old b/layouts/community/ergodox/drashna/visualizer.c_old deleted file mode 100644 index 6b1c3ff498b6..000000000000 --- a/layouts/community/ergodox/drashna/visualizer.c_old +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright 2017 Fred Sundvik - -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 . -*/ - -#include "./simple_visualizer.h" -#include "util.h" -#include "drashna.h" -#include "rgblight_list.h" - -#define LCD_COLOR_wrapper(...) LCD_COLOR(__VA_ARGS__) -// This function should be implemented by the keymap visualizer -// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing -// that the simple_visualizer assumes that you are updating -// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is -// stopped. This can be done by either double buffering it or by using constant strings -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - - switch(get_highest_layer(state->status.layer|default_layer_state)) { - case _LOWER: - state->layer_text = "Lower"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_GREEN); - break; - case _RAISE: - state->layer_text = "Raise"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_YELLOW); - break; - case _ADJUST: - state->layer_text = "Adjust"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_RED); - break; - case _MACROS: - state->layer_text = "Macros"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_ORANGE); - break; - case _MEDIA: - state->layer_text = "Media"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_CHARTREUSE); - break; - case _GAMEPAD: - state->layer_text = "Game"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_ORANGE); - break; - case _QWERTY: - state->layer_text = "QWERTY"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_CYAN); - break; - case _WORKMAN: - state->layer_text = "Workman"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_GOLDENROD); - break; - case _DVORAK: - state->layer_text = "Dvorak"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_SPRINGGREEN); - break; - case _COLEMAK: - state->layer_text = "Colemak"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_MAGENTA); - break; break; - default: - state->layer_text = "NONE"; - state->target_lcd_color = LCD_COLOR_wrapper(HSV_RED); - break; - } -} diff --git a/layouts/community/ergodox/osx_neo2/visualizer.c b/layouts/community/ergodox/osx_neo2/visualizer.c deleted file mode 100644 index 653201bb8aae..000000000000 --- a/layouts/community/ergodox/osx_neo2/visualizer.c +++ /dev/null @@ -1,47 +0,0 @@ -#include "layers.h" -#include "simple_visualizer.h" -#include "util.h" - -static void get_visualizer_layer_and_color(visualizer_state_t *state) { - uint8_t layer = biton32(state->status.layer); - - // Go from highest to lowest layer to get the right text/color combination. - switch (layer) { - // #AEB2F4 / hsv(65.71%, 28.69%, 95.69%) - case FKEYS: - // #F4AEDC / hsv(89.05%, 28.69%, 95.69%) - state->layer_text = "FUNCTION KEYS"; - state->target_lcd_color = LCD_COLOR(228, 73, 245); - break; - case US_1: - // #F4B993 / hsv(6.53%, 39.75%, 95.69%) - state->layer_text = "QWERTY"; - state->target_lcd_color = LCD_COLOR(17, 102, 245); - break; - case NEO_6: - // #F4E393 / hsv(13.75%, 39.75%, 95.69%) - state->layer_text = "NEO: 6"; - state->target_lcd_color = LCD_COLOR(35, 102, 245); - break; - case NEO_5: - // #C6F493 / hsv(24.57%, 39.75%, 95.69%) - state->layer_text = "NEO: 5"; - state->target_lcd_color = LCD_COLOR(63, 102, 245); - break; - case NEO_4: - // #8EEBC9 / hsv(43.91%, 39.57%, 92.16%) - state->layer_text = "NEO: 4"; - state->target_lcd_color = LCD_COLOR(112, 101, 189); - break; - case NEO_3: - // #93D2F4 / hsv(55.84%, 39.75%, 95.69%) - state->layer_text = "NEO: 3"; - state->target_lcd_color = LCD_COLOR(143, 102, 245); - break; - default: - // #EEEEEE / hsv(0%, 0%, 93%) - state->layer_text = "NEO: 1"; - state->target_lcd_color = LCD_COLOR(0, 0, 255); - break; - } -} diff --git a/show_options.mk b/show_options.mk index e0d7c9b072b6..c1da90bcbc41 100644 --- a/show_options.mk +++ b/show_options.mk @@ -28,7 +28,6 @@ HARDWARE_OPTION_NAMES = \ AUDIO_ENABLE \ HD44780_ENABLE \ ENCODER_ENABLE \ - LCD_ENABLE \ LED_TABLES \ POINTING_DEVICE_ENABLE \ DIP_SWITCH_ENABLE diff --git a/users/talljoe/visualizer.c b/users/talljoe/visualizer.c deleted file mode 100644 index c17b56706bfc..000000000000 --- a/users/talljoe/visualizer.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2020 Joseph Wasson - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "talljoe.h" - -static void get_visualizer_layer_and_color(visualizer_state_t* state) { - state->status_text = layer_names[biton32(state->status.layer)]; -} From b36e0c66581b5ec0e3aff5212857e9694115e66c Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 21 Oct 2021 14:39:13 +0100 Subject: [PATCH 0009/1136] Move USE_CCACHE logic to common location (#14899) --- tmk_core/arm_atsam.mk | 2 +- tmk_core/avr.mk | 2 +- tmk_core/chibios.mk | 6 ------ tmk_core/native.mk | 2 +- tmk_core/rules.mk | 7 +++++-- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tmk_core/arm_atsam.mk b/tmk_core/arm_atsam.mk index b29de9132b8d..b49bf764d7eb 100644 --- a/tmk_core/arm_atsam.mk +++ b/tmk_core/arm_atsam.mk @@ -2,7 +2,7 @@ ############################################################################## # Compiler settings # -CC = arm-none-eabi-gcc +CC = $(CC_PREFIX) arm-none-eabi-gcc OBJCOPY = arm-none-eabi-objcopy OBJDUMP = arm-none-eabi-objdump SIZE = arm-none-eabi-size diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk index 940e95397bff..c52262273ee1 100644 --- a/tmk_core/avr.mk +++ b/tmk_core/avr.mk @@ -2,7 +2,7 @@ ############################################################################## # Compiler settings # -CC = avr-gcc +CC = $(CC_PREFIX) avr-gcc OBJCOPY = avr-objcopy OBJDUMP = avr-objdump SIZE = avr-size diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk index c520d6025b76..957a25922984 100644 --- a/tmk_core/chibios.mk +++ b/tmk_core/chibios.mk @@ -398,12 +398,6 @@ OPT_DEFS += -DPROTOCOL_CHIBIOS # Workaround to stop ChibiOS from complaining about new GCC -- it's been fixed for 7/8/9 already OPT_DEFS += -DPORT_IGNORE_GCC_VERSION_CHECK=1 -# Speed up recompilations by opt-in usage of ccache -USE_CCACHE ?= no -ifneq ($(USE_CCACHE),no) - CC_PREFIX ?= ccache -endif - # Construct GCC toolchain CC = $(CC_PREFIX) $(TOOLCHAIN)gcc OBJCOPY = $(TOOLCHAIN)objcopy diff --git a/tmk_core/native.mk b/tmk_core/native.mk index f609fd0e6fa3..eb2424ec5c8e 100644 --- a/tmk_core/native.mk +++ b/tmk_core/native.mk @@ -1,7 +1,7 @@ SYSTEM_TYPE := $(shell gcc -dumpmachine) GCC_VERSION := $(shell gcc --version 2>/dev/null) -CC = gcc +CC = $(CC_PREFIX) gcc OBJCOPY = OBJDUMP = SIZE = diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index 5a629d1eb098..4c547cfd247c 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -69,8 +69,11 @@ CSTANDARD = -std=gnu99 #CXXDEFS += -D__STDC_CONSTANT_MACROS #CXXDEFS += - - +# Speed up recompilations by opt-in usage of ccache +USE_CCACHE ?= yes +ifneq ($(USE_CCACHE),no) + CC_PREFIX ?= ccache +endif #---------------- Compiler Options C ---------------- # -g*: generate debugging information From 1b93d576f84822d0f4947179ee49f614ba345f12 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Fri, 22 Oct 2021 00:21:43 +0100 Subject: [PATCH 0010/1136] Fix ccache default (#14906) --- tmk_core/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index 4c547cfd247c..56a331e28827 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -70,7 +70,7 @@ CSTANDARD = -std=gnu99 #CXXDEFS += # Speed up recompilations by opt-in usage of ccache -USE_CCACHE ?= yes +USE_CCACHE ?= no ifneq ($(USE_CCACHE),no) CC_PREFIX ?= ccache endif From 1b1f3ec68ee1e7abe436a46bcfedf30f21330aef Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Fri, 22 Oct 2021 00:49:38 +0100 Subject: [PATCH 0011/1136] Split out arm_atsam shift register logic (#14848) --- keyboards/massdrop/alt/config.h | 18 ++- keyboards/massdrop/ctrl/config.h | 18 ++- tmk_core/common/arm_atsam/gpio.h | 8 +- tmk_core/protocol/arm_atsam.mk | 3 +- .../protocol/arm_atsam/arm_atsam_protocol.h | 2 +- tmk_core/protocol/arm_atsam/shift_register.c | 118 ++++++++++++++++++ .../arm_atsam/{spi.h => shift_register.h} | 25 +--- tmk_core/protocol/arm_atsam/spi.c | 92 -------------- tmk_core/protocol/arm_atsam/spi_master.c | 109 ++++++++++++++++ tmk_core/protocol/arm_atsam/spi_master.h | 48 +++++++ 10 files changed, 301 insertions(+), 140 deletions(-) create mode 100644 tmk_core/protocol/arm_atsam/shift_register.c rename tmk_core/protocol/arm_atsam/{spi.h => shift_register.h} (77%) delete mode 100644 tmk_core/protocol/arm_atsam/spi.c create mode 100644 tmk_core/protocol/arm_atsam/spi_master.c create mode 100644 tmk_core/protocol/arm_atsam/spi_master.h diff --git a/keyboards/massdrop/alt/config.h b/keyboards/massdrop/alt/config.h index d28094c49239..085e1aebbaea 100644 --- a/keyboards/massdrop/alt/config.h +++ b/keyboards/massdrop/alt/config.h @@ -50,22 +50,18 @@ along with this program. If not, see . /* This Shift Register expands available hardware output lines to control additional peripherals */ /* It uses four lines from the MCU to provide 16 output lines */ /* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */ -#define SR_EXP_RCLK_PORT PB -#define SR_EXP_RCLK_PIN 14 +#define SR_EXP_RCLK_PIN B14 /* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */ -#define SR_EXP_OE_N_PORT PB -#define SR_EXP_OE_N_PIN 15 +#define SR_EXP_OE_PIN B15 /* SERCOM port to use for Shift Register SPI */ /* DATAOUT and SCLK must be configured to use hardware pins of this port */ -#define SR_EXP_SERCOM SERCOM2 +#define SPI_SERCOM SERCOM2 /* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ -#define SR_EXP_DATAOUT_PORT PA -#define SR_EXP_DATAOUT_PIN 12 -#define SR_EXP_DATAOUT_MUX 2 +#define SPI_DATAOUT_PIN A12 +#define SPI_DATAOUT_MUX 2 /* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */ -#define SR_EXP_SCLK_PORT PA -#define SR_EXP_SCLK_PIN 13 -#define SR_EXP_SCLK_MUX 2 +#define SPI_SCLK_PIN A13 +#define SPI_SCLK_MUX 2 /* Debug LED (Small LED Located near MCU) */ #define DEBUG_LED_ENABLE 1 diff --git a/keyboards/massdrop/ctrl/config.h b/keyboards/massdrop/ctrl/config.h index 3dbd9b887700..aefb9004486b 100644 --- a/keyboards/massdrop/ctrl/config.h +++ b/keyboards/massdrop/ctrl/config.h @@ -49,22 +49,18 @@ along with this program. If not, see . /* This Shift Register expands available hardware output lines to control additional peripherals */ /* It uses four lines from the MCU to provide 16 output lines */ /* Shift Register Clock configuration (MCU to ShiftRegister.RCLK) */ -#define SR_EXP_RCLK_PORT PB -#define SR_EXP_RCLK_PIN 14 +#define SR_EXP_RCLK_PIN B14 /* Shift Register Output Enable configuration (MCU to ShiftRegister.OE_N) */ -#define SR_EXP_OE_N_PORT PB -#define SR_EXP_OE_N_PIN 15 +#define SR_EXP_OE_PIN B15 /* SERCOM port to use for Shift Register SPI */ /* DATAOUT and SCLK must be configured to use hardware pins of this port */ -#define SR_EXP_SERCOM SERCOM2 +#define SPI_SERCOM SERCOM2 /* Shift Register SPI Data Out configuration (MCU.SERCOMx.PAD[0] to ShiftRegister.SER) */ -#define SR_EXP_DATAOUT_PORT PA -#define SR_EXP_DATAOUT_PIN 12 -#define SR_EXP_DATAOUT_MUX 2 +#define SPI_DATAOUT_PIN A12 +#define SPI_DATAOUT_MUX 2 /* Shift Register SPI Serial Clock configuration (MCU.SERCOMx.PAD[1] to ShiftRegister.SRCLK) */ -#define SR_EXP_SCLK_PORT PA -#define SR_EXP_SCLK_PIN 13 -#define SR_EXP_SCLK_MUX 2 +#define SPI_SCLK_PIN A13 +#define SPI_SCLK_MUX 2 /* Debug LED (Small LED Located near MCU) */ #define DEBUG_LED_ENABLE 1 diff --git a/tmk_core/common/arm_atsam/gpio.h b/tmk_core/common/arm_atsam/gpio.h index c2d5a30889b0..915ed0ef4f74 100644 --- a/tmk_core/common/arm_atsam/gpio.h +++ b/tmk_core/common/arm_atsam/gpio.h @@ -64,7 +64,13 @@ typedef uint8_t pin_t; PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ } while (0) -#define writePin(pin, level) ((level) ? (writePinHigh(pin)) : (writePinLow(pin))) +#define writePin(pin, level) \ + do { \ + if (level) \ + PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \ + else \ + PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ + } while (0) #define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0) diff --git a/tmk_core/protocol/arm_atsam.mk b/tmk_core/protocol/arm_atsam.mk index 5bb45d658e51..e3b550596625 100644 --- a/tmk_core/protocol/arm_atsam.mk +++ b/tmk_core/protocol/arm_atsam.mk @@ -9,7 +9,8 @@ ifeq ($(RGB_MATRIX_DRIVER),custom) SRC += $(ARM_ATSAM_DIR)/md_rgb_matrix.c endif SRC += $(ARM_ATSAM_DIR)/main_arm_atsam.c -SRC += $(ARM_ATSAM_DIR)/spi.c +SRC += $(ARM_ATSAM_DIR)/shift_register.c +SRC += $(ARM_ATSAM_DIR)/spi_master.c SRC += $(ARM_ATSAM_DIR)/startup.c SRC += $(ARM_ATSAM_DIR)/usb/main_usb.c diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h index d126c66e7d11..c3eab39fb184 100644 --- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h +++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h @@ -27,7 +27,7 @@ along with this program. If not, see . #include "wait.h" #include "adc.h" #include "i2c_master.h" -#include "spi.h" +#include "shift_register.h" #include "./usb/usb2422.h" diff --git a/tmk_core/protocol/arm_atsam/shift_register.c b/tmk_core/protocol/arm_atsam/shift_register.c new file mode 100644 index 000000000000..8d63af1b59de --- /dev/null +++ b/tmk_core/protocol/arm_atsam/shift_register.c @@ -0,0 +1,118 @@ +/* +Copyright 2018 Massdrop Inc. + +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 . +*/ + +#include "arm_atsam_protocol.h" + +#include "spi_master.h" +#include "wait.h" +#include "gpio.h" + +// #define SR_USE_BITBANG + +// Bodge for when spi_master is not available +#ifdef SR_USE_BITBANG +# define CLOCK_DELAY 10 + +void shift_init_impl(void) { + setPinOutput(SR_EXP_RCLK_PIN); + setPinOutput(SPI_DATAOUT_PIN); + setPinOutput(SPI_SCLK_PIN); +} + +void shift_out_impl(const uint8_t *data, uint16_t length) { + writePinLow(SR_EXP_RCLK_PIN); + for (uint16_t i = 0; i < length; i++) { + uint8_t val = data[i]; + + // shift out lsb first + for (uint8_t bit = 0; bit < 8; bit++) { + writePin(SPI_DATAOUT_PIN, !!(val & (1 << bit))); + writePin(SPI_SCLK_PIN, true); + wait_us(CLOCK_DELAY); + + writePin(SPI_SCLK_PIN, false); + wait_us(CLOCK_DELAY); + } + } + writePinHigh(SR_EXP_RCLK_PIN); + return SPI_STATUS_SUCCESS; +} + +#else + +void shift_init_impl(void) { spi_init(); } + +void shift_out_impl(const uint8_t *data, uint16_t length) { + spi_start(SR_EXP_RCLK_PIN, true, 0, 0); + + spi_transmit(data, length); + + spi_stop(); +} +#endif + +// *************************************************************** + +void shift_out(const uint8_t *data, uint16_t length) { shift_out_impl(data, length); } + +void shift_enable(void) { + setPinOutput(SR_EXP_OE_PIN); + writePinLow(SR_EXP_OE_PIN); +} + +void shift_disable(void) { + setPinOutput(SR_EXP_OE_PIN); + writePinHigh(SR_EXP_OE_PIN); +} + +void shift_init(void) { + shift_disable(); + shift_init_impl(); +} + +// *************************************************************** + +sr_exp_t sr_exp_data; + +void SR_EXP_WriteData(void) { + uint8_t data[2] = { + sr_exp_data.reg & 0xFF, // Shift in bits 7-0 + (sr_exp_data.reg >> 8) & 0xFF, // Shift in bits 15-8 + }; + shift_out(data, 2); +} + +void SR_EXP_Init(void) { + shift_init(); + + sr_exp_data.reg = 0; + sr_exp_data.bit.HUB_CONNECT = 0; + sr_exp_data.bit.HUB_RESET_N = 0; + sr_exp_data.bit.S_UP = 0; + sr_exp_data.bit.E_UP_N = 1; + sr_exp_data.bit.S_DN1 = 1; + sr_exp_data.bit.E_DN1_N = 1; + sr_exp_data.bit.E_VBUS_1 = 0; + sr_exp_data.bit.E_VBUS_2 = 0; + sr_exp_data.bit.SRC_1 = 1; + sr_exp_data.bit.SRC_2 = 1; + sr_exp_data.bit.IRST = 1; + sr_exp_data.bit.SDB_N = 0; + SR_EXP_WriteData(); + + shift_enable(); +} diff --git a/tmk_core/protocol/arm_atsam/spi.h b/tmk_core/protocol/arm_atsam/shift_register.h similarity index 77% rename from tmk_core/protocol/arm_atsam/spi.h rename to tmk_core/protocol/arm_atsam/shift_register.h index dcd45f31afe8..56a8c7f7177f 100644 --- a/tmk_core/protocol/arm_atsam/spi.h +++ b/tmk_core/protocol/arm_atsam/shift_register.h @@ -15,28 +15,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef _SPI_H_ -#define _SPI_H_ +#pragma once -/* Macros for Shift Register control */ -#define SR_EXP_RCLK_LO PORT->Group[SR_EXP_RCLK_PORT].OUTCLR.reg = (1 << SR_EXP_RCLK_PIN) -#define SR_EXP_RCLK_HI PORT->Group[SR_EXP_RCLK_PORT].OUTSET.reg = (1 << SR_EXP_RCLK_PIN) -#define SR_EXP_OE_N_ENA PORT->Group[SR_EXP_OE_N_PORT].OUTCLR.reg = (1 << SR_EXP_OE_N_PIN) -#define SR_EXP_OE_N_DIS PORT->Group[SR_EXP_OE_N_PORT].OUTSET.reg = (1 << SR_EXP_OE_N_PIN) - -/* Determine bits to set for mux selection */ -#if SR_EXP_DATAOUT_PIN % 2 == 0 -# define SR_EXP_DATAOUT_MUX_SEL PMUXE -#else -# define SR_EXP_DATAOUT_MUX_SEL PMUXO -#endif - -/* Determine bits to set for mux selection */ -#if SR_EXP_SCLK_PIN % 2 == 0 -# define SR_EXP_SCLK_MUX_SEL PMUXE -#else -# define SR_EXP_SCLK_MUX_SEL PMUXO -#endif +#include /* Data structure to define Shift Register output expander hardware */ /* This structure gets shifted into registers LSB first */ @@ -66,5 +47,3 @@ extern sr_exp_t sr_exp_data; void SR_EXP_WriteData(void); void SR_EXP_Init(void); - -#endif //_SPI_H_ diff --git a/tmk_core/protocol/arm_atsam/spi.c b/tmk_core/protocol/arm_atsam/spi.c deleted file mode 100644 index 3b118bc1f134..000000000000 --- a/tmk_core/protocol/arm_atsam/spi.c +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright 2018 Massdrop Inc. - -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 . -*/ - -#include "arm_atsam_protocol.h" - -sr_exp_t sr_exp_data; - -void SR_EXP_WriteData(void) { - SR_EXP_RCLK_LO; - - while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.DRE)) { - DBGC(DC_SPI_WRITE_DRE); - } - - SR_EXP_SERCOM->SPI.DATA.bit.DATA = sr_exp_data.reg & 0xFF; // Shift in bits 7-0 - while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { - DBGC(DC_SPI_WRITE_TXC_1); - } - - SR_EXP_SERCOM->SPI.DATA.bit.DATA = (sr_exp_data.reg >> 8) & 0xFF; // Shift in bits 15-8 - while (!(SR_EXP_SERCOM->SPI.INTFLAG.bit.TXC)) { - DBGC(DC_SPI_WRITE_TXC_2); - } - - SR_EXP_RCLK_HI; -} - -void SR_EXP_Init(void) { - DBGC(DC_SPI_INIT_BEGIN); - - CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT); - - // Set up MCU Shift Register pins - PORT->Group[SR_EXP_RCLK_PORT].DIRSET.reg = (1 << SR_EXP_RCLK_PIN); - PORT->Group[SR_EXP_OE_N_PORT].DIRSET.reg = (1 << SR_EXP_OE_N_PIN); - - // Set up MCU SPI pins - PORT->Group[SR_EXP_DATAOUT_PORT].PMUX[SR_EXP_DATAOUT_PIN / 2].bit.SR_EXP_DATAOUT_MUX_SEL = SR_EXP_DATAOUT_MUX; // MUX select for sercom - PORT->Group[SR_EXP_SCLK_PORT].PMUX[SR_EXP_SCLK_PIN / 2].bit.SR_EXP_SCLK_MUX_SEL = SR_EXP_SCLK_MUX; // MUX select for sercom - PORT->Group[SR_EXP_DATAOUT_PORT].PINCFG[SR_EXP_DATAOUT_PIN].bit.PMUXEN = 1; // MUX Enable - PORT->Group[SR_EXP_SCLK_PORT].PINCFG[SR_EXP_SCLK_PIN].bit.PMUXEN = 1; // MUX Enable - - // Initialize Shift Register - SR_EXP_OE_N_DIS; - SR_EXP_RCLK_HI; - - SR_EXP_SERCOM->SPI.CTRLA.bit.DORD = 1; // Data Order - LSB is transferred first - SR_EXP_SERCOM->SPI.CTRLA.bit.CPOL = 1; // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. - SR_EXP_SERCOM->SPI.CTRLA.bit.CPHA = 1; // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample - SR_EXP_SERCOM->SPI.CTRLA.bit.DIPO = 3; // Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) - SR_EXP_SERCOM->SPI.CTRLA.bit.DOPO = 0; // Data Output PAD[0], Serial Clock PAD[1] - SR_EXP_SERCOM->SPI.CTRLA.bit.MODE = 3; // Operating Mode - Master operation - - SR_EXP_SERCOM->SPI.CTRLA.bit.ENABLE = 1; // Enable - Peripheral is enabled or being enabled - while (SR_EXP_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { - DBGC(DC_SPI_SYNC_ENABLING); - } - - sr_exp_data.reg = 0; - sr_exp_data.bit.HUB_CONNECT = 0; - sr_exp_data.bit.HUB_RESET_N = 0; - sr_exp_data.bit.S_UP = 0; - sr_exp_data.bit.E_UP_N = 1; - sr_exp_data.bit.S_DN1 = 1; - sr_exp_data.bit.E_DN1_N = 1; - sr_exp_data.bit.E_VBUS_1 = 0; - sr_exp_data.bit.E_VBUS_2 = 0; - sr_exp_data.bit.SRC_1 = 1; - sr_exp_data.bit.SRC_2 = 1; - sr_exp_data.bit.IRST = 1; - sr_exp_data.bit.SDB_N = 0; - SR_EXP_WriteData(); - - // Enable Shift Register output - SR_EXP_OE_N_ENA; - - DBGC(DC_SPI_INIT_COMPLETE); -} diff --git a/tmk_core/protocol/arm_atsam/spi_master.c b/tmk_core/protocol/arm_atsam/spi_master.c new file mode 100644 index 000000000000..9781d45b1e00 --- /dev/null +++ b/tmk_core/protocol/arm_atsam/spi_master.c @@ -0,0 +1,109 @@ +/* +Copyright 2018 Massdrop Inc. + +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 . +*/ + +#include "arm_atsam_protocol.h" +#include "spi_master.h" +#include "gpio.h" + +/* Determine bits to set for mux selection */ +#if SPI_DATAOUT_PIN % 2 == 0 +# define SPI_DATAOUT_MUX_SEL PMUXE +#else +# define SPI_DATAOUT_MUX_SEL PMUXO +#endif + +/* Determine bits to set for mux selection */ +#if SPI_SCLK_PIN % 2 == 0 +# define SPI_SCLK_MUX_SEL PMUXE +#else +# define SPI_SCLK_MUX_SEL PMUXO +#endif + +static pin_t currentSelectPin = NO_PIN; + +__attribute__((weak)) void spi_init(void) { + static bool is_initialised = false; + if (!is_initialised) { + is_initialised = true; + + DBGC(DC_SPI_INIT_BEGIN); + + CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT); + + // Set up MCU SPI pins + PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PMUX[SAMD_PIN(SPI_DATAOUT_PIN) / 2].bit.SPI_DATAOUT_MUX_SEL = SPI_DATAOUT_MUX; // MUX select for sercom + PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PMUX[SAMD_PIN(SPI_SCLK_PIN) / 2].bit.SPI_SCLK_MUX_SEL = SPI_SCLK_MUX; // MUX select for sercom + PORT->Group[SAMD_PORT(SPI_DATAOUT_PIN)].PINCFG[SAMD_PIN(SPI_DATAOUT_PIN)].bit.PMUXEN = 1; // MUX Enable + PORT->Group[SAMD_PORT(SPI_SCLK_PIN)].PINCFG[SAMD_PIN(SPI_SCLK_PIN)].bit.PMUXEN = 1; // MUX Enable + + DBGC(DC_SPI_INIT_COMPLETE); + } +} + +bool spi_start(pin_t csPin, bool lsbFirst, uint8_t mode, uint16_t divisor) { + if (currentSelectPin != NO_PIN || csPin == NO_PIN) { + return false; + } + + currentSelectPin = csPin; + setPinOutput(currentSelectPin); + writePinLow(currentSelectPin); + + SPI_SERCOM->SPI.CTRLA.bit.DORD = lsbFirst; // Data Order - LSB is transferred first + SPI_SERCOM->SPI.CTRLA.bit.CPOL = 1; // Clock Polarity - SCK high when idle. Leading edge of cycle is falling. Trailing rising. + SPI_SERCOM->SPI.CTRLA.bit.CPHA = 1; // Clock Phase - Leading Edge Falling, change, Trailing Edge - Rising, sample + SPI_SERCOM->SPI.CTRLA.bit.DIPO = 3; // Data In Pinout - SERCOM PAD[3] is used as data input (Configure away from DOPO. Not using input.) + SPI_SERCOM->SPI.CTRLA.bit.DOPO = 0; // Data Output PAD[0], Serial Clock PAD[1] + SPI_SERCOM->SPI.CTRLA.bit.MODE = 3; // Operating Mode - Master operation + + SPI_SERCOM->SPI.CTRLA.bit.ENABLE = 1; // Enable - Peripheral is enabled or being enabled + while (SPI_SERCOM->SPI.SYNCBUSY.bit.ENABLE) { + DBGC(DC_SPI_SYNC_ENABLING); + } + return true; +} + +spi_status_t spi_transmit(const uint8_t *data, uint16_t length) { + while (!(SPI_SERCOM->SPI.INTFLAG.bit.DRE)) { + DBGC(DC_SPI_WRITE_DRE); + } + + for (uint16_t i = 0; i < length; i++) { + SPI_SERCOM->SPI.DATA.bit.DATA = data[i]; + while (!(SPI_SERCOM->SPI.INTFLAG.bit.TXC)) { + DBGC(DC_SPI_WRITE_TXC_1); + } + } + + return SPI_STATUS_SUCCESS; +} + +void spi_stop(void) { + if (currentSelectPin != NO_PIN) { + setPinOutput(currentSelectPin); + writePinHigh(currentSelectPin); + currentSelectPin = NO_PIN; + } +} + +// Not implemented yet.... + +spi_status_t spi_write(uint8_t data); + +spi_status_t spi_read(void); + +spi_status_t spi_receive(uint8_t *data, uint16_t length); diff --git a/tmk_core/protocol/arm_atsam/spi_master.h b/tmk_core/protocol/arm_atsam/spi_master.h new file mode 100644 index 000000000000..26c55128be12 --- /dev/null +++ b/tmk_core/protocol/arm_atsam/spi_master.h @@ -0,0 +1,48 @@ +/* Copyright 2021 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +typedef int16_t spi_status_t; + +#define SPI_STATUS_SUCCESS (0) +#define SPI_STATUS_ERROR (-1) +#define SPI_STATUS_TIMEOUT (-2) + +#define SPI_TIMEOUT_IMMEDIATE (0) +#define SPI_TIMEOUT_INFINITE (0xFFFF) + +#ifdef __cplusplus +extern "C" { +#endif +void spi_init(void); + +bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor); + +spi_status_t spi_write(uint8_t data); + +spi_status_t spi_read(void); + +spi_status_t spi_transmit(const uint8_t *data, uint16_t length); + +spi_status_t spi_receive(uint8_t *data, uint16_t length); + +void spi_stop(void); +#ifdef __cplusplus +} +#endif From 0093d3d761e60a31bb2a15a5859dbd0c08ef9999 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Fri, 22 Oct 2021 00:49:58 +0100 Subject: [PATCH 0012/1136] Initial USB2422 driver (#14835) --- .../usb/usb2422.h => drivers/usb2422.c | 216 +++++++++--------- drivers/usb2422.h | 59 +++++ keyboards/massdrop/alt/alt.h | 2 +- keyboards/massdrop/alt/config.h | 9 + keyboards/massdrop/ctrl/config.h | 9 + keyboards/massdrop/ctrl/ctrl.h | 2 +- tmk_core/protocol/arm_atsam.mk | 4 +- .../protocol/arm_atsam/arm_atsam_protocol.h | 2 +- tmk_core/protocol/arm_atsam/i2c_master.c | 19 ++ tmk_core/protocol/arm_atsam/i2c_master.h | 9 + tmk_core/protocol/arm_atsam/main_arm_atsam.c | 4 +- .../arm_atsam/usb/{usb2422.c => usb_hub.c} | 98 +------- tmk_core/protocol/arm_atsam/usb/usb_hub.h | 51 +++++ 13 files changed, 278 insertions(+), 206 deletions(-) rename tmk_core/protocol/arm_atsam/usb/usb2422.h => drivers/usb2422.c (68%) create mode 100644 drivers/usb2422.h rename tmk_core/protocol/arm_atsam/usb/{usb2422.c => usb_hub.c} (67%) create mode 100644 tmk_core/protocol/arm_atsam/usb/usb_hub.h diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.h b/drivers/usb2422.c similarity index 68% rename from tmk_core/protocol/arm_atsam/usb/usb2422.h rename to drivers/usb2422.c index b4830b5bc8fa..62b919093b96 100644 --- a/tmk_core/protocol/arm_atsam/usb/usb2422.h +++ b/drivers/usb2422.c @@ -1,32 +1,25 @@ -/* -Copyright 2018 Massdrop Inc. - -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 . -*/ - -#ifndef _USB2422_H_ -#define _USB2422_H_ - -#define REV_USB2422 0x100 - -#define USB2422_ADDR 0x58 // I2C device address, one instance - -#define USB2422_HUB_ACTIVE_GROUP 0 // PA -#define USB2422_HUB_ACTIVE_PIN 18 // 18 +/* Copyright 2021 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 3 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 . + */ +#include +#include "usb2422.h" +#include "i2c_master.h" +#include "wait.h" +#include "gpio.h" /* -------- USB2422_VID : (USB2422L Offset: 0x00) (R/W 16) Vendor ID -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint16_t VID_LSB : 8; @@ -34,10 +27,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint16_t reg; /*!< Type used for register access */ } USB2422_VID_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PID : (USB2422L Offset: 0x02) (R/W 16) Product ID -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint16_t PID_LSB : 8; @@ -45,10 +36,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint16_t reg; /*!< Type used for register access */ } USB2422_PID_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_DID : (USB2422L Offset: 0x04) (R/W 16) Device ID -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint16_t DID_LSB : 8; @@ -56,10 +45,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint16_t reg; /*!< Type used for register access */ } USB2422_DID_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_CFG1 : (USB2422L Offset: 0x06) (R/W 8) Configuration Data Byte 1-------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t PORT_PWR : 1; @@ -72,10 +59,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_CFG1_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_CFG2 : (USB2422L Offset: 0x07) (R/W 8) Configuration Data Byte 2-------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t : 3; @@ -86,10 +71,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_CFG2_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_CFG3 : (USB2422L Offset: 0x08) (R/W 16) Configuration Data Byte 3-------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t STRING_EN : 1; @@ -99,10 +82,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_CFG3_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_NRD : (USB2422L Offset: 0x09) (R/W 8) Non Removable Device -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t : 5; @@ -112,10 +93,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_NRD_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PDS : (USB2422L Offset: 0x0A) (R/W 8) Port Diable for Self-Powered Operation -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t : 1; @@ -125,10 +104,9 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_PDS_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PDB : (USB2422L Offset: 0x0B) (R/W 8) Port Diable for Bus-Powered Operation -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + typedef union { struct { uint8_t : 1; @@ -138,125 +116,98 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_PDB_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_MAXPS : (USB2422L Offset: 0x0C) (R/W 8) Max Power for Self-Powered Operation -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t MAX_PWR_SP : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_MAXPS_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_MAXPB : (USB2422L Offset: 0x0D) (R/W 8) Max Power for Bus-Powered Operation -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t MAX_PWR_BP : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_MAXPB_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_HCMCS : (USB2422L Offset: 0x0E) (R/W 8) Hub Controller Max Current for Self-Powered Operation -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t HC_MAX_C_SP : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_HCMCS_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_HCMCB : (USB2422L Offset: 0x0F) (R/W 8) Hub Controller Max Current for Bus-Powered Operation -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t HC_MAX_C_BP : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_HCMCB_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PWRT : (USB2422L Offset: 0x10) (R/W 8) Power On Time -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t POWER_ON_TIME : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_PWRT_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_LANGID LSB : (USB2422L Offset: 0x11) (R/W 16) Language ID -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t LANGID_LSB : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_LANGID_LSB_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_LANGID MSB : (USB2422L Offset: 0x12) (R/W 16) Language ID -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t LANGID_MSB : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_LANGID_MSB_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_MFRSL : (USB2422L Offset: 0x13) (R/W 8) Manufacturer String Length -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t MFR_STR_LEN : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_MFRSL_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PRDSL : (USB2422L Offset: 0x14) (R/W 8) Product String Length -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t PRD_STR_LEN : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_PRDSL_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_SERSL : (USB2422L Offset: 0x15) (R/W 8) Serial String Length -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t SER_STR_LEN : 8; } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_SERSL_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_MFRSTR : (USB2422L Offset: 0x16-53) (R/W 8) Maufacturer String -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef uint16_t USB2422_MFRSTR_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PRDSTR : (USB2422L Offset: 0x54-91) (R/W 8) Product String -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef uint16_t USB2422_PRDSTR_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_SERSTR : (USB2422L Offset: 0x92-CF) (R/W 8) Serial String -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef uint16_t USB2422_SERSTR_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_BCEN : (USB2422L Offset: 0xD0) (R/W 8) Battery Charging Enable -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + typedef union { struct { uint8_t : 1; @@ -266,10 +217,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_BCEN_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_BOOSTUP : (USB2422L Offset: 0xF6) (R/W 8) Boost Upstream -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t BOOST : 2; @@ -277,10 +226,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_BOOSTUP_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_BOOSTDOWN : (USB2422L Offset: 0xF8) (R/W 8) Boost Downstream -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t BOOST1 : 2; @@ -289,10 +236,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_BOOSTDOWN_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PRTSP : (USB2422L Offset: 0xFA) (R/W 8) Port Swap -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t : 1; @@ -302,10 +247,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_PRTSP_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /* -------- USB2422_PRTR12 : (USB2422L Offset: 0xFB) (R/W 8) Port 1/2 Remap -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t PORT1_REMAP : 4; @@ -313,7 +256,7 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_PRTR12_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + #define USB2422_PRTR12_DISABLE 0 #define USB2422_PRT12_P2TOL1 1 #define USB2422_PRT12_P2XTOL2 2 @@ -321,7 +264,6 @@ typedef union { #define USB2422_PRT12_P1XTOL2 2 /* -------- USB2422_STCD : (USB2422L Offset: 0xFF) (R/W 8) Status Command -------- */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef union { struct { uint8_t USB_ATTACH : 1; @@ -331,10 +273,8 @@ typedef union { } bit; /*!< Structure used for bit access */ uint8_t reg; /*!< Type used for register access */ } USB2422_STCD_Type; -#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ /** \brief USB2422 device hardware registers */ -#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) typedef struct { USB2422_VID_Type VID; /**< \brief Offset: 0x00*/ USB2422_PID_Type PID; /**< \brief Offset: 0x02*/ @@ -368,35 +308,95 @@ typedef struct { USB2422_PRTR12_Type PRTR12; /**< \brief Offset: 0xFB*/ uint8_t Reserved4[0x3]; USB2422_STCD_Type STCD; /**< \brief Offset: 0xFF*/ -} Usb2422; -#endif +} Usb2422_t; + +// *************************************************************** + +static Usb2422_t config; -#define PORT_DETECT_RETRY_INTERVAL 2000 +// *************************************************************** -#define USB_EXTRA_ADC_THRESHOLD 900 +/** \brief Handle the conversion to allow simple strings + */ +static void USB2422_strcpy(const char* str, USB2422_MFRSTR_Type* dest, uint8_t len) { + for (uint8_t i = 0; i < len; i++) { + dest[i] = str[i]; + } +} -#define USB_EXTRA_STATE_DISABLED 0 -#define USB_EXTRA_STATE_ENABLED 1 -#define USB_EXTRA_STATE_UNKNOWN 2 -#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3 +/** \brief Handle the conversion to allow simple strings + */ +static void USB2422_write_block(void) { + static unsigned char i2c0_buf[34]; -#define USB_HOST_PORT_1 0 -#define USB_HOST_PORT_2 1 -#define USB_HOST_PORT_UNKNOWN 2 + unsigned char* dest = i2c0_buf; + unsigned char* src; + unsigned char* base = (unsigned char*)&config; -extern uint8_t usb_host_port; -extern uint8_t usb_extra_state; -extern uint8_t usb_extra_manual; -extern uint8_t usb_gcr_auto; + for (src = base; src < base + 256; src += 32) { + dest[0] = src - base; + dest[1] = 32; + memcpy(&dest[2], src, 32); + i2c_transmit(USB2422_ADDRESS, dest, 34, 50000); + wait_us(100); + } +} -void USB2422_init(void); -void USB_reset(void); -void USB_configure(void); -uint16_t USB_active(void); -void USB_set_host_by_voltage(void); -uint16_t adc_get(uint8_t muxpos); -uint8_t USB2422_Port_Detect_Init(void); -void USB_HandleExtraDevice(void); -void USB_ExtraSetState(uint8_t state); +// *************************************************************** -#endif //_USB2422_H_ +void USB2422_init() { +#ifdef USB2422_RESET_PIN + setPinOutput(USB2422_RESET_PIN); +#endif +#ifdef USB2422_ACTIVE_PIN + setPinInput(USB2422_ACTIVE_PIN); +#endif + + i2c_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration +} + +void USB2422_configure() { + static const char SERNAME[] = "Unavailable"; + + memset(&config, 0, sizeof(Usb2422_t)); + + // configure Usb2422 registers + config.VID.reg = USB2422_VENDOR_ID; + config.PID.reg = USB2422_PRODUCT_ID; + config.DID.reg = USB2422_DEVICE_VER; // BCD format, eg 01.01 + config.CFG1.bit.SELF_BUS_PWR = 1; // self powered for now + config.CFG1.bit.HS_DISABLE = 1; // full or high speed + // config.CFG2.bit.COMPOUND = 0; // compound device + config.CFG3.bit.STRING_EN = 1; // strings enabled + // config.NRD.bit.PORT2_NR = 0; // MCU is non-removable + config.MAXPB.reg = 20; // 0mA + config.HCMCB.reg = 20; // 0mA + config.MFRSL.reg = sizeof(USB2422_MANUFACTURER); + config.PRDSL.reg = sizeof(USB2422_PRODUCT); + config.SERSL.reg = sizeof(SERNAME); + USB2422_strcpy(USB2422_MANUFACTURER, config.MFRSTR, sizeof(USB2422_MANUFACTURER)); + USB2422_strcpy(USB2422_PRODUCT, config.PRDSTR, sizeof(USB2422_PRODUCT)); + USB2422_strcpy(SERNAME, config.SERSTR, sizeof(SERNAME)); + // config.BOOSTUP.bit.BOOST=3; //upstream port + // config.BOOSTDOWN.bit.BOOST1=0; // extra port + // config.BOOSTDOWN.bit.BOOST2=2; //MCU is close + config.STCD.bit.USB_ATTACH = 1; + + USB2422_write_block(); +} + +void USB2422_reset() { +#ifdef USB2422_RESET_PIN + writePinLow(USB2422_RESET_PIN); + wait_us(2); + writePinHigh(USB2422_RESET_PIN); +#endif +} + +bool USB2422_active() { +#ifdef USB2422_ACTIVE_PIN + return readPin(USB2422_ACTIVE_PIN); +#else + return 1; +#endif +} diff --git a/drivers/usb2422.h b/drivers/usb2422.h new file mode 100644 index 000000000000..2e435b02bc97 --- /dev/null +++ b/drivers/usb2422.h @@ -0,0 +1,59 @@ +/* Copyright 2021 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include + +#ifndef USB2422_ADDRESS +# define USB2422_ADDRESS 0x58 +#endif + +#ifndef USB2422_VENDOR_ID +# define USB2422_VENDOR_ID 0xFEED +#endif +#ifndef USB2422_PRODUCT_ID +# define USB2422_PRODUCT_ID 0x0001 +#endif +#ifndef USB2422_DEVICE_VER +# define USB2422_DEVICE_VER 0x0001 +#endif + +#ifndef USB2422_MANUFACTURER +# define USB2422_MANUFACTURER "QMK" +#endif +#ifndef USB2422_PRODUCT +# define USB2422_PRODUCT "QMK Hub" +#endif + +/** \brief Initialises the dependent subsystems */ +void USB2422_init(void); + +/** \brief Push configuration to the USB2422 device */ +void USB2422_configure(void); + +/** \brief Reset the chip (RESET_N) + * + * NOTE: + * Depends on a valid USB2422_RESET_PIN configuration + */ +void USB2422_reset(void); + +/** \brief Indicates the USB state of the hub (SUSP_IND) + * + * NOTE: + * Depends on a valid USB2422_ACTIVE_PIN configuration + */ +bool USB2422_active(void); diff --git a/keyboards/massdrop/alt/alt.h b/keyboards/massdrop/alt/alt.h index 03960954506a..c3761bee8bab 100644 --- a/keyboards/massdrop/alt/alt.h +++ b/keyboards/massdrop/alt/alt.h @@ -7,7 +7,7 @@ #include "i2c_master.h" #include "md_rgb_matrix.h" //For led keycodes #include "usb/udi_cdc.h" -#include "usb/usb2422.h" +#include "usb/usb_hub.h" #define LAYOUT_65_ansi_blocker( \ K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, \ diff --git a/keyboards/massdrop/alt/config.h b/keyboards/massdrop/alt/config.h index 085e1aebbaea..c37949a74b68 100644 --- a/keyboards/massdrop/alt/config.h +++ b/keyboards/massdrop/alt/config.h @@ -90,6 +90,15 @@ along with this program. If not, see . #define DEBUG_BOOT_TRACING_PORT PB #define DEBUG_BOOT_TRACING_PIN 23 +/* USB2422 config */ +#define USB2422_ADDRESS 0x58 +#define USB2422_VENDOR_ID 0x04D8 +#define USB2422_PRODUCT_ID 0xEEC5 +#define USB2422_DEVICE_VER 0x0101 +#define USB2422_MANUFACTURER "Massdrop Inc." +#define USB2422_PRODUCT "Massdrop Hub" +#define USB2422_ACTIVE_PIN A18 + /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCE 5 diff --git a/keyboards/massdrop/ctrl/config.h b/keyboards/massdrop/ctrl/config.h index aefb9004486b..fe8b60023418 100644 --- a/keyboards/massdrop/ctrl/config.h +++ b/keyboards/massdrop/ctrl/config.h @@ -89,6 +89,15 @@ along with this program. If not, see . #define DEBUG_BOOT_TRACING_PORT PB #define DEBUG_BOOT_TRACING_PIN 23 +/* USB2422 config */ +#define USB2422_ADDRESS 0x58 +#define USB2422_VENDOR_ID 0x04D8 +#define USB2422_PRODUCT_ID 0xEEC5 +#define USB2422_DEVICE_VER 0x0101 +#define USB2422_MANUFACTURER "Massdrop Inc." +#define USB2422_PRODUCT "Massdrop Hub" +#define USB2422_ACTIVE_PIN A18 + /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ #define DEBOUNCE 5 diff --git a/keyboards/massdrop/ctrl/ctrl.h b/keyboards/massdrop/ctrl/ctrl.h index 1650beb9a444..a3d66ba77551 100644 --- a/keyboards/massdrop/ctrl/ctrl.h +++ b/keyboards/massdrop/ctrl/ctrl.h @@ -7,7 +7,7 @@ #include "i2c_master.h" #include "md_rgb_matrix.h" //For led keycodes #include "usb/udi_cdc.h" -#include "usb/usb2422.h" +#include "usb/usb_hub.h" #define LAYOUT( \ K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, \ diff --git a/tmk_core/protocol/arm_atsam.mk b/tmk_core/protocol/arm_atsam.mk index e3b550596625..ffd1fa9f5027 100644 --- a/tmk_core/protocol/arm_atsam.mk +++ b/tmk_core/protocol/arm_atsam.mk @@ -20,10 +20,12 @@ SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd.c SRC += $(ARM_ATSAM_DIR)/usb/udi_hid_kbd_desc.c SRC += $(ARM_ATSAM_DIR)/usb/ui.c -SRC += $(ARM_ATSAM_DIR)/usb/usb2422.c SRC += $(ARM_ATSAM_DIR)/usb/usb.c SRC += $(ARM_ATSAM_DIR)/usb/usb_device_udd.c +SRC += $(ARM_ATSAM_DIR)/usb/usb_hub.c SRC += $(ARM_ATSAM_DIR)/usb/usb_util.c +SRC += $(DRIVER_PATH)/usb2422.c + # Search Path VPATH += $(TMK_DIR)/$(ARM_ATSAM_DIR) diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h index c3eab39fb184..e1749f872daa 100644 --- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h +++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h @@ -29,7 +29,7 @@ along with this program. If not, see . #include "i2c_master.h" #include "shift_register.h" -#include "./usb/usb2422.h" +#include "./usb/usb_hub.h" #ifndef MD_BOOTLOADER diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c index dda2f85b0019..af046625f433 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.c +++ b/tmk_core/protocol/arm_atsam/i2c_master.c @@ -564,4 +564,23 @@ uint8_t i2c_led_q_run(void) { return 1; } + +__attribute__((weak)) void i2c_init(void) { + static bool is_initialised = false; + if (!is_initialised) { + is_initialised = true; + + i2c0_init(); + } +} + +i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) { + uint8_t ret = i2c0_transmit(address, (uint8_t *)data, length, timeout); + SERCOM0->I2CM.CTRLB.bit.CMD = 0x03; + while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { + DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP); + } + return ret ? I2C_STATUS_SUCCESS : I2C_STATUS_ERROR; +} + #endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE) diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h index 68773f213fbe..e11235d4476a 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.h +++ b/tmk_core/protocol/arm_atsam/i2c_master.h @@ -101,4 +101,13 @@ void i2c0_init(void); uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout); void i2c0_stop(void); +// Terrible interface compatiblity... +#define I2C_STATUS_SUCCESS (0) +#define I2C_STATUS_ERROR (-1) + +typedef int16_t i2c_status_t; + +void i2c_init(void); +i2c_status_t i2c_transmit(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout); + #endif // _I2C_MASTER_H_ diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index 858b4cd9fc02..1df5112ed8a6 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c @@ -296,7 +296,7 @@ int main(void) { matrix_init(); - USB2422_init(); + USB_Hub_init(); DBGC(DC_MAIN_UDC_START_BEGIN); udc_start(); @@ -306,7 +306,7 @@ int main(void) { CDC_init(); DBGC(DC_MAIN_CDC_INIT_COMPLETE); - while (USB2422_Port_Detect_Init() == 0) { + while (USB_Hub_Port_Detect_Init() == 0) { } DBG_LED_OFF; diff --git a/tmk_core/protocol/arm_atsam/usb/usb2422.c b/tmk_core/protocol/arm_atsam/usb/usb_hub.c similarity index 67% rename from tmk_core/protocol/arm_atsam/usb/usb2422.c rename to tmk_core/protocol/arm_atsam/usb/usb_hub.c index a878cb6b7cab..c5fd284aab76 100644 --- a/tmk_core/protocol/arm_atsam/usb/usb2422.c +++ b/tmk_core/protocol/arm_atsam/usb/usb_hub.c @@ -16,25 +16,9 @@ along with this program. If not, see . */ #include "arm_atsam_protocol.h" +#include "drivers/usb2422.h" #include -Usb2422 USB2422_shadow; -unsigned char i2c0_buf[34]; - -const uint16_t MFRNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'I', 'n', 'c', '.'}; // Massdrop Inc. -const uint16_t PRDNAME[] = {'M', 'a', 's', 's', 'd', 'r', 'o', 'p', ' ', 'H', 'u', 'b'}; // Massdrop Hub -#ifndef MD_BOOTLOADER -// Serial number reported stops before first found space character or at last found character -const uint16_t SERNAME[] = {'U', 'n', 'a', 'v', 'a', 'i', 'l', 'a', 'b', 'l', 'e'}; // Unavailable -#else -// In production, this field is found, modified, and offset noted as the last 32-bit word in the bootloader space -// The offset allows the application to use the factory programmed serial (which may differ from the physical serial label) -// Serial number reported stops before first found space character or when max size is reached -__attribute__((__aligned__(4))) const uint16_t SERNAME[BOOTLOADER_SERIAL_MAX_SIZE] = {'M', 'D', 'H', 'U', 'B', 'B', 'O', 'O', 'T', 'L', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'}; -// NOTE: Serial replacer will not write a string longer than given here as a precaution, so give enough -// space as needed and adjust BOOTLOADER_SERIAL_MAX_SIZE to match amount given -#endif // MD_BOOTLOADER - uint8_t usb_host_port; #ifndef MD_BOOTLOADER @@ -47,29 +31,7 @@ uint8_t usb_gcr_auto; uint16_t adc_extra; -void USB_write2422_block(void) { - unsigned char *dest = i2c0_buf; - unsigned char *src; - unsigned char *base = (unsigned char *)&USB2422_shadow; - - DBGC(DC_USB_WRITE2422_BLOCK_BEGIN); - - for (src = base; src < base + 256; src += 32) { - dest[0] = src - base; - dest[1] = 32; - memcpy(&dest[2], src, 32); - i2c0_transmit(USB2422_ADDR, dest, 34, 50000); - SERCOM0->I2CM.CTRLB.bit.CMD = 0x03; - while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { - DBGC(DC_USB_WRITE2422_BLOCK_SYNC_SYSOP); - } - wait_us(100); - } - - DBGC(DC_USB_WRITE2422_BLOCK_COMPLETE); -} - -void USB2422_init(void) { +void USB_Hub_init(void) { Gclk * pgclk = GCLK; Mclk * pmclk = MCLK; Port * pport = PORT; @@ -147,9 +109,7 @@ void USB2422_init(void) { pusb->DEVICE.QOSCTRL.bit.DQOS = 2; pusb->DEVICE.QOSCTRL.bit.CQOS = 2; - pport->Group[USB2422_HUB_ACTIVE_GROUP].PINCFG[USB2422_HUB_ACTIVE_PIN].bit.INEN = 1; - - i2c0_init(); // IC2 clk must be high at USB2422 reset release time to signal SMB configuration + USB2422_init(); sr_exp_data.bit.HUB_CONNECT = 1; // connect signal sr_exp_data.bit.HUB_RESET_N = 1; // reset high @@ -181,62 +141,16 @@ void USB_reset(void) { } void USB_configure(void) { - Usb2422 *pusb2422 = &USB2422_shadow; - memset(pusb2422, 0, sizeof(Usb2422)); - - uint16_t *serial_use = (uint16_t *)SERNAME; // Default to use SERNAME from this file - uint8_t serial_length = sizeof(SERNAME) / sizeof(uint16_t); // Default to use SERNAME from this file -#ifndef MD_BOOTLOADER - uint32_t serial_ptrloc = (uint32_t)&_srom - 4; -#else // MD_BOOTLOADER - uint32_t serial_ptrloc = (uint32_t)&_erom - 4; -#endif // MD_BOOTLOADER - uint32_t serial_address = *(uint32_t *)serial_ptrloc; // Address of bootloader's serial number if available - DBGC(DC_USB_CONFIGURE_BEGIN); - if (serial_address != 0xFFFFFFFF && serial_address < serial_ptrloc) // Check for factory programmed serial address - { - if ((serial_address & 0xFF) % 4 == 0) // Check alignment - { - serial_use = (uint16_t *)(serial_address); - serial_length = 0; - while ((*(serial_use + serial_length) > 32 && *(serial_use + serial_length) < 127) && serial_length < BOOTLOADER_SERIAL_MAX_SIZE) { - serial_length++; - DBGC(DC_USB_CONFIGURE_GET_SERIAL); - } - } - } - - // configure Usb2422 registers - pusb2422->VID.reg = 0x04D8; // from Microchip 4/19/2018 - pusb2422->PID.reg = 0xEEC5; // from Microchip 4/19/2018 = Massdrop, Inc. USB Hub - pusb2422->DID.reg = 0x0101; // BCD 01.01 - pusb2422->CFG1.bit.SELF_BUS_PWR = 1; // self powered for now - pusb2422->CFG1.bit.HS_DISABLE = 1; // full or high speed - // pusb2422->CFG2.bit.COMPOUND = 0; // compound device - pusb2422->CFG3.bit.STRING_EN = 1; // strings enabled - // pusb2422->NRD.bit.PORT2_NR = 0; // MCU is non-removable - pusb2422->MAXPB.reg = 20; // 0mA - pusb2422->HCMCB.reg = 20; // 0mA - pusb2422->MFRSL.reg = sizeof(MFRNAME) / sizeof(uint16_t); - pusb2422->PRDSL.reg = sizeof(PRDNAME) / sizeof(uint16_t); - pusb2422->SERSL.reg = serial_length; - memcpy(pusb2422->MFRSTR, MFRNAME, sizeof(MFRNAME)); - memcpy(pusb2422->PRDSTR, PRDNAME, sizeof(PRDNAME)); - memcpy(pusb2422->SERSTR, serial_use, serial_length * sizeof(uint16_t)); - // pusb2422->BOOSTUP.bit.BOOST=3; //upstream port - // pusb2422->BOOSTDOWN.bit.BOOST1=0; // extra port - // pusb2422->BOOSTDOWN.bit.BOOST2=2; //MCU is close - pusb2422->STCD.bit.USB_ATTACH = 1; - USB_write2422_block(); + USB2422_configure(); adc_extra = 0; DBGC(DC_USB_CONFIGURE_COMPLETE); } -uint16_t USB_active(void) { return (PORT->Group[USB2422_HUB_ACTIVE_GROUP].IN.reg & (1 << USB2422_HUB_ACTIVE_PIN)) != 0; } +uint16_t USB_active(void) { return USB2422_active(); } void USB_set_host_by_voltage(void) { // UP is upstream device (HOST) @@ -314,7 +228,7 @@ void USB_set_host_by_voltage(void) { DBGC(DC_USB_SET_HOST_BY_VOLTAGE_COMPLETE); } -uint8_t USB2422_Port_Detect_Init(void) { +uint8_t USB_Hub_Port_Detect_Init(void) { uint32_t port_detect_retry_ms; uint32_t tmod; diff --git a/tmk_core/protocol/arm_atsam/usb/usb_hub.h b/tmk_core/protocol/arm_atsam/usb/usb_hub.h new file mode 100644 index 000000000000..76b1e0a32633 --- /dev/null +++ b/tmk_core/protocol/arm_atsam/usb/usb_hub.h @@ -0,0 +1,51 @@ +/* +Copyright 2018 Massdrop Inc. + +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 . +*/ + +#ifndef _USB2422_H_ +#define _USB2422_H_ + +#define REV_USB2422 0x100 + +#define PORT_DETECT_RETRY_INTERVAL 2000 + +#define USB_EXTRA_ADC_THRESHOLD 900 + +#define USB_EXTRA_STATE_DISABLED 0 +#define USB_EXTRA_STATE_ENABLED 1 +#define USB_EXTRA_STATE_UNKNOWN 2 +#define USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG 3 + +#define USB_HOST_PORT_1 0 +#define USB_HOST_PORT_2 1 +#define USB_HOST_PORT_UNKNOWN 2 + +extern uint8_t usb_host_port; +extern uint8_t usb_extra_state; +extern uint8_t usb_extra_manual; +extern uint8_t usb_gcr_auto; + +void USB_Hub_init(void); +uint8_t USB_Hub_Port_Detect_Init(void); +void USB_reset(void); +void USB_configure(void); +uint16_t USB_active(void); +void USB_set_host_by_voltage(void); +uint16_t adc_get(uint8_t muxpos); +void USB_HandleExtraDevice(void); +void USB_ExtraSetState(uint8_t state); + +#endif //_USB2422_H_ From 3979137995e32491ddebc48eab991a4dfdccc02f Mon Sep 17 00:00:00 2001 From: James Young <18669334+noroadsleft@users.noreply.github.com> Date: Fri, 22 Oct 2021 13:32:14 +0000 Subject: [PATCH 0013/1136] Pteron36 Refactor (#14904) * reformat info.json - friendly-format info.json - move the right half to the left by 0.5u (improves readability, for me anyway) - correct key sequence * refactor default keymap - use short-form keycodes - use four-space indent * refactor via keymap - use short-form keycodes - use four-space indent * update maintainer field in info.json Use the maintainer's GitHub username. * readme touch-up Minor edit to the lead paragraph, and reformat the Hardware Availability section. * change BOOTMAGIC_ENABLE from `lite` to `yes` --- keyboards/pteron36/info.json | 88 ++++++++++++++++++- keyboards/pteron36/keymaps/default/keymap.c | 13 +-- keyboards/pteron36/keymaps/via/keymap.c | 95 +++++++++++---------- keyboards/pteron36/readme.md | 5 +- keyboards/pteron36/rules.mk | 2 +- 5 files changed, 144 insertions(+), 59 deletions(-) diff --git a/keyboards/pteron36/info.json b/keyboards/pteron36/info.json index b493879bf2d2..e191dc616fd6 100644 --- a/keyboards/pteron36/info.json +++ b/keyboards/pteron36/info.json @@ -1,13 +1,95 @@ { "keyboard_name": "Pteron36", "url": "", - "maintainer": "Harshit Goel", + "maintainer": "harshitgoel96", "layouts": { "LAYOUT_split_3x5_3": { - "layout": [{"x":2, "y":0}, {"x":12.5, "y":0}, {"x":1, "y":0.5}, {"x":3, "y":0.5}, {"x":11.5, "y":0.5}, {"x":13.5, "y":0.5}, {"x":4, "y":0.75}, {"x":10.5, "y":0.75}, {"x":0, "y":1}, {"x":2, "y":1}, {"x":12.5, "y":1}, {"x":14.5, "y":1}, {"x":1, "y":1.5}, {"x":3, "y":1.5}, {"x":11.5, "y":1.5}, {"x":13.5, "y":1.5}, {"x":4, "y":1.75}, {"x":10.5, "y":1.75}, {"x":0, "y":2}, {"x":2, "y":2}, {"x":12.5, "y":2}, {"x":14.5, "y":2}, {"x":1, "y":2.5}, {"x":3, "y":2.5}, {"x":11.5, "y":2.5}, {"x":13.5, "y":2.5}, {"x":4, "y":2.75}, {"x":10.5, "y":2.75}, {"x":0, "y":3}, {"x":14.5, "y":3}, {"x":4, "y":4}, {"x":5, "y":4}, {"x":6, "y":4}, {"x":8.5, "y":4}, {"x":9.5, "y":4}, {"x":10.5, "y":4}] + "layout": [ + {"x":0, "y":1}, + {"x":1, "y":0.5}, + {"x":2, "y":0}, + {"x":3, "y":0.5}, + {"x":4, "y":0.75}, + {"x":10, "y":0.75}, + {"x":11, "y":0.5}, + {"x":12, "y":0}, + {"x":13, "y":0.5}, + {"x":14, "y":1}, + + {"x":0, "y":2}, + {"x":1, "y":1.5}, + {"x":2, "y":1}, + {"x":3, "y":1.5}, + {"x":4, "y":1.75}, + {"x":10, "y":1.75}, + {"x":11, "y":1.5}, + {"x":12, "y":1}, + {"x":13, "y":1.5}, + {"x":14, "y":2}, + + {"x":0, "y":3}, + {"x":1, "y":2.5}, + {"x":2, "y":2}, + {"x":3, "y":2.5}, + {"x":4, "y":2.75}, + {"x":10, "y":2.75}, + {"x":11, "y":2.5}, + {"x":12, "y":2}, + {"x":13, "y":2.5}, + {"x":14, "y":3}, + + {"x":4, "y":4}, + {"x":5, "y":4}, + {"x":6, "y":4}, + {"x":8, "y":4}, + {"x":9, "y":4}, + {"x":10, "y":4} + ] }, "LAYOUT_split_3x5_3_encoder": { - "layout": [{"x":2, "y":0}, {"x":12.5, "y":0}, {"x":1, "y":0.5}, {"x":3, "y":0.5}, {"x":11.5, "y":0.5}, {"x":13.5, "y":0.5}, {"x":4, "y":0.75}, {"x":10.5, "y":0.75}, {"x":0, "y":1}, {"x":2, "y":1}, {"x":12.5, "y":1}, {"x":14.5, "y":1}, {"x":1, "y":1.5}, {"x":3, "y":1.5}, {"x":11.5, "y":1.5}, {"x":13.5, "y":1.5}, {"x":4, "y":1.75}, {"x":10.5, "y":1.75}, {"x":0, "y":2}, {"x":2, "y":2}, {"x":12.5, "y":2}, {"x":14.5, "y":2}, {"x":1, "y":2.5}, {"x":3, "y":2.5}, {"x":11.5, "y":2.5}, {"x":13.5, "y":2.5}, {"x":4, "y":2.75}, {"label":"enc1", "x":5.5, "y":2.75}, {"label":"enc2", "x":9, "y":2.75}, {"x":10.5, "y":2.75}, {"x":0, "y":3}, {"x":14.5, "y":3}, {"x":4, "y":4}, {"x":5, "y":4}, {"x":6, "y":4}, {"x":8.5, "y":4}, {"x":9.5, "y":4}, {"x":10.5, "y":4}] + "layout": [ + {"x":0, "y":1}, + {"x":1, "y":0.5}, + {"x":2, "y":0}, + {"x":3, "y":0.5}, + {"x":4, "y":0.75}, + {"x":10, "y":0.75}, + {"x":11, "y":0.5}, + {"x":12, "y":0}, + {"x":13, "y":0.5}, + {"x":14, "y":1}, + + {"x":0, "y":2}, + {"x":1, "y":1.5}, + {"x":2, "y":1}, + {"x":3, "y":1.5}, + {"x":4, "y":1.75}, + {"x":10, "y":1.75}, + {"x":11, "y":1.5}, + {"x":12, "y":1}, + {"x":13, "y":1.5}, + {"x":14, "y":2}, + + {"x":0, "y":3}, + {"x":1, "y":2.5}, + {"x":2, "y":2}, + {"x":3, "y":2.5}, + {"x":4, "y":2.75}, + {"label":"enc1", "x":5.5, "y":2.75}, + {"label":"enc2", "x":8.5, "y":2.75}, + {"x":10, "y":2.75}, + {"x":11, "y":2.5}, + {"x":12, "y":2}, + {"x":13, "y":2.5}, + {"x":14, "y":3}, + + {"x":4, "y":4}, + {"x":5, "y":4}, + {"x":6, "y":4}, + {"x":8, "y":4}, + {"x":9, "y":4}, + {"x":10, "y":4} + ] } } } diff --git a/keyboards/pteron36/keymaps/default/keymap.c b/keyboards/pteron36/keymaps/default/keymap.c index 0cc0e2b4716a..14b4e5979b24 100644 --- a/keyboards/pteron36/keymaps/default/keymap.c +++ b/keyboards/pteron36/keymaps/default/keymap.c @@ -27,9 +27,10 @@ enum custom_keycodes { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [_QWERTY] = LAYOUT_split_3x5_3_encoder( - KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, - KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, - KC_Z, KC_X, KC_C, KC_V, KC_B,KC_LBRACKET, KC_RBRACKET, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, - KC_LGUI, KC_BSPC, KC_SPC, KC_SPC, KC_ENT, KC_RALT - )}; + [_QWERTY] = LAYOUT_split_3x5_3_encoder( + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, + KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, + KC_LGUI, KC_BSPC, KC_SPC, KC_SPC, KC_ENT, KC_RALT + ) +}; diff --git a/keyboards/pteron36/keymaps/via/keymap.c b/keyboards/pteron36/keymaps/via/keymap.c index 9e467dcde529..ce96ea6c5987 100644 --- a/keyboards/pteron36/keymaps/via/keymap.c +++ b/keyboards/pteron36/keymaps/via/keymap.c @@ -33,53 +33,54 @@ enum layer_names { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [_QWERTY] = LAYOUT_split_3x5_3_encoder( - KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, - KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, - KC_Z, KC_X, KC_C, KC_V, KC_B,KC_LBRACKET, KC_RBRACKET, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, - KC_LGUI, KC_BSPC, KC_SPC, KC_SPC, KC_ENT, KC_RALT - ), - - [_SYMB] = LAYOUT_split_3x5_3_encoder( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS - ), - - [_NAV] = LAYOUT_split_3x5_3_encoder( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS - ), - - [_ADJUST] = LAYOUT_split_3x5_3_encoder( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS - ), - [_MOUSE] = LAYOUT_split_3x5_3_encoder( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS - ), - - [_NUMB] = LAYOUT_split_3x5_3_encoder( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS - ), - - [_FNR] = LAYOUT_split_3x5_3_encoder( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS - ) + [_QWERTY] = LAYOUT_split_3x5_3_encoder( + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, + KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, + KC_LGUI, KC_BSPC, KC_SPC, KC_SPC, KC_ENT, KC_RALT + ), + + [_SYMB] = LAYOUT_split_3x5_3_encoder( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [_NAV] = LAYOUT_split_3x5_3_encoder( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [_ADJUST] = LAYOUT_split_3x5_3_encoder( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [_MOUSE] = LAYOUT_split_3x5_3_encoder( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [_NUMB] = LAYOUT_split_3x5_3_encoder( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + [_FNR] = LAYOUT_split_3x5_3_encoder( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) }; diff --git a/keyboards/pteron36/readme.md b/keyboards/pteron36/readme.md index a68c7a55b4fe..0e430db24326 100644 --- a/keyboards/pteron36/readme.md +++ b/keyboards/pteron36/readme.md @@ -2,11 +2,12 @@ ![Pteron36](https://i.imgur.com/PuXPWYfh.jpg) -A 36 key keyboard with a bit more natural thumb cluster. +A 36-key keyboard with a bit more natural thumb cluster. * Keyboard Maintainer: [Harshit Goel](https://github.com/harshitgoel96) * Hardware Supported: Pteron36 using promicro. -* Hardware Availability: Hardware is opensource, you can simply send the gerber to a PCB manufacturere and them made. File are availalbe in [pteron36 repository](https://github.com/harshitgoel96/pteron36-split-keyboard/releases/tag/v1.2.0) +* Hardware Availability: Files are available in the [pteron36 repository](https://github.com/harshitgoel96/pteron36-split-keyboard/releases/tag/v1.2.0) + * The hardware is open source; you can simply send the Gerber to a PCB manufacturer and have them made. Make example for this keyboard (after setting up your build environment): diff --git a/keyboards/pteron36/rules.mk b/keyboards/pteron36/rules.mk index 278246b37134..a12be263511a 100644 --- a/keyboards/pteron36/rules.mk +++ b/keyboards/pteron36/rules.mk @@ -7,7 +7,7 @@ BOOTLOADER = caterina # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE = lite # Enable Bootmagic Lite +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = no # Console for debug From 1e13d07cac92946262be2a8e6e1d497b6e3a6f1c Mon Sep 17 00:00:00 2001 From: Danny Date: Fri, 22 Oct 2021 10:12:35 -0400 Subject: [PATCH 0014/1136] Fix right half of Nyquist in 4x12 mode having row shifted up by one (#14914) --- keyboards/keebio/nyquist/rev3/rev3.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/keyboards/keebio/nyquist/rev3/rev3.h b/keyboards/keebio/nyquist/rev3/rev3.h index 506fcc6e36db..e365c0e41743 100644 --- a/keyboards/keebio/nyquist/rev3/rev3.h +++ b/keyboards/keebio/nyquist/rev3/rev3.h @@ -42,10 +42,12 @@ { L10, L11, L12, L13, L14, L15 }, \ { L20, L21, L22, L23, L24, L25 }, \ { L30, L31, L32, L33, L34, L35 }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \ { R00, R01, R02, R03, R04, R05 }, \ { R10, R11, R12, R13, R14, R15 }, \ { R20, R21, R22, R23, R24, R25 }, \ - { R30, R31, R32, R33, R34, R35 } \ + { R30, R31, R32, R33, R34, R35 }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO } \ } #define LAYOUT_ortho_5x12 LAYOUT From 1953a968c51630cc2badfade9ee54f59c878b422 Mon Sep 17 00:00:00 2001 From: Dasky <32983009+daskygit@users.noreply.github.com> Date: Sat, 23 Oct 2021 05:04:15 +0100 Subject: [PATCH 0015/1136] Check usb transmit status in send_extra() (#14643) --- tmk_core/protocol/chibios/usb_main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index cc282e6a9b44..04049c1a9a30 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -921,6 +921,17 @@ static void send_extra(uint8_t report_id, uint16_t data) { return; } + if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { + /* Need to either suspend, or loop and call unlock/lock during + * every iteration - otherwise the system will remain locked, + * no interrupts served, so USB not going through as well. + * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ + if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { + osalSysUnlock(); + return; + } + } + static report_extra_t report; report = (report_extra_t){.report_id = report_id, .usage = data}; From b9c9f3759a63e4bfd1b2a6f8c3b407426f38ee84 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sat, 23 Oct 2021 05:17:07 +0100 Subject: [PATCH 0016/1136] Remove legacy handling for ErgoDox Infinity handedness (#14919) --- build_keyboard.mk | 14 -------------- keyboards/ergodox_infinity/readme.md | 24 +++++------------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/build_keyboard.mk b/build_keyboard.mk index e5edacfd8a6f..c1f4f93381e4 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -32,20 +32,6 @@ endif # this an empty or blank macro! KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET) -# For split boards we need to set a master half. -MASTER ?= left -ifdef master - MASTER = $(master) -endif - -ifeq ($(MASTER),right) - OPT_DEFS += -DMASTER_IS_ON_RIGHT -else - ifneq ($(MASTER),left) -$(error MASTER does not have a valid value(left/right)) - endif -endif - ifdef SKIP_VERSION OPT_DEFS += -DSKIP_VERSION endif diff --git a/keyboards/ergodox_infinity/readme.md b/keyboards/ergodox_infinity/readme.md index 73ee3bc1df14..c51bdd7c82d5 100644 --- a/keyboards/ergodox_infinity/readme.md +++ b/keyboards/ergodox_infinity/readme.md @@ -13,18 +13,16 @@ for the left and right halves seperately. To flash them: - Install the firmware with `sudo make ergodox_infinity:keymapname:dfu-util` - - Build right hand firmware with `make ergodox_infinity:keymapname MASTER=right` - - Plug in the right hand keyboard only. - Press the program button (back of keyboard, above thumb pad). - - Install the firmware with `sudo make ergodox_infinity:keymapname:dfu-util MASTER=right` + - Install the firmware with `sudo make ergodox_infinity:keymapname:dfu-util` More information on the Infinity firmware is available in the [TMK/chibios for Input Club Infinity Ergodox](https://github.com/fredizzimo/infinity_ergodox/blob/master/README.md) -## Infinity Master/Two Halves +## Infinity Two Halves The Infinity is two completely independent keyboards, that can connect together. You have a few options in how you flash the firmware: @@ -32,21 +30,10 @@ You have a few options in how you flash the firmware: - Add `#define EE_HANDS` to your config.h, initialize the EEPROM values (see below), and then flash the same firmware to both halves. -- Flash the left half, rebuild the firmware with "MASTER=right" and then flash - the right half. This allows you to plug in either half directly to the - computer and is what the above instructions do. - -- Flash the left half, then flash the same firmware on the right. This only - works when the left half is plugged directly to the computer and the keymap - is mirrored. It saves the small extra step of rebuilding with - "MASTER=right". - -- The same as the previous one but with "MASTER=right" when you build the - firmware, then flash the same firmware to both halves. You just have to - directly connect the right half to the computer. +- Flash with the instructions above, which assume the left hand is connected to USB. - For minor changes such as changing only the keymap without having updated - any part of the firmware code itself, you can program only the MASTER half, + any part of the firmware code itself, you can program only the half connected to USB, but it is safest to program both halves. ### EE_HANDS initialization @@ -74,7 +61,6 @@ They only need to be done once, unless you reset the EEPROM later. - Add `#define EE_HANDS` to the config.h file of your keymap, and build your firmware using `make ergodox_infinity:keymapname`. - - After this, you can flash both halves with the same firmware, _without_ having to rebuild with - "MASTER=right" or risking a mirrored keyboard when connected the wrong way. + - After this, you can flash both halves with the same firmware, _without_ risking a mirrored keyboard when connected the wrong way. If you reset your EEPROM later, you'll have to follow these steps again, though. From 8ec1afd17ce1fdc9aa217c1e8ea2e5b5f0decf4b Mon Sep 17 00:00:00 2001 From: TW59420 <40019210+TW59420@users.noreply.github.com> Date: Sat, 23 Oct 2021 13:05:23 +0800 Subject: [PATCH 0017/1136] [Keyboard] Add MW75 support (#14833) --- keyboards/mwstudio/mw75/config.h | 75 ++++++++++++++ keyboards/mwstudio/mw75/info.json | 99 +++++++++++++++++++ .../mwstudio/mw75/keymaps/default/keymap.c | 57 +++++++++++ keyboards/mwstudio/mw75/keymaps/via/keymap.c | 57 +++++++++++ keyboards/mwstudio/mw75/keymaps/via/rules.mk | 2 + keyboards/mwstudio/mw75/mw75.c | 47 +++++++++ keyboards/mwstudio/mw75/mw75.h | 36 +++++++ keyboards/mwstudio/mw75/readme.md | 22 +++++ keyboards/mwstudio/mw75/rules.mk | 24 +++++ keyboards/mwstudio/readme.md | 5 + 10 files changed, 424 insertions(+) create mode 100644 keyboards/mwstudio/mw75/config.h create mode 100644 keyboards/mwstudio/mw75/info.json create mode 100644 keyboards/mwstudio/mw75/keymaps/default/keymap.c create mode 100644 keyboards/mwstudio/mw75/keymaps/via/keymap.c create mode 100644 keyboards/mwstudio/mw75/keymaps/via/rules.mk create mode 100644 keyboards/mwstudio/mw75/mw75.c create mode 100644 keyboards/mwstudio/mw75/mw75.h create mode 100644 keyboards/mwstudio/mw75/readme.md create mode 100644 keyboards/mwstudio/mw75/rules.mk create mode 100644 keyboards/mwstudio/readme.md diff --git a/keyboards/mwstudio/mw75/config.h b/keyboards/mwstudio/mw75/config.h new file mode 100644 index 000000000000..58fcdf2c7c00 --- /dev/null +++ b/keyboards/mwstudio/mw75/config.h @@ -0,0 +1,75 @@ +/* Copyright 2021 TW59420 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "config_common.h" + + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x7BA1 +#define PRODUCT_ID 0x7501 +#define DEVICE_VER 0x0001 +#define MANUFACTURER MWStudio +#define PRODUCT MW75 + +/* key matrix size */ +#define MATRIX_ROWS 7 +#define MATRIX_COLS 15 + +/* key matrix pins */ +#define MATRIX_ROW_PINS { B7, D0, D1, D2, D3, D5, B0} +#define MATRIX_COL_PINS { D4, D6, D7, B4, B5, B6, C6, C7, F7, F6, F5, F4, F1, F0, E6 } + +#define BOOTMAGIC_LITE_ROW 0 +#define BOOTMAGIC_LITE_COLUMN 1 + +/* COL2ROW or ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +#define RGB_DI_PIN B3 +#define RGBLIGHT_SLEEP + +#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 +#define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS +#define DRIVER_LED_TOTAL 97 +#define RGBLED_NUM 97 +#define RGB_MATRIX_KEYPRESSES + +// #define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN +// #define DISABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +// #define DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE +// #define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE +// #define DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS +// #define DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS +// #define DISABLE_RGB_MATRIX_TYPING_HEATMAP +// #define DISABLE_RGB_MATRIX_DIGITAL_RAIN +// #define DISABLE_RGB_MATRIX_BAND_SAT +// #define DISABLE_RGB_MATRIX_BAND_VAL +// #define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT +// #define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL +// #define DISABLE_RGB_MATRIX_BAND_SPIRAL_SAT +// #define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL + +#define RGBLIGHT_HUE_STEP 8 +#define RGBLIGHT_SAT_STEP 8 +#define RGBLIGHT_VAL_STEP 8 + +#define ENCODERS_PAD_A { B1 } +#define ENCODERS_PAD_B { B2 } diff --git a/keyboards/mwstudio/mw75/info.json b/keyboards/mwstudio/mw75/info.json new file mode 100644 index 000000000000..0c53689865bc --- /dev/null +++ b/keyboards/mwstudio/mw75/info.json @@ -0,0 +1,99 @@ +{ + "keyboard_name": "MW75", + "url": "", + "maintainer": "qmk", + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"Esc", "x":0, "y":0}, + {"label":"F1", "x":1.5, "y":0}, + {"label":"F2", "x":2.5, "y":0}, + {"label":"F3", "x":3.5, "y":0}, + {"label":"F4", "x":4.5, "y":0}, + {"label":"F5", "x":6, "y":0}, + {"label":"F6", "x":7, "y":0}, + {"label":"F7", "x":8, "y":0}, + {"label":"F8", "x":9, "y":0}, + {"label":"F9", "x":10.5, "y":0}, + {"label":"F10", "x":11.5, "y":0}, + {"label":"F11", "x":12.5, "y":0}, + {"label":"F12", "x":13.5, "y":0}, + {"label":"DEL", "x":15, "y":0}, + + {"label":"`", "x":0, "y":1.5}, + {"label":"1", "x":1, "y":1.5}, + {"label":"2", "x":2, "y":1.5}, + {"label":"3", "x":3, "y":1.5}, + {"label":"4", "x":4, "y":1.5}, + {"label":"5", "x":5, "y":1.5}, + {"label":"6", "x":6, "y":1.5}, + {"label":"7", "x":7, "y":1.5}, + {"label":"8", "x":8, "y":1.5}, + {"label":"9", "x":9, "y":1.5}, + {"label":"0", "x":10, "y":1.5}, + {"label":"-", "x":11, "y":1.5}, + {"label":"=", "x":12, "y":1.5}, + {"label":"Backspace", "x":13, "y":1.5, "w":2}, + {"label":"Delete", "x":15, "y":1.5}, + + {"label":"Tab", "x":0, "y":2.5, "w":1.5}, + {"label":"Q", "x":1.5, "y":2.5}, + {"label":"W", "x":2.5, "y":2.5}, + {"label":"E", "x":3.5, "y":2.5}, + {"label":"R", "x":4.5, "y":2.5}, + {"label":"T", "x":5.5, "y":2.5}, + {"label":"Y", "x":6.5, "y":2.5}, + {"label":"U", "x":7.5, "y":2.5}, + {"label":"I", "x":8.5, "y":2.5}, + {"label":"O", "x":9.5, "y":2.5}, + {"label":"P", "x":10.5, "y":2.5}, + {"label":"[", "x":11.5, "y":2.5}, + {"label":"]", "x":12.5, "y":2.5}, + {"label":"\\", "x":13.5, "y":2.5, "w":1.5}, + {"label":"PgUp", "x":15, "y":2.5}, + + {"label":"Caps Lock", "x":0, "y":3.5, "w":1.75}, + {"label":"A", "x":1.75, "y":3.5}, + {"label":"S", "x":2.75, "y":3.5}, + {"label":"D", "x":3.75, "y":3.5}, + {"label":"F", "x":4.75, "y":3.5}, + {"label":"G", "x":5.75, "y":3.5}, + {"label":"H", "x":6.75, "y":3.5}, + {"label":"J", "x":7.75, "y":3.5}, + {"label":"K", "x":8.75, "y":3.5}, + {"label":"L", "x":9.75, "y":3.5}, + {"label":";", "x":10.75, "y":3.5}, + {"label":"'", "x":11.75, "y":3.5}, + {"label":"Enter", "x":12.75, "y":3.5, "w":2.25}, + {"label":"PgDn", "x":15, "y":3.5}, + + {"label":"Shift", "x":0, "y":4.5, "w":2.25}, + {"label":"Z", "x":2.25, "y":4.5}, + {"label":"X", "x":3.25, "y":4.5}, + {"label":"C", "x":4.25, "y":4.5}, + {"label":"V", "x":5.25, "y":4.5}, + {"label":"B", "x":6.25, "y":4.5}, + {"label":"N", "x":7.25, "y":4.5}, + {"label":"M", "x":8.25, "y":4.5}, + {"label":",", "x":9.25, "y":4.5}, + {"label":".", "x":10.25, "y":4.5}, + {"label":"/", "x":11.25, "y":4.5}, + {"label":"Shift", "x":12.25, "y":4.5, "w":1.75}, + {"label":"\u2191", "x":14, "y":4.5}, + {"label":"End", "x":15, "y":4.5}, + + {"label":"Ctrl", "x":0, "y":5.5, "w":1.25}, + {"label":"Win", "x":1.25, "y":5.5, "w":1.25}, + {"label":"Alt", "x":2.5, "y":5.5, "w":1.25}, + {"label":"Vol-", "x":3.75, "y":5.5 }, + {"label":"Vol+", "x":4.75, "y":5.5 }, + {"x":5.75, "y":5.5, "w":4.25}, + {"label":"Alt", "x":10, "y":5.5, "w":1.25}, + {"label":"Fn", "x":11.25, "y":5.5, "w":1.25}, + {"label":"\u2190", "x":13, "y":5.5}, + {"label":"\u2193", "x":14, "y":5.5}, + {"label":"\u2192", "x":15, "y":5.5} + ] + } + } +} diff --git a/keyboards/mwstudio/mw75/keymaps/default/keymap.c b/keyboards/mwstudio/mw75/keymaps/default/keymap.c new file mode 100644 index 000000000000..44eb8d0c04ae --- /dev/null +++ b/keyboards/mwstudio/mw75/keymaps/default/keymap.c @@ -0,0 +1,57 @@ +/* Copyright 2021 TW59420 + * + * 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 . + */ + + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, RGB_TOG, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_VOLU, KC_VOLD, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT + ), + + [1] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, + RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUD, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, RGB_SAD, + _______, _______, _______, _______, _______, _______, RGB_MOD, _______, RGB_SPD, RGB_VAD, RGB_SPI + ), + + [2] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + + [3] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/mwstudio/mw75/keymaps/via/keymap.c b/keyboards/mwstudio/mw75/keymaps/via/keymap.c new file mode 100644 index 000000000000..44eb8d0c04ae --- /dev/null +++ b/keyboards/mwstudio/mw75/keymaps/via/keymap.c @@ -0,0 +1,57 @@ +/* Copyright 2021 TW59420 + * + * 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 . + */ + + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, RGB_TOG, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_VOLU, KC_VOLD, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT + ), + + [1] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUI, + RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUD, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, RGB_SAD, + _______, _______, _______, _______, _______, _______, RGB_MOD, _______, RGB_SPD, RGB_VAD, RGB_SPI + ), + + [2] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + + [3] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/mwstudio/mw75/keymaps/via/rules.mk b/keyboards/mwstudio/mw75/keymaps/via/rules.mk new file mode 100644 index 000000000000..36b7ba9cbc98 --- /dev/null +++ b/keyboards/mwstudio/mw75/keymaps/via/rules.mk @@ -0,0 +1,2 @@ +VIA_ENABLE = yes +LTO_ENABLE = yes diff --git a/keyboards/mwstudio/mw75/mw75.c b/keyboards/mwstudio/mw75/mw75.c new file mode 100644 index 000000000000..7e6641d5dbdc --- /dev/null +++ b/keyboards/mwstudio/mw75/mw75.c @@ -0,0 +1,47 @@ +/* Copyright 2021 TW59420 + * + * 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 . + */ + +#include "mw75.h" + +#ifdef RGB_MATRIX_ENABLE +led_config_t g_led_config = { { + { 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67 }, + { 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52 }, + { 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37 }, + { 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, NO_LED, 24, 23 }, + { 22, NO_LED, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9 }, + { 8, 7, 6, NO_LED, NO_LED, NO_LED, 5, NO_LED, NO_LED, NO_LED, 4, 3, 2, 1, 0 }, + { 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96 } +}, { + { 217, 60 }, { 203, 60 }, { 189, 60 }, { 166, 60 }, { 150, 60 }, { 95, 60 }, { 40, 60 }, { 24, 60 }, { 8, 60 }, + { 217, 50 }, { 203, 50 }, { 184, 50 }, { 165, 50 }, { 151, 50 }, { 137, 50 }, { 123, 50 }, { 109, 50 }, { 95, 50 }, { 81, 50 }, { 67, 50 }, { 53, 50 }, { 39, 50 }, { 17, 50 }, + { 217, 40 }, { 195, 40 }, { 172, 40 }, { 158, 40 }, { 144, 40 }, { 130, 40 }, { 116, 40 }, { 102, 40 }, { 88, 40 }, { 74, 40 }, { 60, 40 }, { 46, 40 }, { 32, 40 }, { 13, 40 }, + { 217, 30 }, { 199, 30 }, { 181, 30 }, { 165, 30 }, { 151, 30 }, { 137, 30 }, { 123, 30 }, { 109, 30 }, { 95, 30 }, { 81, 30 }, { 67, 30 }, { 53, 30 }, { 39, 30 }, { 25, 30 }, { 9, 30 }, + { 217, 20 }, { 196, 20 }, { 175, 20 }, { 161, 20 }, { 147, 20 }, { 133, 20 }, { 119, 20 }, { 105, 20 }, { 91, 20 }, { 77, 20 }, { 63, 20 }, { 49, 20 }, { 35, 20 }, { 21, 20 }, { 7, 20 }, + { 217, 5 }, { 196, 5 }, { 182, 5 }, { 168, 5 }, { 154, 5 }, { 133, 5 }, { 119, 5 }, { 105, 5 }, { 91, 5 }, { 70, 5 }, { 56, 5 }, { 42, 5 }, { 28, 5 }, { 7, 5 }, + + { 14, 14 }, { 42, 14 }, { 98, 14 }, { 154, 14 }, { 182, 14 }, { 210, 14 }, { 210, 25 }, { 210, 40 }, + { 210, 55 },{ 182, 55 },{ 126, 55 },{ 98, 55 }, { 42, 55 }, { 14, 55 }, { 14, 40 }, { 14, 25 } +}, { + 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +} }; +#endif diff --git a/keyboards/mwstudio/mw75/mw75.h b/keyboards/mwstudio/mw75/mw75.h new file mode 100644 index 000000000000..a322ed4a1b63 --- /dev/null +++ b/keyboards/mwstudio/mw75/mw75.h @@ -0,0 +1,36 @@ +/* Copyright 2021 TW59420 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + +#define LAYOUT( \ + K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014,\ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114,\ + K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214,\ + K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K313, K314,\ + K400, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K413, K414,\ + K500, K501, K502, K503, K504, K506, K510, K511, K512, K513, K514\ +) { \ + { KC_NO, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 },\ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 },\ + { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214 },\ + { K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, KC_NO, K313, K314 },\ + { K400, KC_NO, K402, K403, K404, K405, K406, K407, K408, K409, K410, K411, K412, K413, K414 },\ + { K500, K501, K502, K503, K504, KC_NO, K506, KC_NO, KC_NO, KC_NO, K510, K511, K512, K513, K514 },\ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO } \ +} diff --git a/keyboards/mwstudio/mw75/readme.md b/keyboards/mwstudio/mw75/readme.md new file mode 100644 index 000000000000..ecabf568aa55 --- /dev/null +++ b/keyboards/mwstudio/mw75/readme.md @@ -0,0 +1,22 @@ +# MW75 + +![MW75](https://i.imgur.com/TdVxYNE.jpg?2) + +Support Atmega32u4 keyboard. + +* Keyboard Maintainer: [TW59420](https://github.com/TW59420) +* Hardware Supported: Atmega32u4 + +Make example for this keyboard (after setting up your build environment): + + make mwstudio/mw75:default + +Flashing example for this keyboard: + + make mwstudio/mw75:default:flash + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +## Bootloader +* **Physical reset button**: Short press the button on the back of the PCB to enter the Bootloader and flash the firmware +* **Keycode in layout**: Press the key mapped to RESET if it is available diff --git a/keyboards/mwstudio/mw75/rules.mk b/keyboards/mwstudio/mw75/rules.mk new file mode 100644 index 000000000000..58d8da3e898b --- /dev/null +++ b/keyboards/mwstudio/mw75/rules.mk @@ -0,0 +1,24 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +RGB_MATRIX_ENABLE = yes +RGB_MATRIX_DRIVER = WS2812 +ENCODER_ENABLE = yes diff --git a/keyboards/mwstudio/readme.md b/keyboards/mwstudio/readme.md new file mode 100644 index 000000000000..d4433a8c9613 --- /dev/null +++ b/keyboards/mwstudio/readme.md @@ -0,0 +1,5 @@ +# MWStudio pcb + +This is a series of PCB +* MW75 The chip is ATmega32U4 + From d71c962b61d638e38a449719401695bdc4fb6257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20A=2E=20Volpato?= Date: Sat, 23 Oct 2021 02:58:52 -0300 Subject: [PATCH 0018/1136] [Keyboard] Update encoder callback on Evolv75 (#14757) Co-authored-by: Ryan --- keyboards/evolv/config.h | 2 ++ keyboards/evolv/evolv.c | 12 +++++------- keyboards/evolv/keymaps/default/keymap.c | 2 ++ keyboards/evolv/keymaps/iso/keymap.c | 2 ++ keyboards/evolv/keymaps/via/keymap.c | 2 ++ keyboards/evolv/mcuconf.h | 4 ---- keyboards/evolv/rules.mk | 6 +++--- 7 files changed, 16 insertions(+), 14 deletions(-) diff --git a/keyboards/evolv/config.h b/keyboards/evolv/config.h index 2b91033c98f0..59223cd2c9dd 100644 --- a/keyboards/evolv/config.h +++ b/keyboards/evolv/config.h @@ -59,6 +59,8 @@ along with this program. If not, see . #define ENCODERS_PAD_A { B3 } #define ENCODERS_PAD_B { A15 } +#define ENCODER_RESOLUTION 2 +#define TAPPING_TERM 200 /* * Feature disable options diff --git a/keyboards/evolv/evolv.c b/keyboards/evolv/evolv.c index 90df449ee204..3f2762894614 100644 --- a/keyboards/evolv/evolv.c +++ b/keyboards/evolv/evolv.c @@ -17,14 +17,12 @@ along with this program. If not, see . #include "evolv.h" +#ifndef MEDIA_KEY_DELAY +# define MEDIA_KEY_DELAY 100 +#endif + bool encoder_update_kb(uint8_t index, bool clockwise) { if (!encoder_update_user(index, clockwise)) return false; - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_VOLU); - } else { - tap_code(KC_VOLD); - } - } + tap_code_delay(clockwise ? KC_VOLU : KC_VOLD, MEDIA_KEY_DELAY); return true; } diff --git a/keyboards/evolv/keymaps/default/keymap.c b/keyboards/evolv/keymaps/default/keymap.c index 5e5e5e7abb63..22866270411e 100755 --- a/keyboards/evolv/keymaps/default/keymap.c +++ b/keyboards/evolv/keymaps/default/keymap.c @@ -17,6 +17,8 @@ along with this program. If not, see . #include QMK_KEYBOARD_H +#define MEDIA_KEY_DELAY 100 + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_evolv_ansi( KC_ESC , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_INS , diff --git a/keyboards/evolv/keymaps/iso/keymap.c b/keyboards/evolv/keymaps/iso/keymap.c index 4efe8268d350..391bcdf5bbf1 100755 --- a/keyboards/evolv/keymaps/iso/keymap.c +++ b/keyboards/evolv/keymaps/iso/keymap.c @@ -17,6 +17,8 @@ along with this program. If not, see . #include QMK_KEYBOARD_H +#define MEDIA_KEY_DELAY 100 + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_evolv_iso( KC_ESC , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_INS , diff --git a/keyboards/evolv/keymaps/via/keymap.c b/keyboards/evolv/keymaps/via/keymap.c index 4efe8268d350..391bcdf5bbf1 100755 --- a/keyboards/evolv/keymaps/via/keymap.c +++ b/keyboards/evolv/keymaps/via/keymap.c @@ -17,6 +17,8 @@ along with this program. If not, see . #include QMK_KEYBOARD_H +#define MEDIA_KEY_DELAY 100 + const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_evolv_iso( KC_ESC , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 , KC_INS , diff --git a/keyboards/evolv/mcuconf.h b/keyboards/evolv/mcuconf.h index 2836e4b01a76..84d14114ff36 100644 --- a/keyboards/evolv/mcuconf.h +++ b/keyboards/evolv/mcuconf.h @@ -23,9 +23,5 @@ #include_next -#undef STM32_I2C_USE_DMA -#define STM32_I2C_USE_DMA FALSE - #undef STM32_SPI_USE_SPI2 #define STM32_SPI_USE_SPI2 TRUE - diff --git a/keyboards/evolv/rules.mk b/keyboards/evolv/rules.mk index 380010c7756f..b0f7124c08ec 100644 --- a/keyboards/evolv/rules.mk +++ b/keyboards/evolv/rules.mk @@ -7,11 +7,11 @@ BOOTLOADER = stm32-dfu # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE = lite # Enable Bootmagic Lite +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = yes # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work From 09daafd4898db3bfb206335b8a33d6ad87c3e58b Mon Sep 17 00:00:00 2001 From: jurassic73 <50930136+jurassic73@users.noreply.github.com> Date: Fri, 22 Oct 2021 23:03:49 -0700 Subject: [PATCH 0019/1136] Corrected keyboard layout which was causing issue in QMK configurator (#14891) --- .../handwired/split89/keymaps/default/keymap.c | 14 +++++++------- keyboards/handwired/split89/split89.h | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/keyboards/handwired/split89/keymaps/default/keymap.c b/keyboards/handwired/split89/keymaps/default/keymap.c index 3b60ef4f6867..5b2ed1740d85 100644 --- a/keyboards/handwired/split89/keymaps/default/keymap.c +++ b/keyboards/handwired/split89/keymaps/default/keymap.c @@ -24,19 +24,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Base */ [0] = LAYOUT( KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, - KC_GRV, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, - KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_Y, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, - KC_CAPS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_H, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSHIFT, KC_UP, - KC_LSFT, KC_LCTL,MO(1),KC_LGUI,KC_LALT,KC_SPACE, KC_N, KC_SPACE, KC_RALT,KC_RGUI, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + KC_GRV,KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, + KC_TAB,KC_Q, KC_W, KC_E, KC_R, KC_T, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_Y, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_H, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSHIFT, KC_UP, + KC_LCTL,MO(1),KC_LGUI,KC_LALT,KC_SPACE, KC_N, KC_SPACE, KC_RALT,KC_RGUI, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT ), /* Volume */ [1] = LAYOUT( KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, - KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, + KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_VOLU, - KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_MEDIA_PLAY_PAUSE, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_MPRV, KC_VOLD, KC_MNXT + KC_TRNS,KC_TRNS, KC_TRNS,KC_TRNS,KC_MEDIA_PLAY_PAUSE, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_MPRV, KC_VOLD, KC_MNXT ), }; diff --git a/keyboards/handwired/split89/split89.h b/keyboards/handwired/split89/split89.h index d04f0296d79a..44c0d0d702f5 100644 --- a/keyboards/handwired/split89/split89.h +++ b/keyboards/handwired/split89/split89.h @@ -28,11 +28,11 @@ */ #define LAYOUT( \ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11, k12, k13, k14, k15, \ - k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k30, k31, \ - k32, k33, k34, k35, k36, k37, k38, k39, k40, k41, k42, k43, k44, k45, k46, k47, \ - k48, k49, k50, k51, k52, k53, k54, k55, k56, k57, k58, k59, k60, \ - k61, k62, k63, k64, k65, k66, k67, k68, k69, k70, k71, k72, k73, \ - k74, k75, k76, k77, k78, k79, k80, k81, k82, k83, k84, k85, k86, k87, k88 \ + k32, k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k30, k31, \ + k48, k33, k34, k35, k36, k37, k38, k39, k40, k41, k42, k43, k44, k45, k46, k47, \ + k61, k49, k50, k51, k52, k53, k54, k55, k56, k57, k58, k59, k60, \ + k74, k62, k63, k64, k65, k66, k67, k68, k69, k70, k71, k72, k73, \ + k75, k76, k77, k78, k79, k80, k81, k82, k83, k84, k85, k86, k87, k88 \ ) \ { \ { KC_NO, KC_NO, KC_NO, KC_NO, k00, k01, k02, k03, k04, k05 }, \ From 443d30682761edf90c327a06a6dbf9badde99df5 Mon Sep 17 00:00:00 2001 From: jonavin <71780717+Jonavin@users.noreply.github.com> Date: Sat, 23 Oct 2021 02:04:08 -0400 Subject: [PATCH 0020/1136] [Keymap] Jonavin userspace keymap updates INVERT_NUMLOCK_INDICATOR (#14880) Co-authored-by: Jonavin <=> --- .../gmmk/pro/ansi/keymaps/jonavin/keymap.c | 17 ++++++--- .../gmmk/pro/ansi/keymaps/jonavin/readme.md | 3 ++ .../gmmk/pro/ansi/keymaps/jonavin/rules.mk | 1 + .../keebio/quefrency/keymaps/jonavin/keymap.c | 13 ++++++- .../quefrency/keymaps/jonavin/readme.md | 1 + .../keebio/quefrency/keymaps/jonavin/rules.mk | 1 + .../mechwild/obe/keymaps/jonavin/keymap.c | 35 +++++++++++-------- .../mechwild/obe/keymaps/jonavin/readme.md | 12 ++++--- .../mechwild/obe/keymaps/jonavin/rules.mk | 1 + users/jonavin/config.h | 1 + users/jonavin/jonavin.c | 12 +++++++ users/jonavin/jonavin.h | 4 +++ users/jonavin/readme.md | 14 +++++++- users/jonavin/rules.mk | 3 ++ 14 files changed, 93 insertions(+), 25 deletions(-) diff --git a/keyboards/gmmk/pro/ansi/keymaps/jonavin/keymap.c b/keyboards/gmmk/pro/ansi/keymaps/jonavin/keymap.c index f37abfac30c3..0d318885f482 100644 --- a/keyboards/gmmk/pro/ansi/keymaps/jonavin/keymap.c +++ b/keyboards/gmmk/pro/ansi/keymaps/jonavin/keymap.c @@ -124,10 +124,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { rgb_matrix_set_color(LED_L1, RGB_GREEN); rgb_matrix_set_color(LED_L2, RGB_GREEN); } - if (!IS_HOST_LED_ON(USB_LED_NUM_LOCK)) { // on if NUM lock is OFF - rgb_matrix_set_color(LED_L3, RGB_MAGENTA); - rgb_matrix_set_color(LED_L4, RGB_MAGENTA); - } + + #ifdef INVERT_NUMLOCK_INDICATOR + if (!IS_HOST_LED_ON(USB_LED_NUM_LOCK)) { // on if NUM lock is OFF + rgb_matrix_set_color(LED_L3, RGB_MAGENTA); + rgb_matrix_set_color(LED_L4, RGB_MAGENTA); + } + #else + if (IS_HOST_LED_ON(USB_LED_NUM_LOCK)) { // Normal, on if NUM lock is ON + rgb_matrix_set_color(LED_L3, RGB_MAGENTA); + rgb_matrix_set_color(LED_L4, RGB_MAGENTA); + } + #endif // INVERT_NUMLOCK_INDICATOR + if (IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { rgb_matrix_set_color(LED_L5, RGB_RED); rgb_matrix_set_color(LED_L6, RGB_RED); diff --git a/keyboards/gmmk/pro/ansi/keymaps/jonavin/readme.md b/keyboards/gmmk/pro/ansi/keymaps/jonavin/readme.md index 2aa910e0c7a9..6e8d6ba8a5ee 100644 --- a/keyboards/gmmk/pro/ansi/keymaps/jonavin/readme.md +++ b/keyboards/gmmk/pro/ansi/keymaps/jonavin/readme.md @@ -44,6 +44,9 @@ TD_LSFT_CAPSLOCK_ENABLE = yes IDLE_TIMEOUT_ENABLE = yes - Enables Timer functionality; for RGB idle timeouts that can be changed dynamically +INVERT_NUMLOCK_INDICATOR + - inverts the Num lock indicator, LED is on when num lokc is off + COLEMAK_LAYER_ENABLE = yes - Enabled optional 5th layer for COLEMAK layout - Use Shift and encoder to enter 5th layer, right led indicator lights up BLUE diff --git a/keyboards/gmmk/pro/ansi/keymaps/jonavin/rules.mk b/keyboards/gmmk/pro/ansi/keymaps/jonavin/rules.mk index 81b84eea7ff0..90ea42dee51e 100644 --- a/keyboards/gmmk/pro/ansi/keymaps/jonavin/rules.mk +++ b/keyboards/gmmk/pro/ansi/keymaps/jonavin/rules.mk @@ -9,3 +9,4 @@ STARTUP_NUMLOCK_ON = yes ENCODER_DEFAULTACTIONS_ENABLE = no COLEMAK_LAYER_ENABLE = yes #Enable Colemak layer / set to no to disable +INVERT_NUMLOCK_INDICATOR = yes diff --git a/keyboards/keebio/quefrency/keymaps/jonavin/keymap.c b/keyboards/keebio/quefrency/keymaps/jonavin/keymap.c index 415f554e2693..81b8497ca251 100644 --- a/keyboards/keebio/quefrency/keymaps/jonavin/keymap.c +++ b/keyboards/keebio/quefrency/keymaps/jonavin/keymap.c @@ -89,6 +89,7 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { enum custom_rgblight_layers { _rgbCAPS, + _rgbNUMLOCK, _rgbWINLOCK, _rgbFN, _rgbNUMPAD, @@ -98,7 +99,9 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { const rgblight_segment_t PROGMEM _rgb_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS( {14, 1, HSV_RED} // Light 4 LEDs, starting with LED 6 ); - const rgblight_segment_t PROGMEM _rgb_winlock_layer[] = RGBLIGHT_LAYER_SEGMENTS( + const rgblight_segment_t PROGMEM _rgb_numlock_layer[] = RGBLIGHT_LAYER_SEGMENTS( + {15, 1, HSV_BLUE} + ); const rgblight_segment_t PROGMEM _rgb_winlock_layer[] = RGBLIGHT_LAYER_SEGMENTS( {13, 1, HSV_PURPLE} // Light 4 LEDs, starting with LED 6 ); const rgblight_segment_t PROGMEM _rgb_fn_layer[] = RGBLIGHT_LAYER_SEGMENTS( @@ -113,6 +116,7 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { const rgblight_segment_t* const PROGMEM _rgb_layers[] = RGBLIGHT_LAYERS_LIST( _rgb_capslock_layer, + _rgb_numlock_layer, _rgb_winlock_layer, _rgb_fn_layer, _rgb_numpad_layer @@ -120,6 +124,13 @@ bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { bool led_update_user(led_t led_state) { rgblight_set_layer_state(_rgbCAPS, led_state.caps_lock); + + #ifdef INVERT_NUMLOCK_INDICATOR + rgblight_set_layer_state(_rgbNUMLOCK, !led_state.num_lock); // inverse numlock indicator override + #else + rgblight_set_layer_state(_rgbNUMLOCK, led_state.num_lock); // normal, light LED when numlock on + #endif // INVERT_NUMLOCK_INDICATOR + rgblight_set_layer_state(_rgbWINLOCK, keymap_config.no_gui); return true; } diff --git a/keyboards/keebio/quefrency/keymaps/jonavin/readme.md b/keyboards/keebio/quefrency/keymaps/jonavin/readme.md index 4833c5b62624..dad817e8ec42 100644 --- a/keyboards/keebio/quefrency/keymaps/jonavin/readme.md +++ b/keyboards/keebio/quefrency/keymaps/jonavin/readme.md @@ -17,6 +17,7 @@ - additional RGB function key binds to arrow on Fn layer - Add capslock indicator, win key lock indicator - Fn and layer 2 indicators using RGB underglow + - Inverted NUM lock indicator (light on when NUM lock is off when INVERT_NUMLOCK_INDICATOR = yes in rules.mk) rules.mk OPTIONS - Active features from userspace STARTUP_NUMLOCK_ON = yes diff --git a/keyboards/keebio/quefrency/keymaps/jonavin/rules.mk b/keyboards/keebio/quefrency/keymaps/jonavin/rules.mk index f27873bb8000..ac2865f60094 100644 --- a/keyboards/keebio/quefrency/keymaps/jonavin/rules.mk +++ b/keyboards/keebio/quefrency/keymaps/jonavin/rules.mk @@ -7,3 +7,4 @@ TAP_DANCE_ENABLE = yes TD_LSFT_CAPSLOCK_ENABLE = yes STARTUP_NUMLOCK_ON = yes +INVERT_NUMLOCK_INDICATOR = yes diff --git a/keyboards/mechwild/obe/keymaps/jonavin/keymap.c b/keyboards/mechwild/obe/keymaps/jonavin/keymap.c index b5b082965811..9e667fba1568 100644 --- a/keyboards/mechwild/obe/keymaps/jonavin/keymap.c +++ b/keyboards/mechwild/obe/keymaps/jonavin/keymap.c @@ -19,7 +19,7 @@ #ifdef RGBLIGHT_ENABLE // Custom RGB Colours - #define RGB_OBE_BOW 0x00, 0xE4, 0xFF // colour for matching keycaps + #define HSV_OBE_BOW 180, 100, 100 // colour for matching keycaps #endif // RGBLIGHT_ENABLE const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { @@ -28,8 +28,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_MUTE, KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL, KC_PGUP, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_PGDN, TT(_RAISE), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, - KC_LSFTCAPSWIN,KC_Z, KC_X, KC_C, KC_V, KC_B, LT(_LOWER,KC_B), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_UP, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN1), LT(_RAISE,KC_SPC), KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + KC_LSFTCAPSWIN,KC_Z, KC_X, KC_C, KC_V, KC_B, LT(_LOWER,KC_B), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_SFTUP,KC_RSFT, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN1), KC_RAISESPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT ), [_FN1] = LAYOUT( KC_NO, KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_INS, @@ -39,18 +39,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TRNS,KC_WINLCK,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_HOME, KC_PGDN, KC_END ), [_LOWER] = LAYOUT( - KC_NO, KC_TILD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_VAD, RGB_VAI, KC_TRNS, KC_DEL, + EEP_RST, KC_TILD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_VAD, RGB_VAI, KC_TRNS, KC_DEL, RGB_HUI, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, EMO_TEARS, EMO_SAD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, RGB_TOG, RGB_HUD, KC_NO, KC_NO, EMO_SHRUG,KC_NO, KC_NO, KC_NO, KC_NO, EMO_JOY, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, - KC_NO, KC_NO, KC_NO, EMO_CONFUSE,KC_NO,KC_NO,KC_TRNS,EMO_NERVOUS,KC_NO, KC_NO, KC_NO, KC_NO, RGB_MOD, KC_TRNS, - KC_TRNS, KC_APP, KC_TRNS, KC_BSPC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_SPD, RGB_RMOD, RGB_SPI + KC_NO, KC_NO, KC_NO, EMO_CONFUSE,KC_NO,KC_NO,KC_TRNS,EMO_NERVOUS, KC_NO, KC_NO, KC_NO, KC_NO, RGB_MOD, KC_TRNS, + KC_TRNS, KC_APP, KC_TRNS, KC_BSPC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_SPD, RGB_RMOD,RGB_SPI ), [_RAISE] = LAYOUT( - KC_NO, KC_TILD, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_P7, KC_P8, KC_P9, KC_P0, KC_PMNS, KC_PPLS, KC_PSLS, KC_DEL, - KC_NO, KC_NO, KC_HOME,KC_UP, KC_END, KC_PGUP, KC_NO, KC_TAB, KC_P4, KC_P5, KC_P6, KC_NO, KC_NO, KC_NO, KC_PEQL, - KC_NO, TT(_RAISE),KC_LEFT,KC_DOWN, KC_RGHT, KC_PGDN, KC_NO, KC_NO, KC_P1, KC_P2, KC_P3, KC_NO, KC_PAST, KC_PENT, + KC_NO, KC_GRV, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_P7, KC_P8, KC_P9, KC_P0, KC_PMNS, KC_PPLS, KC_PSLS, KC_DEL, + KC_VOLU, KC_NO, KC_HOME,KC_UP, KC_END, KC_PGUP, KC_NO, KC_TAB, KC_P4, KC_P5, KC_P6, KC_NO, KC_NO, KC_NO, KC_PEQL, + KC_VOLD,TT(_RAISE),KC_LEFT,KC_DOWN,KC_RGHT, KC_PGDN, KC_NO, KC_NO, KC_P1, KC_P2, KC_P3, KC_NO, KC_PAST, KC_PENT, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_P0, KC_00, KC_NO, KC_PDOT, KC_PSLS, CT_PGUP, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, CT_HOME, CT_PGDN, CT_END + KC_TRNS, KC_TRNS, KC_TRNS, KC_BSPC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, CT_HOME, CT_PGDN, CT_END ) }; @@ -58,8 +58,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { enum custom_rgblight_layers { - _rgbWINLOCK, - _rgbFN, + _rgbWINLOCK, _rgbFN, _rgbLOWER, _rgbRAISE }; @@ -91,7 +90,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { bool led_update_user(led_t led_state) { rgblight_set_layer_state(_rgbWINLOCK, keymap_config.no_gui); - return true; + writePin(LED_CAPS_LOCK_PIN, led_state.caps_lock); + #ifdef INVERT_NUMLOCK_INDICATOR + writePin(LED_NUM_LOCK_PIN, !led_state.num_lock); // inverse numlock indicator override + #else + writePin(LED_NUM_LOCK_PIN, led_state.num_lock); // normal, light LED when numlock on + #endif // INVERT_NUMLOCK_INDICATOR + return false; } layer_state_t layer_state_set_user(layer_state_t state) { @@ -106,8 +111,8 @@ void keyboard_post_init_keymap(void) { // keyboard_post_init_user() moved to userspace #ifdef RGBLIGHT_ENABLE rgblight_enable_noeeprom(); - rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); - rgblight_setrgb(RGB_OBE_BOW); // Default startup colour + rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); + rgblight_sethsv_noeeprom(HSV_OBE_BOW); // Default startup colour rgblight_layers = _rgb_layers; #endif } diff --git a/keyboards/mechwild/obe/keymaps/jonavin/readme.md b/keyboards/mechwild/obe/keymaps/jonavin/readme.md index d60958a4e9e8..f903a36f12c1 100644 --- a/keyboards/mechwild/obe/keymaps/jonavin/readme.md +++ b/keyboards/mechwild/obe/keymaps/jonavin/readme.md @@ -1,9 +1,10 @@ # Jonavin's MechWild Orange Boy Ergo keymap ---> This keymap makes user of user/jonavin userspace +--> This keymap makes use of user/jonavin userspace Features - Split spacebars, Split Backspace + - Inverted Num Lock indicator (LED on when num lock if off) - RGB Winlock indicator (requires LED stripto be installed) - RGB Layer indicators: FN/MO1 - Purple; LOWER/MO2 - Yellow; RAISE/MO3/NumPad - Green - quick demo https://youtu.be/gR1awbsouLk @@ -11,11 +12,12 @@ Features - Add PrtScr, Scroll Lock, Break, NumLock to Fn layer - Implement Win key lock using Fn+Win - Layer 2 (LOWER) when right B is held -- for emoticons -- Layer 2 RGB functions +- Layer 2 RGB functions, and EEPROM Reset - Layer 3 (RAISE) mod on Caps Lock with double-tap to switch to this layer, double tap to switch back - provides arrows on WASD and additional nav keys + right hand numpad with 00; an be used for Alt Code entry - left spacebar Backspace - add double tap of Left Shift to toggle Caps Lock +- Up arrow is also Shift when held rules.mk OPTIONS - Active features from userspace @@ -41,6 +43,8 @@ IDLE_TIMEOUT_ENABLE = yes EMOTICON_ENABLE - adds EMO_ keycodes for text emojis +INVERT_NUMLOCK_INDICATOR + - inverts the Num lock indicator, LED is on when num lokc is off + ## All layers diagram -![image](https://user-images.githubusercontent.com/71780717/135770721-ab263532-f645-4903-99cb-749549944e15.png) - +![image](https://user-images.githubusercontent.com/71780717/137356366-6b23c71b-9499-473e-a1e3-c65644135fc6.png) diff --git a/keyboards/mechwild/obe/keymaps/jonavin/rules.mk b/keyboards/mechwild/obe/keymaps/jonavin/rules.mk index e371b6349843..008d0e1de941 100644 --- a/keyboards/mechwild/obe/keymaps/jonavin/rules.mk +++ b/keyboards/mechwild/obe/keymaps/jonavin/rules.mk @@ -9,3 +9,4 @@ TD_LSFT_CAPSLOCK_ENABLE = yes STARTUP_NUMLOCK_ON = yes ENCODER_DEFAULTACTIONS_ENABLE = yes EMOTICON_ENABLE = yes +INVERT_NUMLOCK_INDICATOR = yes diff --git a/users/jonavin/config.h b/users/jonavin/config.h index 440d222df0c1..7b6e335e3c58 100644 --- a/users/jonavin/config.h +++ b/users/jonavin/config.h @@ -23,6 +23,7 @@ #define GRAVE_ESC_CTRL_OVERRIDE // Always send Escape if Control is pressed #define TAPPING_TERM 180 +#define TAPPING_TERM_PER_KEY #ifdef RGB_MATRIX_ENABLE #define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_SOLID_COLOR diff --git a/users/jonavin/jonavin.c b/users/jonavin/jonavin.c index 1a0760ea8f4f..367601dfbabf 100644 --- a/users/jonavin/jonavin.c +++ b/users/jonavin/jonavin.c @@ -341,6 +341,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { }; +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case KC_SFTUP: + return 300; + case KC_RAISESPC: + case KC_LOWERSPC: + return 450; + default: + return TAPPING_TERM; + } +} + // Turn on/off NUM LOCK if current state is different void activate_numlock(bool turn_on) { if (IS_HOST_LED_ON(USB_LED_NUM_LOCK) != turn_on) { diff --git a/users/jonavin/jonavin.h b/users/jonavin/jonavin.h index feaf6b6a15fb..21b972ed75e3 100644 --- a/users/jonavin/jonavin.h +++ b/users/jonavin/jonavin.h @@ -55,6 +55,10 @@ enum custom_user_keycodes { #define CT_PGDN RCTL(KC_PGDN) #define CT_HOME RCTL(KC_HOME) #define CT_END RCTL(KC_END) +#define KC_SFTUP RSFT_T(KC_UP) // Shift when held, Up arrow when tapped +#define KC_RAISESPC LT(_RAISE,KC_SPC) // _RAISE layer mod when held, space when tapped +#define KC_LOWERSPC LT(_LOWER,KC_SPC) // _LOWER layer mod when held, space when tapped + #ifdef TD_LSFT_CAPSLOCK_ENABLE // Tap Dance Definitions diff --git a/users/jonavin/readme.md b/users/jonavin/readme.md index 9fccb8c73cf6..1b064ddc3cdd 100644 --- a/users/jonavin/readme.md +++ b/users/jonavin/readme.md @@ -32,6 +32,9 @@ KEYCODES: - CT_PGDN Ctrl-PgDn - CT_HOME Ctrl-HOme - CT_END Ctrl-End +- KC_SFTUP RShift when held, Up arrow when tapped +- KC_RAISESPC _RAISE layer mod when held, space when tapped +- KC_LOWERSPC _LOWER layer mod when held, space when tapped - When EMOTICON_ENABLE = yes - EMO_SHRUG `\_("/)_/` @@ -39,6 +42,7 @@ KEYCODES: - EMD_TEARS (T_T) - EMO_NERVOUS (~_~;) - EMO_JOY (^o^) +- EMO_SAD :'-( AVAILABLE ENCODER ACTIONS: @@ -79,7 +83,15 @@ IDLE_TIMEOUT_ENABLE = yes - Enables Timer functionality; for RGB idle timeouts that can be changed dynamically - When enabled, use this in the keymap for an additional matrix processing: void matrix_scan_keymap(void) -- Functions: +EMOTICON_ENABLE +- adds EMO_ keycodes for text emojis + +INVERT_NUMLOCK_INDICATOR +- inverts the Num lock indicator, LED is on when num lock is off + + +FUNCTIONS +------------------------ - u16int_t get_timeout_threshold(void) // returns the current timeout threshold - void timeout_update_threshold(bool increase) // change threshold: true = increase, false = decrease - void timeout_reset_timer(void) // resets timer (put in process_record_user if you override it) diff --git a/users/jonavin/rules.mk b/users/jonavin/rules.mk index eb279f6290b3..646002124713 100644 --- a/users/jonavin/rules.mk +++ b/users/jonavin/rules.mk @@ -17,3 +17,6 @@ endif ifeq ($(strip $(EMOTICON_ENABLE)), yes) OPT_DEFS += -DEMOTICON_ENABLE endif +ifeq ($(strip $(INVERT_NUMLOCK_INDICATOR)), yes) + OPT_DEFS += -DINVERT_NUMLOCK_INDICATOR +endif From bfddc7dfa15555edf0cf36d649ba84413e642c9c Mon Sep 17 00:00:00 2001 From: Ingomancer Date: Sat, 23 Oct 2021 08:15:39 +0200 Subject: [PATCH 0021/1136] Reformat iris keymap antonlindstrom to be a bit more readable and consistent (#14902) Co-authored-by: Ingo Junefjord --- .../iris/keymaps/antonlindstrom/keymap.c | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/keyboards/keebio/iris/keymaps/antonlindstrom/keymap.c b/keyboards/keebio/iris/keymaps/antonlindstrom/keymap.c index ff98545ba31f..3e06ffff2946 100644 --- a/keyboards/keebio/iris/keymaps/antonlindstrom/keymap.c +++ b/keyboards/keebio/iris/keymaps/antonlindstrom/keymap.c @@ -19,17 +19,17 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT( - //,----+----+----+----+----+----. ,----+----+----+----+----+----. - KC_ESC , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,KC_BSPC, - //|----+----+----+----+----+----| |----+----+----+----+----+----| - KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P , SE_ARNG , - //|----+----+----+----+----+----| |----+----+----+----+----+----| - KC_LSFT, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L , SE_ODIA , SE_ADIA , - //|----+----+----+----+----+----+----. ,----|----+----+----+----+----+----| - KC_LCTL, KC_Z , KC_X , KC_C , KC_V , KC_B ,KC_LBR ,KC_RBR , KC_N , KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_MINS, - //`----+----+----+--+-+----+----+----/ \----+----+----+----+----+----+----' - KC_LGUI,KC_LOWR,KC_SPC , KC_ENT ,KC_RASE,KC_LALT - // `----+----+----' `----+----+----' + //,-------+-------+-------+-------+-------+-------. ,-------+-------+-------+-------+-------+-------. + KC_ESC , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 ,KC_BSPC, + //|-------+-------+-------+-------+-------+-------| |-------+-------+-------+-------+-------+-------| + KC_TAB , KC_Q , KC_W , KC_E , KC_R , KC_T , KC_Y , KC_U , KC_I , KC_O , KC_P ,SE_ARNG, + //|-------+-------+-------+-------+-------+-------| |-------+-------+-------+-------+-------+-------| + KC_LSFT, KC_A , KC_S , KC_D , KC_F , KC_G , KC_H , KC_J , KC_K , KC_L ,SE_ODIA,SE_ADIA, + //|-------+-------+-------+-------+-------+-------+-------. ,-------|-------+-------+-------+-------+-------+-------| + KC_LCTL, KC_Z , KC_X , KC_C , KC_V , KC_B ,KC_LBR , KC_RBR , KC_N , KC_M ,KC_COMM,KC_DOT ,KC_SLSH,KC_MINS, + //`-------+-------+-------+--+----+-------+-------+-------/ \-------+-------+-------+-------+-------+-------+-------' + KC_LGUI,KC_LOWR,KC_SPC , KC_ENT ,KC_RASE,KC_LALT + // `-------+-------+-------' `-------+-------+-------' ), [_LOWER] = LAYOUT( From a167a95bd07adfa15c3837fdee9cee507e49ae06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reibl=20J=C3=A1nos=20D=C3=A1niel?= Date: Sat, 23 Oct 2021 08:30:43 +0200 Subject: [PATCH 0022/1136] [Keymap] Simplify unicode input mode change and CTRL and GUI swapping (#14874) --- layouts/community/ortho_5x12/riblee/keymap.c | 12 ++++++------ users/riblee/riblee.c | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/layouts/community/ortho_5x12/riblee/keymap.c b/layouts/community/ortho_5x12/riblee/keymap.c index b34217bff4b7..b72248375981 100644 --- a/layouts/community/ortho_5x12/riblee/keymap.c +++ b/layouts/community/ortho_5x12/riblee/keymap.c @@ -189,17 +189,17 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |------+------+------+------+------+-------------+------+------+------+------+------| * | | |Mu mod|Aud on|AudOff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| HUN |Wrkmn | * |------+------+------+------+------+------|------+------+------+------+------+------| - * | | | | | | | NKRO | Swap |Un swp|UC Mod| | | + * | | | | | | | NKRO | Mac |Linux | | | | * |------+------+------+------+------+------+------+------+------+------+------+------| * | | | | | | | | | | | | * `-----------------------------------------------------------------------------------' */ [_ADJUST] = LAYOUT_ortho_5x12( - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, - _______, RESET, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF,KC_INS, KC_PSCR, KC_DEL, - _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, HUNGARIAN, WORKMAN, - _______, _______, _______, _______, _______, _______, NK_TOGG, LCG_SWP, LCG_NRM, UC_MOD, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + _______, RESET, DEBUG, _______, _______, _______, _______, TERM_ON, TERM_OFF, KC_INS, KC_PSCR, KC_DEL, + _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, HUNGARIAN, WORKMAN, + _______, _______, _______, _______, _______, _______, NK_TOGG, CG_NORM, CG_SWAP, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ) }; \ No newline at end of file diff --git a/users/riblee/riblee.c b/users/riblee/riblee.c index ae3bd7a2b195..6f608f94f592 100644 --- a/users/riblee/riblee.c +++ b/users/riblee/riblee.c @@ -175,6 +175,12 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { } return false; break; + case CG_NORM: + set_unicode_input_mode(UC_MAC); + break; + case CG_SWAP: + set_unicode_input_mode(UC_LNX); + break; } return true; }; From 974e9e0a6b60423aaeb55a32d62f4835aee01a33 Mon Sep 17 00:00:00 2001 From: George Petri Date: Sat, 23 Oct 2021 09:34:05 +0300 Subject: [PATCH 0023/1136] [Keymap] Add Gergoplex keymap (#14768) --- .../gergoplex/keymaps/georgepetri/combos.def | 11 ++ .../gergoplex/keymaps/georgepetri/config.h | 26 +++++ .../keymaps/georgepetri/gergoplex.def | 6 + .../gergoplex/keymaps/georgepetri/keymap.c | 110 ++++++++++++++++++ .../gergoplex/keymaps/georgepetri/readme.md | 6 + .../gergoplex/keymaps/georgepetri/rules.mk | 17 +++ 6 files changed, 176 insertions(+) create mode 100644 keyboards/gboards/gergoplex/keymaps/georgepetri/combos.def create mode 100644 keyboards/gboards/gergoplex/keymaps/georgepetri/config.h create mode 100644 keyboards/gboards/gergoplex/keymaps/georgepetri/gergoplex.def create mode 100644 keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c create mode 100644 keyboards/gboards/gergoplex/keymaps/georgepetri/readme.md create mode 100644 keyboards/gboards/gergoplex/keymaps/georgepetri/rules.mk diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/combos.def b/keyboards/gboards/gergoplex/keymaps/georgepetri/combos.def new file mode 100644 index 000000000000..a9205c028a09 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/combos.def @@ -0,0 +1,11 @@ +// List any combo dictionaries you want loaded to your device below! + +// QMK wide includes +//#include "combos/germ-vim-helpers.def" +#include "combos/germ-mouse-keys.def" + +// User includes +#include "gergoplex.def" + +// Word completion +// #include "combos/eng-combos.def" diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h b/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h new file mode 100644 index 000000000000..a60188ef9008 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/config.h @@ -0,0 +1,26 @@ +/* +Copyright 2012 Jun Wako +Copyright 2013 Oleg Kostyuk + +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 . +*/ + +// Copy and worked on with love from the EZ team + +#pragma once + +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY + +#undef DEBOUNCE +#define DEBOUNCE 25 diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/gergoplex.def b/keyboards/gboards/gergoplex/keymaps/georgepetri/gergoplex.def new file mode 100644 index 000000000000..239d351b707f --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/gergoplex.def @@ -0,0 +1,6 @@ +// Gergoplex specfic combos + +COMB(hjEnt, KC_ENT, KC_H, KC_J) +COMB(loDel, KC_DEL, KC_L, KC_O) +COMB(pscBspace, KC_BSPC, KC_P, KC_SCLN) +COMB(fgEsc, KC_ESC, KC_F, KC_G) diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c b/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c new file mode 100644 index 000000000000..de3bcf67ad17 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/keymap.c @@ -0,0 +1,110 @@ +/* Copyright 2021 Jane Bernhardt + * + * 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 . + */ + +/* Good on you for modifying your layout! if you don't have + * time to read the QMK docs, a list of keycodes can be found at + * https://github.com/qmk/qmk_firmware/blob/master/docs/keycodes.md + */ + +#include QMK_KEYBOARD_H +#include "g/keymap_combo.h" + +enum { + _ALPHA, // default + _SPECIAL, // special characters + _NUMBERS // numbers/function/motion +}; + +#define KC_CTL_A MT(MOD_LCTL, KC_A) // Tap for A, hold for Control +#define KC_SFT_Z MT(MOD_RSFT, KC_Z) // Tap for Z, hold for Shift +#define KC_SFT_SL MT(MOD_RSFT, KC_SLSH) // Tap for slash, hold for Shift + +#define KC_ALT_ENT MT(MOD_LALT, KC_ENT) // Tap for Enter, hold for Alt (Option) +#define KC_SPE_SPC LT(_SPECIAL, KC_SPC) // Tap for Space, hold for Special layer +#define KC_NUM_SPC LT(_NUMBERS, KC_SPC) // Tap for Space, hold for Numbers layer + + /* Combomap + * + * ,-------------------------------. ,-------------------------------. + * | | | | | | | | | | | | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-DEL-+-BSPC--| + * | | | | ESC | | ENT | | | | + * |-------+-----+-----+-RMB-+-LMB-| |-----+-----+-----+-----+-------| + * | | | | | | | | | | | | + * `-------------------------------' `-------------------------------' + * .-----------------. .-----------------. + * | | | | | | | | + * '-----------------' '-----------------' + */ + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Keymap 0: Alpha layer + * + * ,-------------------------------. ,-------------------------------. + * | Q | W | E | R | T | | Y | U | I | O | P | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-----+-------| + * | CTRL A| S | D | F | G | | H | J | K | L | ; | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-----+-------| + * | SHFT Z| X | C | V | B | | N | M | , | . |SHFT / | + * `-------------------------------' `-------------------------------' + * .--------------------------. .----------------------. + * | META | ENT ALT | SPC SPE | | SPC NUM | TAB | SHFT | + * '--------------------------' '----------------------' + */ + [_ALPHA] = LAYOUT_split_3x5_3( + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + KC_CTL_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, + KC_SFT_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, KC_SFT_SL, + KC_LGUI, KC_ALT_ENT, KC_SPE_SPC, KC_NUM_SPC, KC_TAB, KC_RSFT), + + /* Keymap 1: Special characters layer + * + * ,-------------------------------. ,-------------------------------. + * | ! | @ | { | } | | | | ` | - | = | / | \ | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-----+-------| + * | # | $ | ( | ) | | | LFT | DWN | UP | RGT | ' | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-----+-------| + * | % | ^ | [ | ] | | | & | ~ | + | * | | + * `-------------------------------' `-------------------------------' + * .-------------------. .-----------------. + * | | | | | | | | + * '-------------------' '-----------------' + */ + [_SPECIAL] = LAYOUT_split_3x5_3( + KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_GRV, KC_MINS, KC_EQL , KC_SLSH, KC_BSLS, + KC_HASH, KC_DLR, KC_LPRN, KC_RPRN, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, KC_QUOT, + KC_PERC, KC_CIRC, KC_LBRC, KC_RBRC, KC_TRNS, KC_AMPR, KC_TILD, KC_PLUS, KC_ASTR, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), + + /* Keymap 2: Numbers/Function/Motion layer + * + * ,-------------------------------. ,-------------------------------. + * | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-----+-------| + * | F1 | F2 | F3 | F4 | F5 | | | | | | | + * |-------+-----+-----+-----+-----| |-----+-----+-----+-----+-------| + * | F6 | F7 | F8 | F9 | F10 | | MLFT| MDWN| MUP | MRGT| | + * `-------------------------------' `-------------------------------' + * .-----------------. .-----------------. + * | F11 | F12 | | | | | | + * '-----------------' '-----------------' + */ + [_NUMBERS] = LAYOUT_split_3x5_3( + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_TRNS, + KC_F11, KC_F12, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS) +}; diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/readme.md b/keyboards/gboards/gergoplex/keymaps/georgepetri/readme.md new file mode 100644 index 000000000000..7c8a6f202348 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/readme.md @@ -0,0 +1,6 @@ +# George Petri's Gergoplex layout +Vim and programming focused layout. +``` +qmk compile -kb gboards/gergoplex -km georgepetri +qmk flash -kb gboards/gergoplex -km georgepetri +``` diff --git a/keyboards/gboards/gergoplex/keymaps/georgepetri/rules.mk b/keyboards/gboards/gergoplex/keymaps/georgepetri/rules.mk new file mode 100644 index 000000000000..e882b8008db2 --- /dev/null +++ b/keyboards/gboards/gergoplex/keymaps/georgepetri/rules.mk @@ -0,0 +1,17 @@ +#---------------------------------------------------------------------------- +# make gboards/gergoplex:default:flash +# Make sure you have dfu-programmer installed! +#---------------------------------------------------------------------------- + +#Debug options +VERBOSE = no +DEBUG_MATRIX_SCAN_RATE = no +DEBUG_MATRIX = no +CONSOLE_ENABLE = no + +#Combos! +VPATH += keyboards/gboards/ + +ifeq ($(strip $(DEBUG_MATRIX)), yes) + OPT_DEFS += -DDEBUG_MATRIX +endif From ff3989062089fca2778b15432403cf68520ca324 Mon Sep 17 00:00:00 2001 From: ForsakenRei <23041178+ForsakenRei@users.noreply.github.com> Date: Sat, 23 Oct 2021 02:45:07 -0400 Subject: [PATCH 0024/1136] [Docs] Add default case to tap dance example 5. (#14893) --- docs/feature_tap_dance.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/feature_tap_dance.md b/docs/feature_tap_dance.md index 5f413d3a39c9..d1988b9b7d35 100644 --- a/docs/feature_tap_dance.md +++ b/docs/feature_tap_dance.md @@ -393,6 +393,9 @@ void altlp_finished(qk_tap_dance_state_t *state, void *user_data) { case TD_DOUBLE_SINGLE_TAP: // Allow nesting of 2 parens `((` within tapping term tap_code16(KC_LPRN); register_code16(KC_LPRN); + break; + default: + break; } } @@ -406,6 +409,9 @@ void altlp_reset(qk_tap_dance_state_t *state, void *user_data) { break; case TD_DOUBLE_SINGLE_TAP: unregister_code16(KC_LPRN); + break; + default: + break; } } From ec8c1e05af7871b160e1f6c330dc5f7f73d74c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reibl=20J=C3=A1nos=20D=C3=A1niel?= Date: Sun, 24 Oct 2021 00:20:18 +0200 Subject: [PATCH 0025/1136] [Keymap] Add logo to riblee userspace (#14875) --- users/riblee/riblee.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/users/riblee/riblee.c b/users/riblee/riblee.c index 6f608f94f592..04e37b2428a0 100644 --- a/users/riblee/riblee.c +++ b/users/riblee/riblee.c @@ -189,8 +189,29 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { static char receive_buffer[128] = {}; static uint8_t receive_buffer_length = 0; +uint16_t startup_timer; -void oled_task_user(void) { +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + startup_timer = timer_read(); + return rotation; +} + +static void render_logo(void) { + static const char PROGMEM raw_logo[] = { + 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, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 96, 96,240,248,255, 63, 56,255,255,248, 63, 63,248,255,255, 56, 63,255,248,240, 96, 96, 96, 0, 0, 0, 0, 0,252,254, 38, 54, 60, 8,240,152,152,248,240, 24,248,224,248,120,224,240,120, 96,248,248,248,248, 32,248,248, 24, 24,240,248,248,248,240,240,248,152,152,254,254, 0, 0, 0,254,254,152,248,240, 24,248,224,240,120, 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,219,219,219,255,255,255,240,192,143,159, 63, 0, 0, 63,159,143,192,240,255,255,255,219,219,219, 0, 0, 0, 0, 0,192,225,112, 48, 48, 48,112,225,129, 1,240,240,240,193, 1, 0, 1,193,240,240,241, 1, 1,241,240,193,225,112, 48, 0, 1, 1, 1, 1,240,241, 49, 49, 49, 0,240,240, 0,129,193,129,193,192, 0,196,135,193,192,128,128,192,192,128, 0, 0,192,128, 0,128,192,128, 0, 0,192,192,128,128,192,192,192,128, 0,128,192,128,192,192, 0,128,192,192,192,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 6, 6, 15, 31,255,255, 31,255,255, 31,252,252, 31,255,255, 31,255,255, 31, 15, 6, 6, 6, 0, 0, 0, 0, 0, 15, 31, 56, 48, 48, 48, 60,127,103, 96, 63, 63, 0, 7, 63, 56, 31, 7, 0, 63, 63, 0, 0, 63, 63, 7, 30, 60, 48, 0, 0, 0, 0, 0, 63, 31, 3, 3, 3, 0, 63, 63, 0, 31, 63, 1, 0, 0, 0, 63, 31, 0, 1, 63, 63, 0, 0, 63, 63, 0, 7, 63, 60, 63, 7, 31, 60, 63, 15, 0, 28, 60, 54, 54, 63, 63, 0, 63, 63, 1, 0, 0, 31, 63, 54, 54, 55, 55, 2, 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,128,128,128,128,128, 0, 0,192,192,192, 0,192,192,192, 0, 0, 0, 0, 0, 0,192,192,192, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255, 29,127,255,247,224, 0,254,254,254, 0,255,255,255,198,254,254,254, 0, 0,255,255,255,124,254,254,214,214,222,222, 92,124,254,254,214,214,222,222, 92, 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, 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, 0, 0, + }; + + oled_write_raw_P(raw_logo, sizeof(raw_logo)); +} + +static void render_info(void) { // Keyboard Layer Status oled_write_P(PSTR("Layer: "), false); @@ -227,6 +248,19 @@ void oled_task_user(void) { oled_write_ln(receive_buffer, false); } +void oled_task_user(void) { + static bool finished_timer = false; + if (!finished_timer && (timer_elapsed(startup_timer) < 1000)) { + render_logo(); + } else { + if (!finished_timer) { + oled_clear(); + finished_timer = true; + } + render_info(); + } +} + #ifdef RAW_ENABLE void raw_hid_receive(uint8_t *data, uint8_t length) { From 19b9e406dc516da79d96ad72fe4bc20e3ea4a773 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sun, 24 Oct 2021 14:18:57 +0100 Subject: [PATCH 0026/1136] Align usbasp flashing behaviour (#14928) --- platforms/avr/flash.mk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platforms/avr/flash.mk b/platforms/avr/flash.mk index 985cb60e52d1..6d50e72534e1 100644 --- a/platforms/avr/flash.mk +++ b/platforms/avr/flash.mk @@ -130,6 +130,15 @@ avrdude-split-right: $(BUILD_DIR)/$(TARGET).hex check-size cpfirmware $(call EXEC_AVRDUDE,eeprom-righthand.eep) define EXEC_USBASP + if $(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU) -c usbasp 2>&1 | grep -q "could not find USB device with"; then \ + printf "$(MSG_BOOTLOADER_NOT_FOUND_QUICK_RETRY)" ;\ + sleep $(BOOTLOADER_RETRY_TIME) ;\ + until $(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU) -c usbasp 2>&1 | (! grep -q "could not find USB device with"); do\ + printf "." ;\ + sleep $(BOOTLOADER_RETRY_TIME) ;\ + done ;\ + printf "\n" ;\ + fi $(AVRDUDE_PROGRAMMER) -p $(AVRDUDE_MCU) -c usbasp -U flash:w:$(BUILD_DIR)/$(TARGET).hex endef From 6ee29d9aa679ff1d1fe21e712c6015982247990e Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 25 Oct 2021 04:46:20 +1100 Subject: [PATCH 0027/1136] Tidy up ADNS9800 and PMW3360 firmware blobs (#14936) --- drivers/sensors/adns9800.c | 7 +- drivers/sensors/adns9800_srom_A6.h | 3268 ++-------------------------- drivers/sensors/pmw3360.c | 2 +- drivers/sensors/pmw3360_firmware.h | 539 +++-- 4 files changed, 461 insertions(+), 3355 deletions(-) diff --git a/drivers/sensors/adns9800.c b/drivers/sensors/adns9800.c index 36213179f757..17966b81f98a 100644 --- a/drivers/sensors/adns9800.c +++ b/drivers/sensors/adns9800.c @@ -78,8 +78,7 @@ #define US_BEFORE_MOTION 100 #define MSB1 0x80 -extern const uint16_t adns_firmware_length; -extern const uint8_t adns_firmware_data[]; +extern const uint8_t firmware_data[]; void adns_spi_start(void){ spi_start(SPI_SS_PIN, false, SPI_MODE, SPI_DIVISOR); @@ -145,8 +144,8 @@ void adns_init() { // send all bytes of the firmware unsigned char c; - for(int i = 0; i < adns_firmware_length; i++){ - c = (unsigned char)pgm_read_byte(adns_firmware_data + i); + for(int i = 0; i < FIRMWARE_LENGTH; i++){ + c = (unsigned char)pgm_read_byte(firmware_data + i); spi_write(c); wait_us(15); } diff --git a/drivers/sensors/adns9800_srom_A6.h b/drivers/sensors/adns9800_srom_A6.h index f5b3abeb6297..e698a401b949 100644 --- a/drivers/sensors/adns9800_srom_A6.h +++ b/drivers/sensors/adns9800_srom_A6.h @@ -2,3077 +2,201 @@ #include "progmem.h" -const uint16_t adns_firmware_length = 3070; +#define FIRMWARE_LENGTH 3070 -const uint8_t adns_firmware_data[] PROGMEM = { -0x03, -0xa6, -0x68, -0x1e, -0x7d, -0x10, -0x7e, -0x7e, -0x5f, -0x1c, -0xb8, -0xf2, -0x47, -0x0c, -0x7b, -0x74, -0x4b, -0x14, -0x8b, -0x75, -0x66, -0x51, -0x0b, -0x8c, -0x76, -0x74, -0x4b, -0x14, -0xaa, -0xd6, -0x0f, -0x9c, -0xba, -0xf6, -0x6e, -0x3f, -0xdd, -0x38, -0xd5, -0x02, -0x80, -0x9b, -0x82, -0x6d, -0x58, -0x13, -0xa4, -0xab, -0xb5, -0xc9, -0x10, -0xa2, -0xc6, -0x0a, -0x7f, -0x5d, -0x19, -0x91, -0xa0, -0xa3, -0xce, -0xeb, -0x3e, -0xc9, -0xf1, -0x60, -0x42, -0xe7, -0x4c, -0xfb, -0x74, -0x6a, -0x56, -0x2e, -0xbf, -0xdd, -0x38, -0xd3, -0x05, -0x88, -0x92, -0xa6, -0xce, -0xff, -0x5d, -0x38, -0xd1, -0xcf, -0xef, -0x58, -0xcb, -0x65, -0x48, -0xf0, -0x35, -0x85, -0xa9, -0xb2, -0x8f, -0x5e, -0xf3, -0x80, -0x94, -0x97, -0x7e, -0x75, -0x97, -0x87, -0x73, -0x13, -0xb0, -0x8a, -0x69, -0xd4, -0x0a, -0xde, -0xc1, -0x79, -0x59, -0x36, -0xdb, -0x9d, -0xd6, -0xb8, -0x15, -0x6f, -0xce, -0x3c, -0x72, -0x32, -0x45, -0x88, -0xdf, -0x6c, -0xa5, -0x6d, -0xe8, -0x76, -0x96, -0x14, -0x74, -0x20, -0xdc, -0xf4, -0xfa, -0x37, -0x6a, -0x27, -0x32, -0xe3, -0x29, -0xbf, -0xc4, -0xc7, -0x06, -0x9d, -0x58, -0xe7, -0x87, -0x7c, -0x2e, -0x9f, -0x6e, -0x49, -0x07, -0x5d, -0x23, -0x64, -0x54, -0x83, -0x6e, -0xcb, -0xb7, -0x77, -0xf7, -0x2b, -0x6e, -0x0f, -0x2e, -0x66, -0x12, -0x60, -0x55, -0x65, -0xfc, -0x43, -0xb3, -0x58, -0x73, -0x5b, -0xe8, -0x67, -0x04, -0x43, -0x02, -0xde, -0xb3, -0x89, -0xa0, -0x6d, -0x3a, -0x27, -0x79, -0x64, -0x5b, -0x0c, -0x16, -0x9e, -0x66, -0xb1, -0x8b, -0x87, -0x0c, -0x5d, -0xf2, -0xb6, -0x3d, -0x71, -0xdf, -0x42, -0x03, -0x8a, -0x06, -0x8d, -0xef, -0x1d, -0xa8, -0x96, -0x5c, -0xed, -0x31, -0x61, -0x5c, -0xa1, -0x34, -0xf6, -0x8c, -0x08, -0x60, -0x33, -0x07, -0x00, -0x3e, -0x79, -0x95, -0x1b, -0x43, -0x7f, -0xfe, -0xb6, -0xa6, -0xd4, -0x9d, -0x76, -0x72, -0xbf, -0xad, -0xc0, -0x15, -0xe8, -0x37, -0x31, -0xa3, -0x72, -0x63, -0x52, -0x1d, -0x1c, -0x5d, -0x51, -0x1b, -0xe1, -0xa9, -0xed, -0x60, -0x32, -0x3e, -0xa9, -0x50, -0x28, -0x53, -0x06, -0x59, -0xe2, -0xfc, -0xe7, -0x02, -0x64, -0x39, -0x21, -0x56, -0x4a, -0xa5, -0x40, -0x80, -0x81, -0xd5, -0x5a, -0x60, -0x7b, -0x68, -0x84, -0xf1, -0xe0, -0xb1, -0xb6, -0x5b, -0xdf, -0xa8, -0x1d, -0x6d, -0x65, -0x20, -0xc0, -0xa2, -0xb9, -0xd9, -0xbb, -0x00, -0xa6, -0xdb, -0x8b, -0x01, -0x53, -0x91, -0xfe, -0xc4, -0x51, -0x85, -0xb0, -0x96, -0x7f, -0xfd, -0x51, -0xdd, -0x14, -0x03, -0x67, -0x2e, -0x75, -0x1c, -0x76, -0xd3, -0x6e, -0xdd, -0x99, -0x55, -0x76, -0xe5, -0xab, -0x23, -0xfc, -0x4a, -0xd5, -0xc6, -0xe8, -0x2e, -0xca, -0x8a, -0xb3, -0xf6, -0x8c, -0x6c, -0xb0, -0xe9, -0xf2, -0xe7, -0x9e, -0x69, -0x41, -0xed, -0xf1, -0x6d, -0xd2, -0x86, -0xd8, -0x7e, -0xcb, -0x5d, -0x47, -0x6c, -0x85, -0x6a, -0x23, -0xed, -0x20, -0x40, -0x93, -0xb4, -0x20, -0xc7, -0xa5, -0xc9, -0xaf, -0x03, -0x15, -0xac, -0x19, -0xe5, -0x2a, -0x36, -0xdf, -0x6d, -0xc5, -0x8c, -0x80, -0x07, -0xce, -0x92, -0x0c, -0xd8, -0x06, -0x62, -0x0f, -0xdd, -0x48, -0x46, -0x1a, -0x53, -0xc7, -0x8a, -0x8c, -0x5d, -0x5d, -0xb4, -0xa1, -0x02, -0xd3, -0xa9, -0xb8, -0xf3, -0x94, -0x8f, -0x3f, -0xe5, -0x54, -0xd4, -0x11, -0x65, -0xb2, -0x5e, -0x09, -0x0b, -0x81, -0xe3, -0x75, -0xa7, -0x89, -0x81, -0x39, -0x6c, -0x46, -0xf6, -0x06, -0x9f, -0x27, -0x3b, -0xb6, -0x2d, -0x5f, -0x1d, -0x4b, -0xd4, -0x7b, -0x1d, -0x61, -0x74, -0x89, -0xe4, -0xe3, -0xbd, -0x98, -0x1b, -0xc4, -0x51, -0x3b, -0xa4, -0xfa, -0xe0, -0x92, -0xf7, -0xbe, -0xf2, -0x4d, -0xbb, -0xff, -0xad, -0x4f, -0x6d, -0x68, -0xc2, -0x79, -0x40, -0xaa, -0x9b, -0x8f, -0x0c, -0x32, -0x4b, -0x5f, -0x3e, -0xab, -0x59, -0x98, -0xb3, -0xf5, -0x1d, -0xac, -0x5e, -0xbc, -0x78, -0xd3, -0x01, -0x6c, -0x64, -0x15, -0x2f, -0xd8, -0x71, -0xa6, -0x2d, -0x45, -0xe1, -0x22, -0x42, -0xe4, -0x4e, -0x04, -0x3c, -0x7d, -0xf4, -0x40, -0x21, -0xb4, -0x67, -0x05, -0xa8, -0xe2, -0xf3, -0x72, -0x87, -0x4c, -0x7d, -0xd9, -0x1b, -0x65, -0x97, -0xf3, -0xc2, -0xe3, -0xe4, -0xc8, -0xd2, -0xde, -0xf6, -0xef, -0xdc, -0xbb, -0x44, -0x08, -0x5e, -0xe2, -0x45, -0x27, -0x01, -0xb0, -0xf6, -0x43, -0xe7, -0x3a, -0xf6, -0xdc, -0x9d, -0xed, -0xf3, -0xc5, -0x0c, -0xb8, -0x9c, -0x98, -0x3a, -0xd8, -0x36, -0xee, -0x96, -0x72, -0x67, -0xe7, -0x81, -0x91, -0xd5, -0x05, -0x0a, -0xe0, -0x82, -0xd5, -0x8f, -0xe8, -0xf9, -0xb0, -0xc9, -0xcf, -0x93, -0xe7, -0x04, -0xc5, -0xbc, -0x2b, -0x43, -0x56, -0x7e, -0xe8, -0x67, -0x7c, -0xe5, -0xfb, -0x49, -0xad, -0x5e, -0x9f, -0x25, -0x13, -0xde, -0x6e, -0x6e, -0xe9, -0xf1, -0xec, -0x87, -0x0b, -0x59, -0x81, -0x76, -0x84, -0x76, -0xb3, -0x24, -0xaf, -0x30, -0xfd, -0x27, -0x8b, -0xab, -0xd8, -0x00, -0x8b, -0x9b, -0x0c, -0xd2, -0xb2, -0x4e, -0x5e, -0x9d, -0x1d, -0x96, -0x01, -0x00, -0x67, -0xc1, -0x5f, -0x02, -0x20, -0xfd, -0x45, -0x6a, -0x01, -0x60, -0x58, -0x45, -0xca, -0x47, -0x21, -0x90, -0x5a, -0xc4, -0x43, -0x26, -0x1a, -0xd7, -0xa5, -0x4a, -0xb2, -0x5d, -0x2b, -0x35, -0x49, -0xfb, -0xa5, -0x17, -0x92, -0x21, -0x1e, -0x93, -0x96, -0x67, -0xa2, -0x7e, -0x36, -0x7a, -0xde, -0x5f, -0xbe, -0x7a, -0x58, -0x9d, -0xf8, -0x78, -0xa3, -0xfa, -0xc8, -0xd5, -0x17, -0xf0, -0x21, -0x97, -0x8c, -0x80, -0xb5, -0x4b, -0x3b, -0xbd, -0xbb, -0x41, -0x21, -0xa8, -0x50, -0x67, -0xf7, -0xe7, -0x19, -0x80, -0x10, -0x8e, -0xce, -0x04, -0x18, -0x3f, -0x51, -0x6b, -0x77, -0xd8, -0x9e, -0x16, -0xaf, -0xec, -0xef, -0x48, -0x16, -0x4d, -0x9e, -0x85, -0x38, -0x18, -0x3e, -0xd4, -0x28, -0x87, -0x60, -0x2a, -0xf6, -0x7f, -0x09, -0x86, -0x6f, -0x9c, -0x3c, -0x3a, -0xff, -0xab, -0xd0, -0x61, -0xa2, -0x97, -0x0d, -0x71, -0x94, -0x7e, -0xfd, -0xb9, -0x80, -0x02, -0x89, -0x6a, -0xb3, -0x84, -0x6c, -0x2a, -0x77, -0x62, -0xbe, -0x0b, -0xf4, -0xaf, -0xac, -0x7b, -0x7c, -0x8e, -0xca, -0x01, -0xba, -0x71, -0x78, -0x94, -0xfd, -0xb5, -0x39, -0xa4, -0x4d, -0x2f, -0x78, -0xcf, -0xca, -0x92, -0x0c, -0x1a, -0x99, -0x48, -0x4c, -0x11, -0x96, -0xb5, -0x4e, -0x41, -0x28, -0xe4, -0xa6, -0xfe, -0x4b, -0x72, -0x91, -0xe7, -0xd4, -0xdd, -0x9f, -0x12, -0xe6, -0x29, -0x38, -0xce, -0x45, -0xae, -0x02, -0xb8, -0x24, -0xae, -0xbd, -0xe9, -0x66, -0x08, -0x62, -0xa2, -0x2c, -0x2b, -0x00, -0xe2, -0x23, -0xd9, -0xc4, -0x48, -0xe4, -0xd3, -0xac, -0xbb, -0x34, -0xc7, -0xf0, -0xe3, -0x4f, -0xb9, -0x30, -0xea, -0xa2, -0x12, -0xf1, -0x30, -0x2c, -0x36, -0xde, -0x48, -0xf2, -0xb0, -0x4c, -0x43, -0x3f, -0x2e, -0x58, -0xe4, -0x20, -0xe3, -0x58, -0xcd, -0x31, -0x22, -0xf0, -0xa2, -0x2a, -0xe6, -0x19, -0x90, -0x55, -0x86, -0xf6, -0x55, -0x79, -0xd1, -0xd7, -0x46, -0x2f, -0xc0, -0xdc, -0x99, -0xe8, -0xf3, -0x6a, -0xdf, -0x7f, -0xeb, -0x24, -0x4a, -0x1e, -0x5a, -0x75, -0xde, -0x2f, -0x5c, -0x19, -0x61, -0x03, -0x53, -0x54, -0x6a, -0x3b, -0x18, -0x70, -0xb6, -0x4f, -0xf1, -0x9c, -0x0a, -0x59, -0x9d, -0x19, -0x92, -0x65, -0x8c, -0x83, -0x14, -0x2d, -0x44, -0x8a, -0x75, -0xa9, -0xf5, -0x90, -0xd2, -0x66, -0x4e, -0xfa, -0x69, -0x0f, -0x5b, -0x0b, -0x98, -0x65, -0xc8, -0x11, -0x42, -0x59, -0x7f, -0xdd, -0x1b, -0x75, -0x17, -0x31, -0x4c, -0x75, -0x58, -0xeb, -0x58, -0x63, -0x7d, -0xf2, -0xa6, -0xc2, -0x6e, -0xb7, -0x3f, -0x3e, -0x5e, -0x47, -0xad, -0xb7, -0x04, -0xe8, -0x05, -0xf8, -0xb2, -0xcf, -0x19, -0xf3, -0xd2, -0x85, -0xfe, -0x3e, -0x3e, -0xb1, -0x62, -0x08, -0x2c, -0x10, -0x07, -0x0d, -0x73, -0x90, -0x17, -0xfa, -0x9b, -0x56, -0x02, -0x75, -0xf9, -0x51, -0xe0, -0xe9, -0x1a, -0x7b, -0x9f, -0xb3, -0xf3, -0x98, -0xb8, -0x1c, -0x9c, -0xe1, -0xd5, -0x35, -0xae, -0xc8, -0x60, -0x48, -0x11, -0x09, -0x94, -0x6b, -0xd0, -0x8b, -0x15, -0xbc, -0x05, -0x68, -0xd3, -0x54, -0x8a, -0x51, -0x39, -0x5c, -0x42, -0x76, -0xce, -0xd8, -0xad, -0x89, -0x30, -0xc9, -0x05, -0x1c, -0xcc, -0x94, -0x3f, -0x0f, -0x90, -0x6f, -0x72, -0x2d, -0x85, -0x64, -0x9a, -0xb9, -0x23, -0xf9, -0x0b, -0xc3, -0x7c, -0x39, -0x0f, -0x97, -0x07, -0x97, -0xda, -0x58, -0x48, -0x33, -0x05, -0x23, -0xb8, -0x82, -0xe8, -0xd3, -0x53, -0x89, -0xaf, -0x33, -0x80, -0x22, -0x84, -0x0c, -0x95, -0x5c, -0x67, -0xb8, -0x77, -0x0c, -0x5c, -0xa2, -0x5f, -0x3d, -0x58, -0x0f, -0x27, -0xf3, -0x2f, -0xae, -0x48, -0xbd, -0x0b, -0x6f, -0x54, -0xfb, -0x67, -0x4c, -0xea, -0x32, -0x27, -0xf1, -0xfa, -0xe2, -0xb0, -0xec, -0x0b, -0x15, -0xb4, -0x70, -0xf6, -0x5c, -0xdd, -0x71, -0x60, -0xc3, -0xc1, -0xa8, -0x32, -0x65, -0xac, -0x7a, -0x77, -0x41, -0xe5, -0xa9, -0x6b, -0x11, -0x81, -0xfa, -0x34, -0x8d, -0xfb, -0xc1, -0x80, -0x6e, -0xc4, -0x60, -0x30, -0x07, -0xd4, -0x8b, -0x67, -0xbd, -0xaa, -0x8c, -0x9c, -0x64, -0xac, -0xdb, -0x0b, -0x24, -0x8b, -0x63, -0x6f, -0xe6, -0xbc, -0xe7, -0x33, -0xa4, -0x4a, -0x4c, -0xa7, -0x9f, -0x43, -0x53, -0xd2, -0xbb, -0x8f, -0x43, -0xc7, -0x3d, -0x78, -0x68, -0x3f, -0xa5, -0x3d, -0xca, -0x69, -0x84, -0xa6, -0x97, -0x2d, -0xc0, -0x7d, -0x31, -0x34, -0x55, -0x1d, -0x07, -0xb1, -0x5f, -0x40, -0x5c, -0x93, -0xb0, -0xbc, -0x7c, -0xb0, -0xbc, -0xe7, -0x12, -0xee, -0x6b, -0x2b, -0xd3, -0x4d, -0x67, -0x70, -0x3a, -0x9a, -0xf2, -0x3c, -0x7c, -0x81, -0xfa, -0xd7, -0xd9, -0x90, -0x91, -0x81, -0xb8, -0xb1, -0xf3, -0x48, -0x6a, -0x26, -0x4f, -0x0c, -0xce, -0xb0, -0x9e, -0xfd, -0x4a, -0x3a, -0xaf, -0xac, -0x5b, -0x3f, -0xbf, -0x44, -0x5a, -0xa3, -0x19, -0x1e, -0x4b, -0xe7, -0x36, -0x6a, -0xd7, -0x20, -0xae, -0xd7, -0x7d, -0x3b, -0xe7, -0xff, -0x3a, -0x86, -0x2e, -0xd0, -0x4a, -0x3e, -0xaf, -0x9f, -0x8e, -0x01, -0xbf, -0xf8, -0x4f, -0xc1, -0xe8, -0x6f, -0x74, -0xe1, -0x45, -0xd3, -0xf7, -0x04, -0x6a, -0x4b, -0x9d, -0xec, -0x33, -0x27, -0x76, -0xd7, -0xc5, -0xe1, -0xb0, -0x3b, -0x0e, -0x23, -0xec, -0xf0, -0x86, -0xd2, -0x1a, -0xbf, -0x3d, -0x04, -0x62, -0xb3, -0x6c, -0xb2, -0xeb, -0x17, -0x05, -0xa6, -0x0a, -0x8a, -0x7e, -0x83, -0x1c, -0xb6, -0x37, -0x09, -0xc6, -0x0b, -0x70, -0x3c, -0xb5, -0x93, -0x81, -0xd8, -0x93, -0xa0, -0x5f, -0x1e, -0x08, -0xe2, -0xc6, -0xe5, -0xc9, -0x72, -0xf1, -0xf1, -0xc1, -0xed, -0xd5, -0x58, -0x93, -0x83, -0xf8, -0x65, -0x67, -0x2e, -0x0d, -0xa9, -0xf1, -0x64, -0x12, -0xe6, -0x4c, -0xea, -0x15, -0x3f, -0x8c, -0x1a, -0xb6, -0xbf, -0xf6, -0xb9, -0x52, -0x35, -0x09, -0xb0, -0xe6, -0xf7, -0xcd, -0xf1, -0xa5, -0xaa, -0x81, -0xd1, -0x81, -0x6f, -0xb4, -0xa9, -0x66, -0x1f, -0xfc, -0x48, -0xc0, -0xb6, -0xd1, -0x8b, -0x06, -0x2f, -0xf6, -0xef, -0x1f, -0x0a, -0xe6, -0xce, -0x3a, -0x4a, -0x55, -0xbf, -0x6d, -0xf9, -0x4d, -0xd4, -0x08, -0x45, -0x4b, -0xc3, -0x66, -0x19, -0x92, -0x10, -0xe1, -0x17, -0x8e, -0x28, -0x91, -0x16, -0xbf, -0x3c, -0xee, -0xa3, -0xa6, -0x99, -0x92, -0x10, -0xe1, -0xf6, -0xcc, -0xac, -0xb8, -0x65, -0x0b, -0x43, -0x66, -0xf8, -0xe3, -0xe5, -0x3f, -0x24, -0x89, -0x47, -0x5d, -0x78, -0x43, -0xd0, -0x61, -0x17, -0xbd, -0x5b, -0x64, -0x54, -0x08, -0x45, -0x59, -0x93, -0xf6, -0x95, -0x8a, -0x41, -0x51, -0x62, -0x4b, -0x51, -0x02, -0x30, -0x73, -0xc7, -0x87, -0xc5, -0x4b, -0xa2, -0x97, -0x0f, -0xe8, -0x46, -0x5f, -0x7e, -0x2a, -0xe1, -0x30, -0x20, -0xb0, -0xfa, -0xe7, -0xce, -0x61, -0x42, -0x57, -0x6e, -0x21, -0xf3, -0x7a, -0xec, -0xe3, -0x25, -0xc7, -0x25, -0xf3, -0x67, -0xa7, -0x57, -0x40, -0x00, -0x02, -0xcf, -0x1c, -0x80, -0x77, -0x67, -0xbd, -0x70, -0xa1, -0x19, -0x92, -0x31, -0x75, -0x93, -0x27, -0x27, -0xb6, -0x82, -0xe4, -0xeb, -0x1d, -0x78, -0x48, -0xe7, -0xa5, -0x5e, -0x57, -0xef, -0x64, -0x28, -0x64, -0x1b, -0xf6, -0x11, -0xb2, -0x03, -0x9d, -0xb9, -0x18, -0x02, -0x27, -0xf7, -0xbe, -0x9d, -0x55, -0xfc, -0x00, -0xd2, -0xc7, -0xae, -0xad, -0x0b, -0xc5, -0xe9, -0x42, -0x41, -0x48, -0xd8, -0x32, -0xcf, -0xf6, -0x0f, -0xf5, -0xbc, -0x97, -0xc6, -0x99, -0x47, -0x76, -0xbd, -0x89, -0x06, -0x0f, -0x63, -0x0c, -0x51, -0xd4, -0x5e, -0xea, -0x48, -0xa8, -0xa2, -0x56, -0x1c, -0x79, -0x84, -0x86, -0x40, -0x88, -0x41, -0x76, -0x55, -0xfc, -0xc2, -0xd7, -0xfd, -0xc9, -0xc7, -0x80, -0x61, -0x35, -0xa7, -0x43, -0x20, -0xf7, -0xeb, -0x6c, -0x66, -0x13, -0xb0, -0xec, -0x02, -0x75, -0x3e, -0x4b, -0xaf, -0xb9, -0x5d, -0x40, -0xda, -0xd6, -0x6e, -0x2d, -0x39, -0x54, -0xc2, -0x95, -0x35, -0x54, -0x25, -0x72, -0xe1, -0x78, -0xb8, -0xeb, -0xc1, -0x16, -0x58, -0x0f, -0x9c, -0x9b, -0xb4, -0xea, -0x37, -0xec, -0x3b, -0x11, -0xba, -0xd5, -0x8a, -0xa9, -0xe3, -0x98, -0x00, -0x51, -0x1c, -0x14, -0xe0, -0x40, -0x96, -0xe5, -0xe9, -0xf2, -0x21, -0x22, -0xb1, -0x23, -0x60, -0x78, -0xd3, -0x17, -0xf8, -0x7a, -0xa5, -0xa8, -0xba, -0x20, -0xd3, -0x15, -0x1e, -0x32, -0xe4, -0x5e, -0x15, -0x48, -0xae, -0xa9, -0xe5, -0xb8, -0x33, -0xec, -0xe8, -0xa2, -0x42, -0xac, -0xbf, -0x10, -0x84, -0x53, -0x87, -0x19, -0xb4, -0x5f, -0x76, -0x4d, -0x01, -0x9d, -0x56, -0x74, -0xd9, -0x5c, -0x97, -0xe7, -0x88, -0xea, -0x3a, -0xbf, -0xdc, -0x4c, -0x33, -0x8a, -0x16, -0xb9, -0x5b, -0xfa, -0xd8, -0x42, -0xa7, -0xbb, -0x3c, -0x04, -0x27, -0x78, -0x49, -0x81, -0x2a, -0x5a, -0x7d, -0x7c, -0x23, -0xa8, -0xba, -0xf7, -0x9a, -0x9f, -0xd2, -0x66, -0x3e, -0x38, -0x3c, -0x75, -0xf9, -0xd1, -0x30, -0x26, -0x30, -0x6e, -0x5a, -0x6e, -0xdc, -0x6a, -0x69, -0x32, -0x50, -0x33, -0x47, -0x9e, -0xa4, -0xa8, -0x64, -0x66, -0xf0, -0x8a, -0xe4, -0xfd, -0x27, -0x6f, -0x51, -0x25, -0x8b, -0x43, -0x74, -0xc9, -0x8e, -0xbd, -0x88, -0x31, -0xbe, -0xec, -0x65, -0xd2, -0xcb, -0x8d, -0x5a, -0x13, -0x48, -0x16, -0x8c, -0x61, -0x0b, -0x11, -0xf6, -0xc6, -0x66, -0xae, -0xc3, -0xcc, -0x0c, -0xd2, -0xe1, -0x9f, -0x82, -0x41, -0x3f, -0x56, -0xf9, -0x73, -0xef, -0xdc, -0x30, -0x50, -0xcf, -0xb6, -0x7f, -0xbc, -0xd0, -0xb3, -0x10, -0xab, -0x24, -0xe4, -0xec, -0xad, -0x18, -0x8c, -0x39, -0x2d, -0x30, -0x4c, -0xc5, -0x40, -0x0d, -0xf6, -0xac, -0xd6, -0x18, -0x5d, -0x96, -0xbf, -0x5f, -0x71, -0x75, -0x96, -0x22, -0x97, -0x0f, -0x02, -0x94, -0x6e, -0xa6, -0xae, -0x6d, -0x8f, -0x1e, -0xca, -0x12, -0x9b, -0x2a, -0x1c, -0xce, -0xa9, -0xee, -0xfd, -0x12, -0x8e, -0xfc, -0xed, -0x09, -0x33, -0xba, -0xf4, -0x1a, -0x15, -0xf6, -0x9d, -0x87, -0x16, -0x43, -0x7c, -0x78, -0x57, -0xe1, -0x44, -0xc9, -0xeb, -0x1f, -0x58, -0x4d, -0xc1, -0x49, -0x11, -0x5c, -0xb2, -0x11, -0xa8, -0x55, -0x16, -0xf1, -0xc6, -0x50, -0xe9, -0x87, -0x89, -0xf6, -0xcf, -0xd8, -0x9c, -0x51, -0xa7, -0xbc, -0x5b, -0x31, -0x6d, -0x4d, -0x51, -0xd0, -0x4c, -0xbc, -0x0d, -0x58, -0x2d, -0x7b, -0x88, -0x7a, -0xf9, -0x8e, -0xd6, -0x40, -0x4d, -0xbb, -0xbe, -0xc4, -0xe5, -0x07, -0xfc, -0xd9, -0x7b, -0x6d, -0xa6, -0x42, -0x57, -0x8f, -0x02, -0x94, -0x4f, -0xe4, -0x2a, -0x65, -0xe2, -0x19, -0x5a, -0x50, -0xe1, -0x25, -0x65, -0x4a, -0x60, -0xc2, -0xcd, -0xa8, -0xec, -0x05, -0x2e, -0x87, -0x7b, -0x95, -0xb7, -0x4f, -0xa0, -0x0b, -0x1b, -0x4a, -0x7f, -0x92, -0xc8, -0x90, -0xee, -0x89, -0x1e, -0x10, -0xd2, -0x85, -0xe4, -0x9f, -0x63, -0xc8, -0x12, -0xbb, -0x4e, -0xb8, -0xcf, -0x0a, -0xec, -0x18, -0x4e, -0xe6, -0x7c, -0xb3, -0x33, -0x26, -0xc7, -0x1f, -0xd2, -0x04, -0x23, -0xea, -0x07, -0x0c, -0x5f, -0x90, -0xbd, -0xa7, -0x6a, -0x0f, -0x4a, -0xd6, -0x10, -0x01, -0x3c, -0x12, -0x29, -0x2e, -0x96, -0xc0, -0x4d, -0xbb, -0xbe, -0xe5, -0xa7, -0x83, -0xd5, -0x6a, -0x3c, -0xe3, -0x5b, -0xb8, -0xf2, -0x5c, -0x6d, -0x1f, -0xa6, -0xf3, -0x12, -0x24, -0xf6, -0xd6, -0x3b, -0x10, -0x14, -0x09, -0x07, -0x82, -0xe8, -0x30, -0x6a, -0x99, -0xdc, -0x95, -0x01, -0x9c, -0xd4, -0x68, -0x3b, -0xca, -0x98, -0x12, -0xab, -0x77, -0x25, -0x15, -0x7d, -0x10, -0x32, -0x45, -0x98, -0xcd, -0x7a, -0xdf, -0x71, -0x8a, -0x75, -0xc1, -0x1c, -0xd4, -0x68, -0x25, -0xeb, -0xbb, -0x54, -0x27, -0x6f, -0x2a, -0xf7, -0xb9, -0x98, -0x03, -0x27, -0xde, -0x24, -0xa8, -0xbb, -0x98, -0xc2, -0x84, -0xff, -0x9b, -0x51, -0xd8, -0x53, -0x50, -0xda, -0xf5, -0x88, -0xaa, -0x87, -0x2f, -0xae, -0xd6, -0xea, -0x6b, -0xde, -0xc8, -0xd7, -0xa7, -0x28, -0x65, -0x81, -0xe8, -0xb2, -0x3b, -0x1d, -0x4f, -0x75, -0x8f, -0x9f, -0x7a, -0x74, -0x8e, -0xc1, -0x5f, -0x9a, -0xa8, -0x9d, -0xfa, -0x03, -0xa3, -0x71, -0x9b, -0x37, -0x6d, -0xd5, -0x0b, -0xf5, -0xe1, -0xa1, -0x1b, -0x01, -0x6a, -0xc6, -0x67, -0xaa, -0xea, -0x2c, -0x9d, -0xa4, -0xd2, -0x6e, -0xfc, -0xde, -0x2e, -0x7f, -0x94, -0x69, -0xe5, -0x4a, -0xe0, -0x01, -0x48, -0x3c, -0x6b, -0xf7, -0x1e, -0xb6, -0x0b, -0x5f, -0xf9, -0x2e, -0x07, -0xc5, -0xe8, -0xae, -0x37, -0x1b, -0xbc, -0x3c, -0xd8, -0xd5, -0x0b, -0x91, -0x9e, -0x80, -0x24, -0xf5, -0x06, -0x0c, -0x0e, -0x98, -0x07, -0x96, -0x2d, -0x19, -0xdc, -0x58, -0x93, -0xcc, -0xfb, -0x4e, -0xeb, -0xbd, -0x0f, -0xf5, -0xaf, -0x01, -0xfa, -0xf1, -0x7c, -0x43, -0x8c, -0xb8, -0x56, -0x3e, -0xbe, -0x77, -0x4e, -0x2b, -0xf7, -0xbb, -0xb7, -0x45, -0x47, -0xcd, -0xcc, -0xa6, -0x4c, -0x72, -0x7b, -0x6a, -0x2a, -0x70, -0x13, -0x07, -0xfd, -0xb8, -0x9c, -0x98, -0x3a, -0xd8, -0x23, -0x67, -0x5b, -0x34, -0xd5, -0x14, -0x0c, -0xab, -0x77, -0x1f, -0xf8, -0x3d, -0x5a, -0x9f, -0x92, -0xb7, -0x2c, -0xad, -0x31, -0xde, -0x61, -0x07, -0xb3, -0x6b, -0xf7, -0x38, -0x15, -0x95, -0x46, -0x14, -0x48, -0x53, -0x69, -0x52, -0x66, -0x07, -0x6d, -0x83, -0x71, -0x8a, -0x67, -0x25, -0x20, -0x0f, -0xfe, -0xd7, -0x02, -0xd7, -0x6e, -0x2c, -0xd2, -0x1a, -0x0a, -0x5d, -0xfd, -0x0f, -0x74, -0xe3, -0xa4, -0x36, -0x07, -0x9a, -0xdf, -0xd4, -0x79, -0xbf, -0xef, -0x59, -0xc0, -0x44, -0x52, -0x87, -0x9a, -0x6e, -0x1d, -0x0e, -0xee, -0xde, -0x2e, -0x1a, -0xa9, -0x8f, -0x3a, -0xc9, -0xba, -0xec, -0x99, -0x78, -0x2d, -0x55, -0x6b, -0x14, -0xc2, -0x06, -0xd5, -0xfc, -0x93, -0x53, -0x4d, -0x11, -0x8c, -0xf8, -0xfa, -0x79, -0x7c, -0xa6, -0x64, -0xae, -0x61, -0xb8, -0x7b, -0x94, -0x56, -0xa6, -0x39, -0x78, -0x9a, -0xe5, -0xc7, -0xdf, -0x18, -0x63, -0x23, -0x9c, -0xfa, -0x66, -0xbb, -0xb7, -0x5a, -0x27, -0x4c, -0xd1, -0xa1, -0x83, -0x22, -0xb3, -0x52, -0x49, -0x35, -0xb0, -0x22, -0x83, -0x59, -0x12, -0x00, -0x16, -0x98, -0xdd, -0xad, -0xc2, -0x94, -0xf9, -0xd3, -0x7b, -0x64, -0x7f, -0x44, -0x3e, -0x3c, -0x8b, -0x9a, -0x83, -0x9c, -0x69, -0x6b, -0xe4, -0xdf, -0x9f, -0xed, -0x54, -0x1f, -0xe5, -0x5d, -0x7a, -0x05, -0x82, -0xb3, -0xdd, -0xef, -0xfc, -0x53, -0x96, -0xb0, -0x2c, -0x5a, -0xf8, -0xdf, -0x9c, -0x8b, -0x16, -0x4e, -0xdf, -0xda, -0x4d, -0x09, -0x09, -0x69, -0x50, -0x03, -0x65, -0xd8, -0x73, -0x70, -0xe8, -0x86, -0xbf, -0xbb, -0x35, -0xce, -0xb2, -0x46, -0xcb, -0x02, -0x00, -0x5b, -0xb4, -0xe2, -0xc6, -0x8f, -0x2f, -0x98, -0xaf, -0x87, -0x4b, -0x48, -0x45, -0xed, -0xcc, -0x1d, -0xe6, -0x58, -0xd6, -0xf2, -0x50, -0x25, -0x9f, -0x52, -0xc7, -0xcb, -0x8a, -0x17, -0x9d, -0x5b, -0xe5, -0xc8, -0xd7, -0x72, -0xb7, -0x52, -0xb2, -0xc4, -0x98, -0xe3, -0x7a, -0x17, -0x3e, -0xc6, -0x60, -0xa7, -0x97, -0xb0, -0xcf, -0x18, -0x81, -0x53, -0x84, -0x4c, -0xd5, -0x17, -0x32, -0x03, -0x13, -0x39, -0x51, -0x09, -0x10, -0xe3, -0x77, -0x49, -0x4f, -0x62, -0x01, -0xbf, -0x8c, -0x9a, -0xe0, -0x41, -0x9e, -0x89, -0x74, -0x36, -0xf9, -0x96, -0x86, -0x2e, -0x96, -0x1c, -0x4a, -0xb7, -0x2b, -0x4a, -0x97, -0xbc, -0x99, -0x40, -0xa3, -0xe0, -0x3d, -0xc8, -0xad, -0x2f, -0xdf, -0x4f, -0x2c, -0xc4, -0x69, -0x82, -0x9f, -0x9b, -0x81, -0x0c, -0x61, -0x5c, -0xa5, -0x9d, -0x8c, -0x89, -0xc0, -0x2c, -0xb4, -0x4a, -0x33, -0x4e, -0xeb, -0xa2, -0x56, -0x40, -0xc0, -0xc2, -0x46, -0xaf, -0x6a, -0xfc, -0x67, -0xd1, -0x80, -0x5e, -0xc5, -0x6d, -0x84, -0x43, -0x27, -0x3f, -0x55, -0x15, -0x96, -0x6a, -0xa0, -0xa5, -0xda, -0xb7, -0xff, -0xb7, -0x75, -0x6e, -0x4c, -0x49, -0x91, -0x9d, -0x22, -0xa3, -0x46, -0xea, -0xed, -0x9a, -0x00, -0xe2, -0x32, -0xc3, -0xd6, -0xa9, -0x71, -0x20, -0x55, -0xa3, -0x19, -0xed, -0xf8, -0x4f, -0xa7, -0x12, -0x9c, -0x66, -0x87, -0xaf, -0x4e, -0xb7, -0xf0, -0xdb, -0xbf, -0xef, -0xf0, -0xf6, -0xaf, -0xea, -0xda, -0x09, -0xfe, -0xde, -0x38, -0x5c, -0xa5, -0xa2, -0xdf, -0x99, -0x45, -0xa8, -0xe4, -0xe7, -0x92, -0xac, -0x67, -0xaa, -0x4f, -0xbf, -0x77, -0x3e, -0xa2, -0x40, -0x49, -0x22, -0x4a, -0x1e, -0x3b, -0xaa, -0x70, -0x7f, -0x95, -0xaf, -0x37, -0x4b, -0xfc, -0x99, -0xe2, -0xe0, -0xba, -0xd7, -0x34, -0xce, -0x55, -0x88, -0x5b, -0x84, -0x1b, -0x57, -0xc4, -0x80, -0x03, -0x53, -0xc9, -0x2f, -0x93, -0x04, -0x4d, -0xd5, -0x96, -0xe5, -0x70, -0xa6, -0x6e, -0x63, -0x5d, -0x9d, -0x6c, -0xdb, -0x02, -0x0a, -0xa9, -0xda, -0x8b, -0x53, -0xdc, -0xd9, -0x9a, -0xc5, -0x94, -0x2c, -0x91, -0x92, -0x2a, -0xde, -0xbb, -0x8b, -0x13, -0xb9, -0x19, -0x96, -0x64, -0xcc, -0xf2, -0x64, -0x39, -0xb7, -0x75, -0x49, -0xe9, -0x86, -0xc2, -0x86, -0x62, -0xd9, -0x24, -0xd3, -0x81, -0x35, -0x49, -0xfc, -0xa0, -0xa5, -0xa0, -0x93, -0x05, -0x64, -0xb4, -0x1a, -0x57, -0xce, -0x0c, -0x90, -0x02, -0x27, -0xc5, -0x7a, -0x2b, -0x5d, -0xae, -0x3e, -0xd5, -0xdd, -0x10, -0x7c, -0x14, -0xea, -0x3a, -0x08, -0xac, -0x72, -0x4e, -0x90, -0x3d, -0x3b, -0x7c, -0x86, -0x2e, -0xeb, -0xd4, -0x06, -0x70, -0xe6, -0xc7, -0xfb, -0x5f, -0xbd, -0x18, -0xf4, -0x11, -0xa4, -0x1a, -0x93, -0xc3, -0xbe, -0xd9, -0xfb, -0x26, -0x48, -0x2f, -0x37, -0x3c, -0xd0, -0x03, -0x47, -0x1a, -0xf7, -0x62, -0x19, -0x24, -0x5c, -0xf4, -0xa8, -0x92, -0x20, -0x7a, -0xf2, -0x9e, -0x2a, -0xc5, -0x95, -0xa2, -0xfb, -0xa4, -0xea, -0x85, -0xd8, -0x56, -0xb7, -0x70, -0xd1, -0x60, -0x30, -0xa5, -0x30, -0x82, -0x70, -0xdc, -0x7a, -0x65, -0x8a, -0x36, -0x3f, -0x5b, -0x0c, -0xae, -0x54, -0x7c, -0xd3, -0x57, -0x84, -0x7b, -0x3a, -0x65, -0x18, -0x81, -0xee, -0x05, -0x9b, -0x44, -0x4d, -0xb8, -0xda, -0xa2, -0xa1, -0xc9, -0x15, -0xd3, -0x73, -0x03, -0x0e, -0x43, -0xe9, -0x8e, -0x15, -0xf9, -0xbe, -0xc6, -0xc5, -0x8a, -0xe5, -0xc0, -0x1e, -0xc2, -0x37, -0x9e, -0x2a, -0x26, -0xa5, -0xa0, -0xbd, -0x24, -0x5f, -0xb9, -0xc1, -0xab, -0x34, -0x48, -0xb9, -0x5d, -0x98, -0xb4, -0x65, -0x18, -0xf3, -0x63, -0x19, -0x44, -0x1b, -0x11, -0x16, -0xff, -0xdc, -0xf1, -0x79, -0x08, -0x86, -0x0f, -0x52, -0x98, -0x73, -0xc4, -0x92, -0x90, -0x2b, -0x47, -0x09, -0xd0, -0x43, -0x6c, -0x2f, -0x20, -0xeb, -0xdc, -0xda, -0xc5, -0x08, -0x7b, -0x94, -0x42, -0x30, -0x6a, -0xc7, -0xda, -0x8c, -0xc3, -0x76, -0xa7, -0xa5, -0xcc, -0x62, -0x13, -0x00, -0x60, -0x31, -0x58, -0x44, -0x9b, -0xf5, -0x64, -0x14, -0xf5, -0x11, -0xc5, -0x54, -0x52, -0x83, -0xd4, -0x73, -0x01, -0x16, -0x0e, -0xb3, -0x7a, -0x29, -0x69, -0x35, -0x56, -0xd4, -0xee, -0x8a, -0x17, -0xa2, -0x99, -0x24, -0x9c, -0xd7, -0x8f, -0xdb, -0x55, -0xb5, -0x3e +// clang-format off + +const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = { + 0x03, 0xA6, 0x68, 0x1E, 0x7D, 0x10, 0x7E, 0x7E, 0x5F, 0x1C, 0xB8, 0xF2, 0x47, 0x0C, 0x7B, 0x74, + 0x4B, 0x14, 0x8B, 0x75, 0x66, 0x51, 0x0B, 0x8C, 0x76, 0x74, 0x4B, 0x14, 0xAA, 0xD6, 0x0F, 0x9C, + 0xBA, 0xF6, 0x6E, 0x3F, 0xDD, 0x38, 0xD5, 0x02, 0x80, 0x9B, 0x82, 0x6D, 0x58, 0x13, 0xA4, 0xAB, + 0xB5, 0xC9, 0x10, 0xA2, 0xC6, 0x0A, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xCE, 0xEB, 0x3E, 0xC9, + 0xF1, 0x60, 0x42, 0xE7, 0x4C, 0xFB, 0x74, 0x6A, 0x56, 0x2E, 0xBF, 0xDD, 0x38, 0xD3, 0x05, 0x88, + 0x92, 0xA6, 0xCE, 0xFF, 0x5D, 0x38, 0xD1, 0xCF, 0xEF, 0x58, 0xCB, 0x65, 0x48, 0xF0, 0x35, 0x85, + 0xA9, 0xB2, 0x8F, 0x5E, 0xF3, 0x80, 0x94, 0x97, 0x7E, 0x75, 0x97, 0x87, 0x73, 0x13, 0xB0, 0x8A, + 0x69, 0xD4, 0x0A, 0xDE, 0xC1, 0x79, 0x59, 0x36, 0xDB, 0x9D, 0xD6, 0xB8, 0x15, 0x6F, 0xCE, 0x3C, + 0x72, 0x32, 0x45, 0x88, 0xDF, 0x6C, 0xA5, 0x6D, 0xE8, 0x76, 0x96, 0x14, 0x74, 0x20, 0xDC, 0xF4, + 0xFA, 0x37, 0x6A, 0x27, 0x32, 0xE3, 0x29, 0xBF, 0xC4, 0xC7, 0x06, 0x9D, 0x58, 0xE7, 0x87, 0x7C, + 0x2E, 0x9F, 0x6E, 0x49, 0x07, 0x5D, 0x23, 0x64, 0x54, 0x83, 0x6E, 0xCB, 0xB7, 0x77, 0xF7, 0x2B, + 0x6E, 0x0F, 0x2E, 0x66, 0x12, 0x60, 0x55, 0x65, 0xFC, 0x43, 0xB3, 0x58, 0x73, 0x5B, 0xE8, 0x67, + 0x04, 0x43, 0x02, 0xDE, 0xB3, 0x89, 0xA0, 0x6D, 0x3A, 0x27, 0x79, 0x64, 0x5B, 0x0C, 0x16, 0x9E, + 0x66, 0xB1, 0x8B, 0x87, 0x0C, 0x5D, 0xF2, 0xB6, 0x3D, 0x71, 0xDF, 0x42, 0x03, 0x8A, 0x06, 0x8D, + 0xEF, 0x1D, 0xA8, 0x96, 0x5C, 0xED, 0x31, 0x61, 0x5C, 0xA1, 0x34, 0xF6, 0x8C, 0x08, 0x60, 0x33, + 0x07, 0x00, 0x3E, 0x79, 0x95, 0x1B, 0x43, 0x7F, 0xFE, 0xB6, 0xA6, 0xD4, 0x9D, 0x76, 0x72, 0xBF, + 0xAD, 0xC0, 0x15, 0xE8, 0x37, 0x31, 0xA3, 0x72, 0x63, 0x52, 0x1D, 0x1C, 0x5D, 0x51, 0x1B, 0xE1, + 0xA9, 0xED, 0x60, 0x32, 0x3E, 0xA9, 0x50, 0x28, 0x53, 0x06, 0x59, 0xE2, 0xFC, 0xE7, 0x02, 0x64, + 0x39, 0x21, 0x56, 0x4A, 0xA5, 0x40, 0x80, 0x81, 0xD5, 0x5A, 0x60, 0x7B, 0x68, 0x84, 0xF1, 0xE0, + 0xB1, 0xB6, 0x5B, 0xDF, 0xA8, 0x1D, 0x6D, 0x65, 0x20, 0xC0, 0xA2, 0xB9, 0xD9, 0xBB, 0x00, 0xA6, + 0xDB, 0x8B, 0x01, 0x53, 0x91, 0xFE, 0xC4, 0x51, 0x85, 0xB0, 0x96, 0x7F, 0xFD, 0x51, 0xDD, 0x14, + 0x03, 0x67, 0x2E, 0x75, 0x1C, 0x76, 0xD3, 0x6E, 0xDD, 0x99, 0x55, 0x76, 0xE5, 0xAB, 0x23, 0xFC, + 0x4A, 0xD5, 0xC6, 0xE8, 0x2E, 0xCA, 0x8A, 0xB3, 0xF6, 0x8C, 0x6C, 0xB0, 0xE9, 0xF2, 0xE7, 0x9E, + 0x69, 0x41, 0xED, 0xF1, 0x6D, 0xD2, 0x86, 0xD8, 0x7E, 0xCB, 0x5D, 0x47, 0x6C, 0x85, 0x6A, 0x23, + 0xED, 0x20, 0x40, 0x93, 0xB4, 0x20, 0xC7, 0xA5, 0xC9, 0xAF, 0x03, 0x15, 0xAC, 0x19, 0xE5, 0x2A, + 0x36, 0xDF, 0x6D, 0xC5, 0x8C, 0x80, 0x07, 0xCE, 0x92, 0x0C, 0xD8, 0x06, 0x62, 0x0F, 0xDD, 0x48, + 0x46, 0x1A, 0x53, 0xC7, 0x8A, 0x8C, 0x5D, 0x5D, 0xB4, 0xA1, 0x02, 0xD3, 0xA9, 0xB8, 0xF3, 0x94, + 0x8F, 0x3F, 0xE5, 0x54, 0xD4, 0x11, 0x65, 0xB2, 0x5E, 0x09, 0x0B, 0x81, 0xE3, 0x75, 0xA7, 0x89, + 0x81, 0x39, 0x6C, 0x46, 0xF6, 0x06, 0x9F, 0x27, 0x3B, 0xB6, 0x2D, 0x5F, 0x1D, 0x4B, 0xD4, 0x7B, + 0x1D, 0x61, 0x74, 0x89, 0xE4, 0xE3, 0xBD, 0x98, 0x1B, 0xC4, 0x51, 0x3B, 0xA4, 0xFA, 0xE0, 0x92, + 0xF7, 0xBE, 0xF2, 0x4D, 0xBB, 0xFF, 0xAD, 0x4F, 0x6D, 0x68, 0xC2, 0x79, 0x40, 0xAA, 0x9B, 0x8F, + 0x0C, 0x32, 0x4B, 0x5F, 0x3E, 0xAB, 0x59, 0x98, 0xB3, 0xF5, 0x1D, 0xAC, 0x5E, 0xBC, 0x78, 0xD3, + 0x01, 0x6C, 0x64, 0x15, 0x2F, 0xD8, 0x71, 0xA6, 0x2D, 0x45, 0xE1, 0x22, 0x42, 0xE4, 0x4E, 0x04, + 0x3C, 0x7D, 0xF4, 0x40, 0x21, 0xB4, 0x67, 0x05, 0xA8, 0xE2, 0xF3, 0x72, 0x87, 0x4C, 0x7D, 0xD9, + 0x1B, 0x65, 0x97, 0xF3, 0xC2, 0xE3, 0xE4, 0xC8, 0xD2, 0xDE, 0xF6, 0xEF, 0xDC, 0xBB, 0x44, 0x08, + 0x5E, 0xE2, 0x45, 0x27, 0x01, 0xB0, 0xF6, 0x43, 0xE7, 0x3A, 0xF6, 0xDC, 0x9D, 0xED, 0xF3, 0xC5, + 0x0C, 0xB8, 0x9C, 0x98, 0x3A, 0xD8, 0x36, 0xEE, 0x96, 0x72, 0x67, 0xE7, 0x81, 0x91, 0xD5, 0x05, + 0x0A, 0xE0, 0x82, 0xD5, 0x8F, 0xE8, 0xF9, 0xB0, 0xC9, 0xCF, 0x93, 0xE7, 0x04, 0xC5, 0xBC, 0x2B, + 0x43, 0x56, 0x7E, 0xE8, 0x67, 0x7C, 0xE5, 0xFB, 0x49, 0xAD, 0x5E, 0x9F, 0x25, 0x13, 0xDE, 0x6E, + 0x6E, 0xE9, 0xF1, 0xEC, 0x87, 0x0B, 0x59, 0x81, 0x76, 0x84, 0x76, 0xB3, 0x24, 0xAF, 0x30, 0xFD, + 0x27, 0x8B, 0xAB, 0xD8, 0x00, 0x8B, 0x9B, 0x0C, 0xD2, 0xB2, 0x4E, 0x5E, 0x9D, 0x1D, 0x96, 0x01, + 0x00, 0x67, 0xC1, 0x5F, 0x02, 0x20, 0xFD, 0x45, 0x6A, 0x01, 0x60, 0x58, 0x45, 0xCA, 0x47, 0x21, + 0x90, 0x5A, 0xC4, 0x43, 0x26, 0x1A, 0xD7, 0xA5, 0x4A, 0xB2, 0x5D, 0x2B, 0x35, 0x49, 0xFB, 0xA5, + 0x17, 0x92, 0x21, 0x1E, 0x93, 0x96, 0x67, 0xA2, 0x7E, 0x36, 0x7A, 0xDE, 0x5F, 0xBE, 0x7A, 0x58, + 0x9D, 0xF8, 0x78, 0xA3, 0xFA, 0xC8, 0xD5, 0x17, 0xF0, 0x21, 0x97, 0x8C, 0x80, 0xB5, 0x4B, 0x3B, + 0xBD, 0xBB, 0x41, 0x21, 0xA8, 0x50, 0x67, 0xF7, 0xE7, 0x19, 0x80, 0x10, 0x8E, 0xCE, 0x04, 0x18, + 0x3F, 0x51, 0x6B, 0x77, 0xD8, 0x9E, 0x16, 0xAF, 0xEC, 0xEF, 0x48, 0x16, 0x4D, 0x9E, 0x85, 0x38, + 0x18, 0x3E, 0xD4, 0x28, 0x87, 0x60, 0x2A, 0xF6, 0x7F, 0x09, 0x86, 0x6F, 0x9C, 0x3C, 0x3A, 0xFF, + 0xAB, 0xD0, 0x61, 0xA2, 0x97, 0x0D, 0x71, 0x94, 0x7E, 0xFD, 0xB9, 0x80, 0x02, 0x89, 0x6A, 0xB3, + 0x84, 0x6C, 0x2A, 0x77, 0x62, 0xBE, 0x0B, 0xF4, 0xAF, 0xAC, 0x7B, 0x7C, 0x8E, 0xCA, 0x01, 0xBA, + 0x71, 0x78, 0x94, 0xFD, 0xB5, 0x39, 0xA4, 0x4D, 0x2F, 0x78, 0xCF, 0xCA, 0x92, 0x0C, 0x1A, 0x99, + 0x48, 0x4C, 0x11, 0x96, 0xB5, 0x4E, 0x41, 0x28, 0xE4, 0xA6, 0xFE, 0x4B, 0x72, 0x91, 0xE7, 0xD4, + 0xDD, 0x9F, 0x12, 0xE6, 0x29, 0x38, 0xCE, 0x45, 0xAE, 0x02, 0xB8, 0x24, 0xAE, 0xBD, 0xE9, 0x66, + 0x08, 0x62, 0xA2, 0x2C, 0x2B, 0x00, 0xE2, 0x23, 0xD9, 0xC4, 0x48, 0xE4, 0xD3, 0xAC, 0xBB, 0x34, + 0xC7, 0xF0, 0xE3, 0x4F, 0xB9, 0x30, 0xEA, 0xA2, 0x12, 0xF1, 0x30, 0x2C, 0x36, 0xDE, 0x48, 0xF2, + 0xB0, 0x4C, 0x43, 0x3F, 0x2E, 0x58, 0xE4, 0x20, 0xE3, 0x58, 0xCD, 0x31, 0x22, 0xF0, 0xA2, 0x2A, + 0xE6, 0x19, 0x90, 0x55, 0x86, 0xF6, 0x55, 0x79, 0xD1, 0xD7, 0x46, 0x2F, 0xC0, 0xDC, 0x99, 0xE8, + 0xF3, 0x6A, 0xDF, 0x7F, 0xEB, 0x24, 0x4A, 0x1E, 0x5A, 0x75, 0xDE, 0x2F, 0x5C, 0x19, 0x61, 0x03, + 0x53, 0x54, 0x6A, 0x3B, 0x18, 0x70, 0xB6, 0x4F, 0xF1, 0x9C, 0x0A, 0x59, 0x9D, 0x19, 0x92, 0x65, + 0x8C, 0x83, 0x14, 0x2D, 0x44, 0x8A, 0x75, 0xA9, 0xF5, 0x90, 0xD2, 0x66, 0x4E, 0xFA, 0x69, 0x0F, + 0x5B, 0x0B, 0x98, 0x65, 0xC8, 0x11, 0x42, 0x59, 0x7F, 0xDD, 0x1B, 0x75, 0x17, 0x31, 0x4C, 0x75, + 0x58, 0xEB, 0x58, 0x63, 0x7D, 0xF2, 0xA6, 0xC2, 0x6E, 0xB7, 0x3F, 0x3E, 0x5E, 0x47, 0xAD, 0xB7, + 0x04, 0xE8, 0x05, 0xF8, 0xB2, 0xCF, 0x19, 0xF3, 0xD2, 0x85, 0xFE, 0x3E, 0x3E, 0xB1, 0x62, 0x08, + 0x2C, 0x10, 0x07, 0x0D, 0x73, 0x90, 0x17, 0xFA, 0x9B, 0x56, 0x02, 0x75, 0xF9, 0x51, 0xE0, 0xE9, + 0x1A, 0x7B, 0x9F, 0xB3, 0xF3, 0x98, 0xB8, 0x1C, 0x9C, 0xE1, 0xD5, 0x35, 0xAE, 0xC8, 0x60, 0x48, + 0x11, 0x09, 0x94, 0x6B, 0xD0, 0x8B, 0x15, 0xBC, 0x05, 0x68, 0xD3, 0x54, 0x8A, 0x51, 0x39, 0x5C, + 0x42, 0x76, 0xCE, 0xD8, 0xAD, 0x89, 0x30, 0xC9, 0x05, 0x1C, 0xCC, 0x94, 0x3F, 0x0F, 0x90, 0x6F, + 0x72, 0x2D, 0x85, 0x64, 0x9A, 0xB9, 0x23, 0xF9, 0x0B, 0xC3, 0x7C, 0x39, 0x0F, 0x97, 0x07, 0x97, + 0xDA, 0x58, 0x48, 0x33, 0x05, 0x23, 0xB8, 0x82, 0xE8, 0xD3, 0x53, 0x89, 0xAF, 0x33, 0x80, 0x22, + 0x84, 0x0C, 0x95, 0x5C, 0x67, 0xB8, 0x77, 0x0C, 0x5C, 0xA2, 0x5F, 0x3D, 0x58, 0x0F, 0x27, 0xF3, + 0x2F, 0xAE, 0x48, 0xBD, 0x0B, 0x6F, 0x54, 0xFB, 0x67, 0x4C, 0xEA, 0x32, 0x27, 0xF1, 0xFA, 0xE2, + 0xB0, 0xEC, 0x0B, 0x15, 0xB4, 0x70, 0xF6, 0x5C, 0xDD, 0x71, 0x60, 0xC3, 0xC1, 0xA8, 0x32, 0x65, + 0xAC, 0x7A, 0x77, 0x41, 0xE5, 0xA9, 0x6B, 0x11, 0x81, 0xFA, 0x34, 0x8D, 0xFB, 0xC1, 0x80, 0x6E, + 0xC4, 0x60, 0x30, 0x07, 0xD4, 0x8B, 0x67, 0xBD, 0xAA, 0x8C, 0x9C, 0x64, 0xAC, 0xDB, 0x0B, 0x24, + 0x8B, 0x63, 0x6F, 0xE6, 0xBC, 0xE7, 0x33, 0xA4, 0x4A, 0x4C, 0xA7, 0x9F, 0x43, 0x53, 0xD2, 0xBB, + 0x8F, 0x43, 0xC7, 0x3D, 0x78, 0x68, 0x3F, 0xA5, 0x3D, 0xCA, 0x69, 0x84, 0xA6, 0x97, 0x2D, 0xC0, + 0x7D, 0x31, 0x34, 0x55, 0x1D, 0x07, 0xB1, 0x5F, 0x40, 0x5C, 0x93, 0xB0, 0xBC, 0x7C, 0xB0, 0xBC, + 0xE7, 0x12, 0xEE, 0x6B, 0x2B, 0xD3, 0x4D, 0x67, 0x70, 0x3A, 0x9A, 0xF2, 0x3C, 0x7C, 0x81, 0xFA, + 0xD7, 0xD9, 0x90, 0x91, 0x81, 0xB8, 0xB1, 0xF3, 0x48, 0x6A, 0x26, 0x4F, 0x0C, 0xCE, 0xB0, 0x9E, + 0xFD, 0x4A, 0x3A, 0xAF, 0xAC, 0x5B, 0x3F, 0xBF, 0x44, 0x5A, 0xA3, 0x19, 0x1E, 0x4B, 0xE7, 0x36, + 0x6A, 0xD7, 0x20, 0xAE, 0xD7, 0x7D, 0x3B, 0xE7, 0xFF, 0x3A, 0x86, 0x2E, 0xD0, 0x4A, 0x3E, 0xAF, + 0x9F, 0x8E, 0x01, 0xBF, 0xF8, 0x4F, 0xC1, 0xE8, 0x6F, 0x74, 0xE1, 0x45, 0xD3, 0xF7, 0x04, 0x6A, + 0x4B, 0x9D, 0xEC, 0x33, 0x27, 0x76, 0xD7, 0xC5, 0xE1, 0xB0, 0x3B, 0x0E, 0x23, 0xEC, 0xF0, 0x86, + 0xD2, 0x1A, 0xBF, 0x3D, 0x04, 0x62, 0xB3, 0x6C, 0xB2, 0xEB, 0x17, 0x05, 0xA6, 0x0A, 0x8A, 0x7E, + 0x83, 0x1C, 0xB6, 0x37, 0x09, 0xC6, 0x0B, 0x70, 0x3C, 0xB5, 0x93, 0x81, 0xD8, 0x93, 0xA0, 0x5F, + 0x1E, 0x08, 0xE2, 0xC6, 0xE5, 0xC9, 0x72, 0xF1, 0xF1, 0xC1, 0xED, 0xD5, 0x58, 0x93, 0x83, 0xF8, + 0x65, 0x67, 0x2E, 0x0D, 0xA9, 0xF1, 0x64, 0x12, 0xE6, 0x4C, 0xEA, 0x15, 0x3F, 0x8C, 0x1A, 0xB6, + 0xBF, 0xF6, 0xB9, 0x52, 0x35, 0x09, 0xB0, 0xE6, 0xF7, 0xCD, 0xF1, 0xA5, 0xAA, 0x81, 0xD1, 0x81, + 0x6F, 0xB4, 0xA9, 0x66, 0x1F, 0xFC, 0x48, 0xC0, 0xB6, 0xD1, 0x8B, 0x06, 0x2F, 0xF6, 0xEF, 0x1F, + 0x0A, 0xE6, 0xCE, 0x3A, 0x4A, 0x55, 0xBF, 0x6D, 0xF9, 0x4D, 0xD4, 0x08, 0x45, 0x4B, 0xC3, 0x66, + 0x19, 0x92, 0x10, 0xE1, 0x17, 0x8E, 0x28, 0x91, 0x16, 0xBF, 0x3C, 0xEE, 0xA3, 0xA6, 0x99, 0x92, + 0x10, 0xE1, 0xF6, 0xCC, 0xAC, 0xB8, 0x65, 0x0B, 0x43, 0x66, 0xF8, 0xE3, 0xE5, 0x3F, 0x24, 0x89, + 0x47, 0x5D, 0x78, 0x43, 0xD0, 0x61, 0x17, 0xBD, 0x5B, 0x64, 0x54, 0x08, 0x45, 0x59, 0x93, 0xF6, + 0x95, 0x8A, 0x41, 0x51, 0x62, 0x4B, 0x51, 0x02, 0x30, 0x73, 0xC7, 0x87, 0xC5, 0x4B, 0xA2, 0x97, + 0x0F, 0xE8, 0x46, 0x5F, 0x7E, 0x2A, 0xE1, 0x30, 0x20, 0xB0, 0xFA, 0xE7, 0xCE, 0x61, 0x42, 0x57, + 0x6E, 0x21, 0xF3, 0x7A, 0xEC, 0xE3, 0x25, 0xC7, 0x25, 0xF3, 0x67, 0xA7, 0x57, 0x40, 0x00, 0x02, + 0xCF, 0x1C, 0x80, 0x77, 0x67, 0xBD, 0x70, 0xA1, 0x19, 0x92, 0x31, 0x75, 0x93, 0x27, 0x27, 0xB6, + 0x82, 0xE4, 0xEB, 0x1D, 0x78, 0x48, 0xE7, 0xA5, 0x5E, 0x57, 0xEF, 0x64, 0x28, 0x64, 0x1B, 0xF6, + 0x11, 0xB2, 0x03, 0x9D, 0xB9, 0x18, 0x02, 0x27, 0xF7, 0xBE, 0x9D, 0x55, 0xFC, 0x00, 0xD2, 0xC7, + 0xAE, 0xAD, 0x0B, 0xC5, 0xE9, 0x42, 0x41, 0x48, 0xD8, 0x32, 0xCF, 0xF6, 0x0F, 0xF5, 0xBC, 0x97, + 0xC6, 0x99, 0x47, 0x76, 0xBD, 0x89, 0x06, 0x0F, 0x63, 0x0C, 0x51, 0xD4, 0x5E, 0xEA, 0x48, 0xA8, + 0xA2, 0x56, 0x1C, 0x79, 0x84, 0x86, 0x40, 0x88, 0x41, 0x76, 0x55, 0xFC, 0xC2, 0xD7, 0xFD, 0xC9, + 0xC7, 0x80, 0x61, 0x35, 0xA7, 0x43, 0x20, 0xF7, 0xEB, 0x6C, 0x66, 0x13, 0xB0, 0xEC, 0x02, 0x75, + 0x3E, 0x4B, 0xAF, 0xB9, 0x5D, 0x40, 0xDA, 0xD6, 0x6E, 0x2D, 0x39, 0x54, 0xC2, 0x95, 0x35, 0x54, + 0x25, 0x72, 0xE1, 0x78, 0xB8, 0xEB, 0xC1, 0x16, 0x58, 0x0F, 0x9C, 0x9B, 0xB4, 0xEA, 0x37, 0xEC, + 0x3B, 0x11, 0xBA, 0xD5, 0x8A, 0xA9, 0xE3, 0x98, 0x00, 0x51, 0x1C, 0x14, 0xE0, 0x40, 0x96, 0xE5, + 0xE9, 0xF2, 0x21, 0x22, 0xB1, 0x23, 0x60, 0x78, 0xD3, 0x17, 0xF8, 0x7A, 0xA5, 0xA8, 0xBA, 0x20, + 0xD3, 0x15, 0x1E, 0x32, 0xE4, 0x5E, 0x15, 0x48, 0xAE, 0xA9, 0xE5, 0xB8, 0x33, 0xEC, 0xE8, 0xA2, + 0x42, 0xAC, 0xBF, 0x10, 0x84, 0x53, 0x87, 0x19, 0xB4, 0x5F, 0x76, 0x4D, 0x01, 0x9D, 0x56, 0x74, + 0xD9, 0x5C, 0x97, 0xE7, 0x88, 0xEA, 0x3A, 0xBF, 0xDC, 0x4C, 0x33, 0x8A, 0x16, 0xB9, 0x5B, 0xFA, + 0xD8, 0x42, 0xA7, 0xBB, 0x3C, 0x04, 0x27, 0x78, 0x49, 0x81, 0x2A, 0x5A, 0x7D, 0x7C, 0x23, 0xA8, + 0xBA, 0xF7, 0x9A, 0x9F, 0xD2, 0x66, 0x3E, 0x38, 0x3C, 0x75, 0xF9, 0xD1, 0x30, 0x26, 0x30, 0x6E, + 0x5A, 0x6E, 0xDC, 0x6A, 0x69, 0x32, 0x50, 0x33, 0x47, 0x9E, 0xA4, 0xA8, 0x64, 0x66, 0xF0, 0x8A, + 0xE4, 0xFD, 0x27, 0x6F, 0x51, 0x25, 0x8B, 0x43, 0x74, 0xC9, 0x8E, 0xBD, 0x88, 0x31, 0xBE, 0xEC, + 0x65, 0xD2, 0xCB, 0x8D, 0x5A, 0x13, 0x48, 0x16, 0x8C, 0x61, 0x0B, 0x11, 0xF6, 0xC6, 0x66, 0xAE, + 0xC3, 0xCC, 0x0C, 0xD2, 0xE1, 0x9F, 0x82, 0x41, 0x3F, 0x56, 0xF9, 0x73, 0xEF, 0xDC, 0x30, 0x50, + 0xCF, 0xB6, 0x7F, 0xBC, 0xD0, 0xB3, 0x10, 0xAB, 0x24, 0xE4, 0xEC, 0xAD, 0x18, 0x8C, 0x39, 0x2D, + 0x30, 0x4C, 0xC5, 0x40, 0x0D, 0xF6, 0xAC, 0xD6, 0x18, 0x5D, 0x96, 0xBF, 0x5F, 0x71, 0x75, 0x96, + 0x22, 0x97, 0x0F, 0x02, 0x94, 0x6E, 0xA6, 0xAE, 0x6D, 0x8F, 0x1E, 0xCA, 0x12, 0x9B, 0x2A, 0x1C, + 0xCE, 0xA9, 0xEE, 0xFD, 0x12, 0x8E, 0xFC, 0xED, 0x09, 0x33, 0xBA, 0xF4, 0x1A, 0x15, 0xF6, 0x9D, + 0x87, 0x16, 0x43, 0x7C, 0x78, 0x57, 0xE1, 0x44, 0xC9, 0xEB, 0x1F, 0x58, 0x4D, 0xC1, 0x49, 0x11, + 0x5C, 0xB2, 0x11, 0xA8, 0x55, 0x16, 0xF1, 0xC6, 0x50, 0xE9, 0x87, 0x89, 0xF6, 0xCF, 0xD8, 0x9C, + 0x51, 0xA7, 0xBC, 0x5B, 0x31, 0x6D, 0x4D, 0x51, 0xD0, 0x4C, 0xBC, 0x0D, 0x58, 0x2D, 0x7B, 0x88, + 0x7A, 0xF9, 0x8E, 0xD6, 0x40, 0x4D, 0xBB, 0xBE, 0xC4, 0xE5, 0x07, 0xFC, 0xD9, 0x7B, 0x6D, 0xA6, + 0x42, 0x57, 0x8F, 0x02, 0x94, 0x4F, 0xE4, 0x2A, 0x65, 0xE2, 0x19, 0x5A, 0x50, 0xE1, 0x25, 0x65, + 0x4A, 0x60, 0xC2, 0xCD, 0xA8, 0xEC, 0x05, 0x2E, 0x87, 0x7B, 0x95, 0xB7, 0x4F, 0xA0, 0x0B, 0x1B, + 0x4A, 0x7F, 0x92, 0xC8, 0x90, 0xEE, 0x89, 0x1E, 0x10, 0xD2, 0x85, 0xE4, 0x9F, 0x63, 0xC8, 0x12, + 0xBB, 0x4E, 0xB8, 0xCF, 0x0A, 0xEC, 0x18, 0x4E, 0xE6, 0x7C, 0xB3, 0x33, 0x26, 0xC7, 0x1F, 0xD2, + 0x04, 0x23, 0xEA, 0x07, 0x0C, 0x5F, 0x90, 0xBD, 0xA7, 0x6A, 0x0F, 0x4A, 0xD6, 0x10, 0x01, 0x3C, + 0x12, 0x29, 0x2E, 0x96, 0xC0, 0x4D, 0xBB, 0xBE, 0xE5, 0xA7, 0x83, 0xD5, 0x6A, 0x3C, 0xE3, 0x5B, + 0xB8, 0xF2, 0x5C, 0x6D, 0x1F, 0xA6, 0xF3, 0x12, 0x24, 0xF6, 0xD6, 0x3B, 0x10, 0x14, 0x09, 0x07, + 0x82, 0xE8, 0x30, 0x6A, 0x99, 0xDC, 0x95, 0x01, 0x9C, 0xD4, 0x68, 0x3B, 0xCA, 0x98, 0x12, 0xAB, + 0x77, 0x25, 0x15, 0x7D, 0x10, 0x32, 0x45, 0x98, 0xCD, 0x7A, 0xDF, 0x71, 0x8A, 0x75, 0xC1, 0x1C, + 0xD4, 0x68, 0x25, 0xEB, 0xBB, 0x54, 0x27, 0x6F, 0x2A, 0xF7, 0xB9, 0x98, 0x03, 0x27, 0xDE, 0x24, + 0xA8, 0xBB, 0x98, 0xC2, 0x84, 0xFF, 0x9B, 0x51, 0xD8, 0x53, 0x50, 0xDA, 0xF5, 0x88, 0xAA, 0x87, + 0x2F, 0xAE, 0xD6, 0xEA, 0x6B, 0xDE, 0xC8, 0xD7, 0xA7, 0x28, 0x65, 0x81, 0xE8, 0xB2, 0x3B, 0x1D, + 0x4F, 0x75, 0x8F, 0x9F, 0x7A, 0x74, 0x8E, 0xC1, 0x5F, 0x9A, 0xA8, 0x9D, 0xFA, 0x03, 0xA3, 0x71, + 0x9B, 0x37, 0x6D, 0xD5, 0x0B, 0xF5, 0xE1, 0xA1, 0x1B, 0x01, 0x6A, 0xC6, 0x67, 0xAA, 0xEA, 0x2C, + 0x9D, 0xA4, 0xD2, 0x6E, 0xFC, 0xDE, 0x2E, 0x7F, 0x94, 0x69, 0xE5, 0x4A, 0xE0, 0x01, 0x48, 0x3C, + 0x6B, 0xF7, 0x1E, 0xB6, 0x0B, 0x5F, 0xF9, 0x2E, 0x07, 0xC5, 0xE8, 0xAE, 0x37, 0x1B, 0xBC, 0x3C, + 0xD8, 0xD5, 0x0B, 0x91, 0x9E, 0x80, 0x24, 0xF5, 0x06, 0x0C, 0x0E, 0x98, 0x07, 0x96, 0x2D, 0x19, + 0xDC, 0x58, 0x93, 0xCC, 0xFB, 0x4E, 0xEB, 0xBD, 0x0F, 0xF5, 0xAF, 0x01, 0xFA, 0xF1, 0x7C, 0x43, + 0x8C, 0xB8, 0x56, 0x3E, 0xBE, 0x77, 0x4E, 0x2B, 0xF7, 0xBB, 0xB7, 0x45, 0x47, 0xCD, 0xCC, 0xA6, + 0x4C, 0x72, 0x7B, 0x6A, 0x2A, 0x70, 0x13, 0x07, 0xFD, 0xB8, 0x9C, 0x98, 0x3A, 0xD8, 0x23, 0x67, + 0x5B, 0x34, 0xD5, 0x14, 0x0C, 0xAB, 0x77, 0x1F, 0xF8, 0x3D, 0x5A, 0x9F, 0x92, 0xB7, 0x2C, 0xAD, + 0x31, 0xDE, 0x61, 0x07, 0xB3, 0x6B, 0xF7, 0x38, 0x15, 0x95, 0x46, 0x14, 0x48, 0x53, 0x69, 0x52, + 0x66, 0x07, 0x6D, 0x83, 0x71, 0x8A, 0x67, 0x25, 0x20, 0x0F, 0xFE, 0xD7, 0x02, 0xD7, 0x6E, 0x2C, + 0xD2, 0x1A, 0x0A, 0x5D, 0xFD, 0x0F, 0x74, 0xE3, 0xA4, 0x36, 0x07, 0x9A, 0xDF, 0xD4, 0x79, 0xBF, + 0xEF, 0x59, 0xC0, 0x44, 0x52, 0x87, 0x9A, 0x6E, 0x1D, 0x0E, 0xEE, 0xDE, 0x2E, 0x1A, 0xA9, 0x8F, + 0x3A, 0xC9, 0xBA, 0xEC, 0x99, 0x78, 0x2D, 0x55, 0x6B, 0x14, 0xC2, 0x06, 0xD5, 0xFC, 0x93, 0x53, + 0x4D, 0x11, 0x8C, 0xF8, 0xFA, 0x79, 0x7C, 0xA6, 0x64, 0xAE, 0x61, 0xB8, 0x7B, 0x94, 0x56, 0xA6, + 0x39, 0x78, 0x9A, 0xE5, 0xC7, 0xDF, 0x18, 0x63, 0x23, 0x9C, 0xFA, 0x66, 0xBB, 0xB7, 0x5A, 0x27, + 0x4C, 0xD1, 0xA1, 0x83, 0x22, 0xB3, 0x52, 0x49, 0x35, 0xB0, 0x22, 0x83, 0x59, 0x12, 0x00, 0x16, + 0x98, 0xDD, 0xAD, 0xC2, 0x94, 0xF9, 0xD3, 0x7B, 0x64, 0x7F, 0x44, 0x3E, 0x3C, 0x8B, 0x9A, 0x83, + 0x9C, 0x69, 0x6B, 0xE4, 0xDF, 0x9F, 0xED, 0x54, 0x1F, 0xE5, 0x5D, 0x7A, 0x05, 0x82, 0xB3, 0xDD, + 0xEF, 0xFC, 0x53, 0x96, 0xB0, 0x2C, 0x5A, 0xF8, 0xDF, 0x9C, 0x8B, 0x16, 0x4E, 0xDF, 0xDA, 0x4D, + 0x09, 0x09, 0x69, 0x50, 0x03, 0x65, 0xD8, 0x73, 0x70, 0xE8, 0x86, 0xBF, 0xBB, 0x35, 0xCE, 0xB2, + 0x46, 0xCB, 0x02, 0x00, 0x5B, 0xB4, 0xE2, 0xC6, 0x8F, 0x2F, 0x98, 0xAF, 0x87, 0x4B, 0x48, 0x45, + 0xED, 0xCC, 0x1D, 0xE6, 0x58, 0xD6, 0xF2, 0x50, 0x25, 0x9F, 0x52, 0xC7, 0xCB, 0x8A, 0x17, 0x9D, + 0x5B, 0xE5, 0xC8, 0xD7, 0x72, 0xB7, 0x52, 0xB2, 0xC4, 0x98, 0xE3, 0x7A, 0x17, 0x3E, 0xC6, 0x60, + 0xA7, 0x97, 0xB0, 0xCF, 0x18, 0x81, 0x53, 0x84, 0x4C, 0xD5, 0x17, 0x32, 0x03, 0x13, 0x39, 0x51, + 0x09, 0x10, 0xE3, 0x77, 0x49, 0x4F, 0x62, 0x01, 0xBF, 0x8C, 0x9A, 0xE0, 0x41, 0x9E, 0x89, 0x74, + 0x36, 0xF9, 0x96, 0x86, 0x2E, 0x96, 0x1C, 0x4A, 0xB7, 0x2B, 0x4A, 0x97, 0xBC, 0x99, 0x40, 0xA3, + 0xE0, 0x3D, 0xC8, 0xAD, 0x2F, 0xDF, 0x4F, 0x2C, 0xC4, 0x69, 0x82, 0x9F, 0x9B, 0x81, 0x0C, 0x61, + 0x5C, 0xA5, 0x9D, 0x8C, 0x89, 0xC0, 0x2C, 0xB4, 0x4A, 0x33, 0x4E, 0xEB, 0xA2, 0x56, 0x40, 0xC0, + 0xC2, 0x46, 0xAF, 0x6A, 0xFC, 0x67, 0xD1, 0x80, 0x5E, 0xC5, 0x6D, 0x84, 0x43, 0x27, 0x3F, 0x55, + 0x15, 0x96, 0x6A, 0xA0, 0xA5, 0xDA, 0xB7, 0xFF, 0xB7, 0x75, 0x6E, 0x4C, 0x49, 0x91, 0x9D, 0x22, + 0xA3, 0x46, 0xEA, 0xED, 0x9A, 0x00, 0xE2, 0x32, 0xC3, 0xD6, 0xA9, 0x71, 0x20, 0x55, 0xA3, 0x19, + 0xED, 0xF8, 0x4F, 0xA7, 0x12, 0x9C, 0x66, 0x87, 0xAF, 0x4E, 0xB7, 0xF0, 0xDB, 0xBF, 0xEF, 0xF0, + 0xF6, 0xAF, 0xEA, 0xDA, 0x09, 0xFE, 0xDE, 0x38, 0x5C, 0xA5, 0xA2, 0xDF, 0x99, 0x45, 0xA8, 0xE4, + 0xE7, 0x92, 0xAC, 0x67, 0xAA, 0x4F, 0xBF, 0x77, 0x3E, 0xA2, 0x40, 0x49, 0x22, 0x4A, 0x1E, 0x3B, + 0xAA, 0x70, 0x7F, 0x95, 0xAF, 0x37, 0x4B, 0xFC, 0x99, 0xE2, 0xE0, 0xBA, 0xD7, 0x34, 0xCE, 0x55, + 0x88, 0x5B, 0x84, 0x1B, 0x57, 0xC4, 0x80, 0x03, 0x53, 0xC9, 0x2F, 0x93, 0x04, 0x4D, 0xD5, 0x96, + 0xE5, 0x70, 0xA6, 0x6E, 0x63, 0x5D, 0x9D, 0x6C, 0xDB, 0x02, 0x0A, 0xA9, 0xDA, 0x8B, 0x53, 0xDC, + 0xD9, 0x9A, 0xC5, 0x94, 0x2C, 0x91, 0x92, 0x2A, 0xDE, 0xBB, 0x8B, 0x13, 0xB9, 0x19, 0x96, 0x64, + 0xCC, 0xF2, 0x64, 0x39, 0xB7, 0x75, 0x49, 0xE9, 0x86, 0xC2, 0x86, 0x62, 0xD9, 0x24, 0xD3, 0x81, + 0x35, 0x49, 0xFC, 0xA0, 0xA5, 0xA0, 0x93, 0x05, 0x64, 0xB4, 0x1A, 0x57, 0xCE, 0x0C, 0x90, 0x02, + 0x27, 0xC5, 0x7A, 0x2B, 0x5D, 0xAE, 0x3E, 0xD5, 0xDD, 0x10, 0x7C, 0x14, 0xEA, 0x3A, 0x08, 0xAC, + 0x72, 0x4E, 0x90, 0x3D, 0x3B, 0x7C, 0x86, 0x2E, 0xEB, 0xD4, 0x06, 0x70, 0xE6, 0xC7, 0xFB, 0x5F, + 0xBD, 0x18, 0xF4, 0x11, 0xA4, 0x1A, 0x93, 0xC3, 0xBE, 0xD9, 0xFB, 0x26, 0x48, 0x2F, 0x37, 0x3C, + 0xD0, 0x03, 0x47, 0x1A, 0xF7, 0x62, 0x19, 0x24, 0x5C, 0xF4, 0xA8, 0x92, 0x20, 0x7A, 0xF2, 0x9E, + 0x2A, 0xC5, 0x95, 0xA2, 0xFB, 0xA4, 0xEA, 0x85, 0xD8, 0x56, 0xB7, 0x70, 0xD1, 0x60, 0x30, 0xA5, + 0x30, 0x82, 0x70, 0xDC, 0x7A, 0x65, 0x8A, 0x36, 0x3F, 0x5B, 0x0C, 0xAE, 0x54, 0x7C, 0xD3, 0x57, + 0x84, 0x7B, 0x3A, 0x65, 0x18, 0x81, 0xEE, 0x05, 0x9B, 0x44, 0x4D, 0xB8, 0xDA, 0xA2, 0xA1, 0xC9, + 0x15, 0xD3, 0x73, 0x03, 0x0E, 0x43, 0xE9, 0x8E, 0x15, 0xF9, 0xBE, 0xC6, 0xC5, 0x8A, 0xE5, 0xC0, + 0x1E, 0xC2, 0x37, 0x9E, 0x2A, 0x26, 0xA5, 0xA0, 0xBD, 0x24, 0x5F, 0xB9, 0xC1, 0xAB, 0x34, 0x48, + 0xB9, 0x5D, 0x98, 0xB4, 0x65, 0x18, 0xF3, 0x63, 0x19, 0x44, 0x1B, 0x11, 0x16, 0xFF, 0xDC, 0xF1, + 0x79, 0x08, 0x86, 0x0F, 0x52, 0x98, 0x73, 0xC4, 0x92, 0x90, 0x2B, 0x47, 0x09, 0xD0, 0x43, 0x6C, + 0x2F, 0x20, 0xEB, 0xDC, 0xDA, 0xC5, 0x08, 0x7B, 0x94, 0x42, 0x30, 0x6A, 0xC7, 0xDA, 0x8C, 0xC3, + 0x76, 0xA7, 0xA5, 0xCC, 0x62, 0x13, 0x00, 0x60, 0x31, 0x58, 0x44, 0x9B, 0xF5, 0x64, 0x14, 0xF5, + 0x11, 0xC5, 0x54, 0x52, 0x83, 0xD4, 0x73, 0x01, 0x16, 0x0E, 0xB3, 0x7A, 0x29, 0x69, 0x35, 0x56, + 0xD4, 0xEE, 0x8A, 0x17, 0xA2, 0x99, 0x24, 0x9C, 0xD7, 0x8F, 0xDB, 0x55, 0xB5, 0x3E }; diff --git a/drivers/sensors/pmw3360.c b/drivers/sensors/pmw3360.c index 17c4675ffa5f..5463bfc59441 100644 --- a/drivers/sensors/pmw3360.c +++ b/drivers/sensors/pmw3360.c @@ -196,7 +196,7 @@ void pmw_upload_firmware(void) { wait_us(15); unsigned char c; - for (int i = 0; i < firmware_length; i++) { + for (int i = 0; i < FIRMWARE_LENGTH; i++) { c = (unsigned char)pgm_read_byte(firmware_data + i); spi_write(c); wait_us(15); diff --git a/drivers/sensors/pmw3360_firmware.h b/drivers/sensors/pmw3360_firmware.h index cca5a6a4d877..4d5fe7a0b973 100644 --- a/drivers/sensors/pmw3360_firmware.h +++ b/drivers/sensors/pmw3360_firmware.h @@ -18,283 +18,266 @@ #pragma once -// clang-format off -// Firmware Blob foor PMW3360 -const uint16_t firmware_length = 4094; -// clang-format off -const uint8_t firmware_data[] PROGMEM = { // SROM 0x04 -0x01, 0x04, 0x8e, 0x96, 0x6e, 0x77, 0x3e, 0xfe, 0x7e, 0x5f, 0x1d, 0xb8, 0xf2, 0x66, 0x4e, -0xff, 0x5d, 0x19, 0xb0, 0xc2, 0x04, 0x69, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0xb0, -0xc3, 0xe5, 0x29, 0xb1, 0xe0, 0x23, 0xa5, 0xa9, 0xb1, 0xc1, 0x00, 0x82, 0x67, 0x4c, 0x1a, -0x97, 0x8d, 0x79, 0x51, 0x20, 0xc7, 0x06, 0x8e, 0x7c, 0x7c, 0x7a, 0x76, 0x4f, 0xfd, 0x59, -0x30, 0xe2, 0x46, 0x0e, 0x9e, 0xbe, 0xdf, 0x1d, 0x99, 0x91, 0xa0, 0xa5, 0xa1, 0xa9, 0xd0, -0x22, 0xc6, 0xef, 0x5c, 0x1b, 0x95, 0x89, 0x90, 0xa2, 0xa7, 0xcc, 0xfb, 0x55, 0x28, 0xb3, -0xe4, 0x4a, 0xf7, 0x6c, 0x3b, 0xf4, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0x9d, 0xb8, 0xd3, 0x05, -0x88, 0x92, 0xa6, 0xce, 0x1e, 0xbe, 0xdf, 0x1d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x5c, 0x07, -0x11, 0x5d, 0x98, 0x0b, 0x9d, 0x94, 0x97, 0xee, 0x4e, 0x45, 0x33, 0x6b, 0x44, 0xc7, 0x29, -0x56, 0x27, 0x30, 0xc6, 0xa7, 0xd5, 0xf2, 0x56, 0xdf, 0xb4, 0x38, 0x62, 0xcb, 0xa0, 0xb6, -0xe3, 0x0f, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6f, 0x76, 0x89, 0xb5, 0x77, 0x41, 0x27, 0x82, -0x66, 0x65, 0x82, 0xcc, 0xd5, 0xe6, 0x20, 0xd5, 0x27, 0x17, 0xc5, 0xf8, 0x03, 0x23, 0x7c, -0x5f, 0x64, 0xa5, 0x1d, 0xc1, 0xd6, 0x36, 0xcb, 0x4c, 0xd4, 0xdb, 0x66, 0xd7, 0x8b, 0xb1, -0x99, 0x7e, 0x6f, 0x4c, 0x36, 0x40, 0x06, 0xd6, 0xeb, 0xd7, 0xa2, 0xe4, 0xf4, 0x95, 0x51, -0x5a, 0x54, 0x96, 0xd5, 0x53, 0x44, 0xd7, 0x8c, 0xe0, 0xb9, 0x40, 0x68, 0xd2, 0x18, 0xe9, -0xdd, 0x9a, 0x23, 0x92, 0x48, 0xee, 0x7f, 0x43, 0xaf, 0xea, 0x77, 0x38, 0x84, 0x8c, 0x0a, -0x72, 0xaf, 0x69, 0xf8, 0xdd, 0xf1, 0x24, 0x83, 0xa3, 0xf8, 0x4a, 0xbf, 0xf5, 0x94, 0x13, -0xdb, 0xbb, 0xd8, 0xb4, 0xb3, 0xa0, 0xfb, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, -0xa2, 0xd3, 0x13, 0xe7, 0xfa, 0xe7, 0xce, 0x0f, 0x63, 0x15, 0x0b, 0x6b, 0x94, 0xbb, 0x37, -0x83, 0x26, 0x05, 0x9d, 0xfb, 0x46, 0x92, 0xfc, 0x0a, 0x15, 0xd1, 0x0d, 0x73, 0x92, 0xd6, -0x8c, 0x1b, 0x8c, 0xb8, 0x55, 0x8a, 0xce, 0xbd, 0xfe, 0x8e, 0xfc, 0xed, 0x09, 0x12, 0x83, -0x91, 0x82, 0x51, 0x31, 0x23, 0xfb, 0xb4, 0x0c, 0x76, 0xad, 0x7c, 0xd9, 0xb4, 0x4b, 0xb2, -0x67, 0x14, 0x09, 0x9c, 0x7f, 0x0c, 0x18, 0xba, 0x3b, 0xd6, 0x8e, 0x14, 0x2a, 0xe4, 0x1b, -0x52, 0x9f, 0x2b, 0x7d, 0xe1, 0xfb, 0x6a, 0x33, 0x02, 0xfa, 0xac, 0x5a, 0xf2, 0x3e, 0x88, -0x7e, 0xae, 0xd1, 0xf3, 0x78, 0xe8, 0x05, 0xd1, 0xe3, 0xdc, 0x21, 0xf6, 0xe1, 0x9a, 0xbd, -0x17, 0x0e, 0xd9, 0x46, 0x9b, 0x88, 0x03, 0xea, 0xf6, 0x66, 0xbe, 0x0e, 0x1b, 0x50, 0x49, -0x96, 0x40, 0x97, 0xf1, 0xf1, 0xe4, 0x80, 0xa6, 0x6e, 0xe8, 0x77, 0x34, 0xbf, 0x29, 0x40, -0x44, 0xc2, 0xff, 0x4e, 0x98, 0xd3, 0x9c, 0xa3, 0x32, 0x2b, 0x76, 0x51, 0x04, 0x09, 0xe7, -0xa9, 0xd1, 0xa6, 0x32, 0xb1, 0x23, 0x53, 0xe2, 0x47, 0xab, 0xd6, 0xf5, 0x69, 0x5c, 0x3e, -0x5f, 0xfa, 0xae, 0x45, 0x20, 0xe5, 0xd2, 0x44, 0xff, 0x39, 0x32, 0x6d, 0xfd, 0x27, 0x57, -0x5c, 0xfd, 0xf0, 0xde, 0xc1, 0xb5, 0x99, 0xe5, 0xf5, 0x1c, 0x77, 0x01, 0x75, 0xc5, 0x6d, -0x58, 0x92, 0xf2, 0xb2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7a, 0x30, 0xff, 0xb7, 0xf0, 0xef, -0x77, 0xc1, 0x8a, 0x5d, 0xdc, 0xc0, 0xd1, 0x29, 0x30, 0x1e, 0x77, 0x38, 0x7a, 0x94, 0xf1, -0xb8, 0x7a, 0x7e, 0xef, 0xa4, 0xd1, 0xac, 0x31, 0x4a, 0xf2, 0x5d, 0x64, 0x3d, 0xb2, 0xe2, -0xf0, 0x08, 0x99, 0xfc, 0x70, 0xee, 0x24, 0xa7, 0x7e, 0xee, 0x1e, 0x20, 0x69, 0x7d, 0x44, -0xbf, 0x87, 0x42, 0xdf, 0x88, 0x3b, 0x0c, 0xda, 0x42, 0xc9, 0x04, 0xf9, 0x45, 0x50, 0xfc, -0x83, 0x8f, 0x11, 0x6a, 0x72, 0xbc, 0x99, 0x95, 0xf0, 0xac, 0x3d, 0xa7, 0x3b, 0xcd, 0x1c, -0xe2, 0x88, 0x79, 0x37, 0x11, 0x5f, 0x39, 0x89, 0x95, 0x0a, 0x16, 0x84, 0x7a, 0xf6, 0x8a, -0xa4, 0x28, 0xe4, 0xed, 0x83, 0x80, 0x3b, 0xb1, 0x23, 0xa5, 0x03, 0x10, 0xf4, 0x66, 0xea, -0xbb, 0x0c, 0x0f, 0xc5, 0xec, 0x6c, 0x69, 0xc5, 0xd3, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0x99, -0x88, 0x76, 0x08, 0xa0, 0xa8, 0x95, 0x7c, 0xd8, 0x38, 0x6d, 0xcd, 0x59, 0x02, 0x51, 0x4b, -0xf1, 0xb5, 0x2b, 0x50, 0xe3, 0xb6, 0xbd, 0xd0, 0x72, 0xcf, 0x9e, 0xfd, 0x6e, 0xbb, 0x44, -0xc8, 0x24, 0x8a, 0x77, 0x18, 0x8a, 0x13, 0x06, 0xef, 0x97, 0x7d, 0xfa, 0x81, 0xf0, 0x31, -0xe6, 0xfa, 0x77, 0xed, 0x31, 0x06, 0x31, 0x5b, 0x54, 0x8a, 0x9f, 0x30, 0x68, 0xdb, 0xe2, -0x40, 0xf8, 0x4e, 0x73, 0xfa, 0xab, 0x74, 0x8b, 0x10, 0x58, 0x13, 0xdc, 0xd2, 0xe6, 0x78, -0xd1, 0x32, 0x2e, 0x8a, 0x9f, 0x2c, 0x58, 0x06, 0x48, 0x27, 0xc5, 0xa9, 0x5e, 0x81, 0x47, -0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xa4, 0x3e, 0x88, 0x9c, 0xda, 0x33, 0x0a, 0xce, 0xbc, -0x8b, 0x8e, 0xcf, 0x9f, 0xd3, 0x71, 0x80, 0x43, 0xcf, 0x6b, 0xa9, 0x51, 0x83, 0x76, 0x30, -0x82, 0xc5, 0x6a, 0x85, 0x39, 0x11, 0x50, 0x1a, 0x82, 0xdc, 0x1e, 0x1c, 0xd5, 0x7d, 0xa9, -0x71, 0x99, 0x33, 0x47, 0x19, 0x97, 0xb3, 0x5a, 0xb1, 0xdf, 0xed, 0xa4, 0xf2, 0xe6, 0x26, -0x84, 0xa2, 0x28, 0x9a, 0x9e, 0xdf, 0xa6, 0x6a, 0xf4, 0xd6, 0xfc, 0x2e, 0x5b, 0x9d, 0x1a, -0x2a, 0x27, 0x68, 0xfb, 0xc1, 0x83, 0x21, 0x4b, 0x90, 0xe0, 0x36, 0xdd, 0x5b, 0x31, 0x42, -0x55, 0xa0, 0x13, 0xf7, 0xd0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xc5, 0xf3, 0x21, -0xf8, 0x37, 0x2f, 0x40, 0xf3, 0xd4, 0xaf, 0x16, 0x08, 0x36, 0x02, 0xfc, 0x77, 0xc5, 0x8b, -0x04, 0x90, 0x56, 0xb9, 0xc9, 0x67, 0x9a, 0x99, 0xe8, 0x00, 0xd3, 0x86, 0xff, 0x97, 0x2d, -0x08, 0xe9, 0xb7, 0xb3, 0x91, 0xbc, 0xdf, 0x45, 0xc6, 0xed, 0x0f, 0x8c, 0x4c, 0x1e, 0xe6, -0x5b, 0x6e, 0x38, 0x30, 0xe4, 0xaa, 0xe3, 0x95, 0xde, 0xb9, 0xe4, 0x9a, 0xf5, 0xb2, 0x55, -0x9a, 0x87, 0x9b, 0xf6, 0x6a, 0xb2, 0xf2, 0x77, 0x9a, 0x31, 0xf4, 0x7a, 0x31, 0xd1, 0x1d, -0x04, 0xc0, 0x7c, 0x32, 0xa2, 0x9e, 0x9a, 0xf5, 0x62, 0xf8, 0x27, 0x8d, 0xbf, 0x51, 0xff, -0xd3, 0xdf, 0x64, 0x37, 0x3f, 0x2a, 0x6f, 0x76, 0x3a, 0x7d, 0x77, 0x06, 0x9e, 0x77, 0x7f, -0x5e, 0xeb, 0x32, 0x51, 0xf9, 0x16, 0x66, 0x9a, 0x09, 0xf3, 0xb0, 0x08, 0xa4, 0x70, 0x96, -0x46, 0x30, 0xff, 0xda, 0x4f, 0xe9, 0x1b, 0xed, 0x8d, 0xf8, 0x74, 0x1f, 0x31, 0x92, 0xb3, -0x73, 0x17, 0x36, 0xdb, 0x91, 0x30, 0xd6, 0x88, 0x55, 0x6b, 0x34, 0x77, 0x87, 0x7a, 0xe7, -0xee, 0x06, 0xc6, 0x1c, 0x8c, 0x19, 0x0c, 0x48, 0x46, 0x23, 0x5e, 0x9c, 0x07, 0x5c, 0xbf, -0xb4, 0x7e, 0xd6, 0x4f, 0x74, 0x9c, 0xe2, 0xc5, 0x50, 0x8b, 0xc5, 0x8b, 0x15, 0x90, 0x60, -0x62, 0x57, 0x29, 0xd0, 0x13, 0x43, 0xa1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xc7, 0x4d, 0x19, -0x86, 0xcc, 0x2f, 0x2a, 0x75, 0x5a, 0xfc, 0xeb, 0x97, 0x2a, 0x70, 0xe3, 0x78, 0xd8, 0x91, -0xb0, 0x4f, 0x99, 0x07, 0xa3, 0x95, 0xea, 0x24, 0x21, 0xd5, 0xde, 0x51, 0x20, 0x93, 0x27, -0x0a, 0x30, 0x73, 0xa8, 0xff, 0x8a, 0x97, 0xe9, 0xa7, 0x6a, 0x8e, 0x0d, 0xe8, 0xf0, 0xdf, -0xec, 0xea, 0xb4, 0x6c, 0x1d, 0x39, 0x2a, 0x62, 0x2d, 0x3d, 0x5a, 0x8b, 0x65, 0xf8, 0x90, -0x05, 0x2e, 0x7e, 0x91, 0x2c, 0x78, 0xef, 0x8e, 0x7a, 0xc1, 0x2f, 0xac, 0x78, 0xee, 0xaf, -0x28, 0x45, 0x06, 0x4c, 0x26, 0xaf, 0x3b, 0xa2, 0xdb, 0xa3, 0x93, 0x06, 0xb5, 0x3c, 0xa5, -0xd8, 0xee, 0x8f, 0xaf, 0x25, 0xcc, 0x3f, 0x85, 0x68, 0x48, 0xa9, 0x62, 0xcc, 0x97, 0x8f, -0x7f, 0x2a, 0xea, 0xe0, 0x15, 0x0a, 0xad, 0x62, 0x07, 0xbd, 0x45, 0xf8, 0x41, 0xd8, 0x36, -0xcb, 0x4c, 0xdb, 0x6e, 0xe6, 0x3a, 0xe7, 0xda, 0x15, 0xe9, 0x29, 0x1e, 0x12, 0x10, 0xa0, -0x14, 0x2c, 0x0e, 0x3d, 0xf4, 0xbf, 0x39, 0x41, 0x92, 0x75, 0x0b, 0x25, 0x7b, 0xa3, 0xce, -0x39, 0x9c, 0x15, 0x64, 0xc8, 0xfa, 0x3d, 0xef, 0x73, 0x27, 0xfe, 0x26, 0x2e, 0xce, 0xda, -0x6e, 0xfd, 0x71, 0x8e, 0xdd, 0xfe, 0x76, 0xee, 0xdc, 0x12, 0x5c, 0x02, 0xc5, 0x3a, 0x4e, -0x4e, 0x4f, 0xbf, 0xca, 0x40, 0x15, 0xc7, 0x6e, 0x8d, 0x41, 0xf1, 0x10, 0xe0, 0x4f, 0x7e, -0x97, 0x7f, 0x1c, 0xae, 0x47, 0x8e, 0x6b, 0xb1, 0x25, 0x31, 0xb0, 0x73, 0xc7, 0x1b, 0x97, -0x79, 0xf9, 0x80, 0xd3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1e, 0xe4, 0xd0, 0x80, 0x21, 0xd6, -0xee, 0x6b, 0x6c, 0x4f, 0xbf, 0xf5, 0xb7, 0xd9, 0x09, 0x87, 0x2f, 0xa9, 0x14, 0xbe, 0x27, -0xd9, 0x72, 0x50, 0x01, 0xd4, 0x13, 0x73, 0xa6, 0xa7, 0x51, 0x02, 0x75, 0x25, 0xe1, 0xb3, -0x45, 0x34, 0x7d, 0xa8, 0x8e, 0xeb, 0xf3, 0x16, 0x49, 0xcb, 0x4f, 0x8c, 0xa1, 0xb9, 0x36, -0x85, 0x39, 0x75, 0x5d, 0x08, 0x00, 0xae, 0xeb, 0xf6, 0xea, 0xd7, 0x13, 0x3a, 0x21, 0x5a, -0x5f, 0x30, 0x84, 0x52, 0x26, 0x95, 0xc9, 0x14, 0xf2, 0x57, 0x55, 0x6b, 0xb1, 0x10, 0xc2, -0xe1, 0xbd, 0x3b, 0x51, 0xc0, 0xb7, 0x55, 0x4c, 0x71, 0x12, 0x26, 0xc7, 0x0d, 0xf9, 0x51, -0xa4, 0x38, 0x02, 0x05, 0x7f, 0xb8, 0xf1, 0x72, 0x4b, 0xbf, 0x71, 0x89, 0x14, 0xf3, 0x77, -0x38, 0xd9, 0x71, 0x24, 0xf3, 0x00, 0x11, 0xa1, 0xd8, 0xd4, 0x69, 0x27, 0x08, 0x37, 0x35, -0xc9, 0x11, 0x9d, 0x90, 0x1c, 0x0e, 0xe7, 0x1c, 0xff, 0x2d, 0x1e, 0xe8, 0x92, 0xe1, 0x18, -0x10, 0x95, 0x7c, 0xe0, 0x80, 0xf4, 0x96, 0x43, 0x21, 0xf9, 0x75, 0x21, 0x64, 0x38, 0xdd, -0x9f, 0x1e, 0x95, 0x16, 0xda, 0x56, 0x1d, 0x4f, 0x9a, 0x53, 0xb2, 0xe2, 0xe4, 0x18, 0xcb, -0x6b, 0x1a, 0x65, 0xeb, 0x56, 0xc6, 0x3b, 0xe5, 0xfe, 0xd8, 0x26, 0x3f, 0x3a, 0x84, 0x59, -0x72, 0x66, 0xa2, 0xf3, 0x75, 0xff, 0xfb, 0x60, 0xb3, 0x22, 0xad, 0x3f, 0x2d, 0x6b, 0xf9, -0xeb, 0xea, 0x05, 0x7c, 0xd8, 0x8f, 0x6d, 0x2c, 0x98, 0x9e, 0x2b, 0x93, 0xf1, 0x5e, 0x46, -0xf0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xd7, 0x7f, 0xf9, 0xf0, 0xe5, 0x7d, 0xdb, 0x1d, 0x75, -0x19, 0xf3, 0xc4, 0x58, 0x9b, 0x17, 0x88, 0xa8, 0x92, 0xe0, 0xbe, 0xbd, 0x8b, 0x1d, 0x8d, -0x9f, 0x56, 0x76, 0xad, 0xaf, 0x29, 0xe2, 0xd9, 0xd5, 0x52, 0xf6, 0xb5, 0x56, 0x35, 0x57, -0x3a, 0xc8, 0xe1, 0x56, 0x43, 0x19, 0x94, 0xd3, 0x04, 0x9b, 0x6d, 0x35, 0xd8, 0x0b, 0x5f, -0x4d, 0x19, 0x8e, 0xec, 0xfa, 0x64, 0x91, 0x0a, 0x72, 0x20, 0x2b, 0xbc, 0x1a, 0x4a, 0xfe, -0x8b, 0xfd, 0xbb, 0xed, 0x1b, 0x23, 0xea, 0xad, 0x72, 0x82, 0xa1, 0x29, 0x99, 0x71, 0xbd, -0xf0, 0x95, 0xc1, 0x03, 0xdd, 0x7b, 0xc2, 0xb2, 0x3c, 0x28, 0x54, 0xd3, 0x68, 0xa4, 0x72, -0xc8, 0x66, 0x96, 0xe0, 0xd1, 0xd8, 0x7f, 0xf8, 0xd1, 0x26, 0x2b, 0xf7, 0xad, 0xba, 0x55, -0xca, 0x15, 0xb9, 0x32, 0xc3, 0xe5, 0x88, 0x97, 0x8e, 0x5c, 0xfb, 0x92, 0x25, 0x8b, 0xbf, -0xa2, 0x45, 0x55, 0x7a, 0xa7, 0x6f, 0x8b, 0x57, 0x5b, 0xcf, 0x0e, 0xcb, 0x1d, 0xfb, 0x20, -0x82, 0x77, 0xa8, 0x8c, 0xcc, 0x16, 0xce, 0x1d, 0xfa, 0xde, 0xcc, 0x0b, 0x62, 0xfe, 0xcc, -0xe1, 0xb7, 0xf0, 0xc3, 0x81, 0x64, 0x73, 0x40, 0xa0, 0xc2, 0x4d, 0x89, 0x11, 0x75, 0x33, -0x55, 0x33, 0x8d, 0xe8, 0x4a, 0xfd, 0xea, 0x6e, 0x30, 0x0b, 0xd7, 0x31, 0x2c, 0xde, 0x47, -0xe3, 0xbf, 0xf8, 0x55, 0x42, 0xe2, 0x7f, 0x59, 0xe5, 0x17, 0xef, 0x99, 0x34, 0x69, 0x91, -0xb1, 0x23, 0x8e, 0x20, 0x87, 0x2d, 0xa8, 0xfe, 0xd5, 0x8a, 0xf3, 0x84, 0x3a, 0xf0, 0x37, -0xe4, 0x09, 0x00, 0x54, 0xee, 0x67, 0x49, 0x93, 0xe4, 0x81, 0x70, 0xe3, 0x90, 0x4d, 0xef, -0xfe, 0x41, 0xb7, 0x99, 0x7b, 0xc1, 0x83, 0xba, 0x62, 0x12, 0x6f, 0x7d, 0xde, 0x6b, 0xaf, -0xda, 0x16, 0xf9, 0x55, 0x51, 0xee, 0xa6, 0x0c, 0x2b, 0x02, 0xa3, 0xfd, 0x8d, 0xfb, 0x30, -0x17, 0xe4, 0x6f, 0xdf, 0x36, 0x71, 0xc4, 0xca, 0x87, 0x25, 0x48, 0xb0, 0x47, 0xec, 0xea, -0xb4, 0xbf, 0xa5, 0x4d, 0x9b, 0x9f, 0x02, 0x93, 0xc4, 0xe3, 0xe4, 0xe8, 0x42, 0x2d, 0x68, -0x81, 0x15, 0x0a, 0xeb, 0x84, 0x5b, 0xd6, 0xa8, 0x74, 0xfb, 0x7d, 0x1d, 0xcb, 0x2c, 0xda, -0x46, 0x2a, 0x76, 0x62, 0xce, 0xbc, 0x5c, 0x9e, 0x8b, 0xe7, 0xcf, 0xbe, 0x78, 0xf5, 0x7c, -0xeb, 0xb3, 0x3a, 0x9c, 0xaa, 0x6f, 0xcc, 0x72, 0xd1, 0x59, 0xf2, 0x11, 0x23, 0xd6, 0x3f, -0x48, 0xd1, 0xb7, 0xce, 0xb0, 0xbf, 0xcb, 0xea, 0x80, 0xde, 0x57, 0xd4, 0x5e, 0x97, 0x2f, -0x75, 0xd1, 0x50, 0x8e, 0x80, 0x2c, 0x66, 0x79, 0xbf, 0x72, 0x4b, 0xbd, 0x8a, 0x81, 0x6c, -0xd3, 0xe1, 0x01, 0xdc, 0xd2, 0x15, 0x26, 0xc5, 0x36, 0xda, 0x2c, 0x1a, 0xc0, 0x27, 0x94, -0xed, 0xb7, 0x9b, 0x85, 0x0b, 0x5e, 0x80, 0x97, 0xc5, 0xec, 0x4f, 0xec, 0x88, 0x5d, 0x50, -0x07, 0x35, 0x47, 0xdc, 0x0b, 0x3b, 0x3d, 0xdd, 0x60, 0xaf, 0xa8, 0x5d, 0x81, 0x38, 0x24, -0x25, 0x5d, 0x5c, 0x15, 0xd1, 0xde, 0xb3, 0xab, 0xec, 0x05, 0x69, 0xef, 0x83, 0xed, 0x57, -0x54, 0xb8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xda, 0x9f, 0x2d, 0x7f, 0x36, 0xbb, 0x44, -0x5a, 0x34, 0xe8, 0x7f, 0xbf, 0x03, 0xeb, 0x00, 0x7f, 0x59, 0x68, 0x22, 0x79, 0xcf, 0x73, -0x6c, 0x2c, 0x29, 0xa7, 0xa1, 0x5f, 0x38, 0xa1, 0x1d, 0xf0, 0x20, 0x53, 0xe0, 0x1a, 0x63, -0x14, 0x58, 0x71, 0x10, 0xaa, 0x08, 0x0c, 0x3e, 0x16, 0x1a, 0x60, 0x22, 0x82, 0x7f, 0xba, -0xa4, 0x43, 0xa0, 0xd0, 0xac, 0x1b, 0xd5, 0x6b, 0x64, 0xb5, 0x14, 0x93, 0x31, 0x9e, 0x53, -0x50, 0xd0, 0x57, 0x66, 0xee, 0x5a, 0x4f, 0xfb, 0x03, 0x2a, 0x69, 0x58, 0x76, 0xf1, 0x83, -0xf7, 0x4e, 0xba, 0x8c, 0x42, 0x06, 0x60, 0x5d, 0x6d, 0xce, 0x60, 0x88, 0xae, 0xa4, 0xc3, -0xf1, 0x03, 0xa5, 0x4b, 0x98, 0xa1, 0xff, 0x67, 0xe1, 0xac, 0xa2, 0xb8, 0x62, 0xd7, 0x6f, -0xa0, 0x31, 0xb4, 0xd2, 0x77, 0xaf, 0x21, 0x10, 0x06, 0xc6, 0x9a, 0xff, 0x1d, 0x09, 0x17, -0x0e, 0x5f, 0xf1, 0xaa, 0x54, 0x34, 0x4b, 0x45, 0x8a, 0x87, 0x63, 0xa6, 0xdc, 0xf9, 0x24, -0x30, 0x67, 0xc6, 0xb2, 0xd6, 0x61, 0x33, 0x69, 0xee, 0x50, 0x61, 0x57, 0x28, 0xe7, 0x7e, -0xee, 0xec, 0x3a, 0x5a, 0x73, 0x4e, 0xa8, 0x8d, 0xe4, 0x18, 0xea, 0xec, 0x41, 0x64, 0xc8, -0xe2, 0xe8, 0x66, 0xb6, 0x2d, 0xb6, 0xfb, 0x6a, 0x6c, 0x16, 0xb3, 0xdd, 0x46, 0x43, 0xb9, -0x73, 0x00, 0x6a, 0x71, 0xed, 0x4e, 0x9d, 0x25, 0x1a, 0xc3, 0x3c, 0x4a, 0x95, 0x15, 0x99, -0x35, 0x81, 0x14, 0x02, 0xd6, 0x98, 0x9b, 0xec, 0xd8, 0x23, 0x3b, 0x84, 0x29, 0xaf, 0x0c, -0x99, 0x83, 0xa6, 0x9a, 0x34, 0x4f, 0xfa, 0xe8, 0xd0, 0x3c, 0x4b, 0xd0, 0xfb, 0xb6, 0x68, -0xb8, 0x9e, 0x8f, 0xcd, 0xf7, 0x60, 0x2d, 0x7a, 0x22, 0xe5, 0x7d, 0xab, 0x65, 0x1b, 0x95, -0xa7, 0xa8, 0x7f, 0xb6, 0x77, 0x47, 0x7b, 0x5f, 0x8b, 0x12, 0x72, 0xd0, 0xd4, 0x91, 0xef, -0xde, 0x19, 0x50, 0x3c, 0xa7, 0x8b, 0xc4, 0xa9, 0xb3, 0x23, 0xcb, 0x76, 0xe6, 0x81, 0xf0, -0xc1, 0x04, 0x8f, 0xa3, 0xb8, 0x54, 0x5b, 0x97, 0xac, 0x19, 0xff, 0x3f, 0x55, 0x27, 0x2f, -0xe0, 0x1d, 0x42, 0x9b, 0x57, 0xfc, 0x4b, 0x4e, 0x0f, 0xce, 0x98, 0xa9, 0x43, 0x57, 0x03, -0xbd, 0xe7, 0xc8, 0x94, 0xdf, 0x6e, 0x36, 0x73, 0x32, 0xb4, 0xef, 0x2e, 0x85, 0x7a, 0x6e, -0xfc, 0x6c, 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xf3, 0xe4, 0x9f, 0x3e, 0xdc, 0x68, 0xf3, -0xb5, 0xf3, 0x19, 0x80, 0x92, 0x06, 0x99, 0xa2, 0xe8, 0x6f, 0xff, 0x2e, 0x7f, 0xae, 0x42, -0xa4, 0x5f, 0xfb, 0xd4, 0x0e, 0x81, 0x2b, 0xc3, 0x04, 0xff, 0x2b, 0xb3, 0x74, 0x4e, 0x36, -0x5b, 0x9c, 0x15, 0x00, 0xc6, 0x47, 0x2b, 0xe8, 0x8b, 0x3d, 0xf1, 0x9c, 0x03, 0x9a, 0x58, -0x7f, 0x9b, 0x9c, 0xbf, 0x85, 0x49, 0x79, 0x35, 0x2e, 0x56, 0x7b, 0x41, 0x14, 0x39, 0x47, -0x83, 0x26, 0xaa, 0x07, 0x89, 0x98, 0x11, 0x1b, 0x86, 0xe7, 0x73, 0x7a, 0xd8, 0x7d, 0x78, -0x61, 0x53, 0xe9, 0x79, 0xf5, 0x36, 0x8d, 0x44, 0x92, 0x84, 0xf9, 0x13, 0x50, 0x58, 0x3b, -0xa4, 0x6a, 0x36, 0x65, 0x49, 0x8e, 0x3c, 0x0e, 0xf1, 0x6f, 0xd2, 0x84, 0xc4, 0x7e, 0x8e, -0x3f, 0x39, 0xae, 0x7c, 0x84, 0xf1, 0x63, 0x37, 0x8e, 0x3c, 0xcc, 0x3e, 0x44, 0x81, 0x45, -0xf1, 0x4b, 0xb9, 0xed, 0x6b, 0x36, 0x5d, 0xbb, 0x20, 0x60, 0x1a, 0x0f, 0xa3, 0xaa, 0x55, -0x77, 0x3a, 0xa9, 0xae, 0x37, 0x4d, 0xba, 0xb8, 0x86, 0x6b, 0xbc, 0x08, 0x50, 0xf6, 0xcc, -0xa4, 0xbd, 0x1d, 0x40, 0x72, 0xa5, 0x86, 0xfa, 0xe2, 0x10, 0xae, 0x3d, 0x58, 0x4b, 0x97, -0xf3, 0x43, 0x74, 0xa9, 0x9e, 0xeb, 0x21, 0xb7, 0x01, 0xa4, 0x86, 0x93, 0x97, 0xee, 0x2f, -0x4f, 0x3b, 0x86, 0xa1, 0x41, 0x6f, 0x41, 0x26, 0x90, 0x78, 0x5c, 0x7f, 0x30, 0x38, 0x4b, -0x3f, 0xaa, 0xec, 0xed, 0x5c, 0x6f, 0x0e, 0xad, 0x43, 0x87, 0xfd, 0x93, 0x35, 0xe6, 0x01, -0xef, 0x41, 0x26, 0x90, 0x99, 0x9e, 0xfb, 0x19, 0x5b, 0xad, 0xd2, 0x91, 0x8a, 0xe0, 0x46, -0xaf, 0x65, 0xfa, 0x4f, 0x84, 0xc1, 0xa1, 0x2d, 0xcf, 0x45, 0x8b, 0xd3, 0x85, 0x50, 0x55, -0x7c, 0xf9, 0x67, 0x88, 0xd4, 0x4e, 0xe9, 0xd7, 0x6b, 0x61, 0x54, 0xa1, 0xa4, 0xa6, 0xa2, -0xc2, 0xbf, 0x30, 0x9c, 0x40, 0x9f, 0x5f, 0xd7, 0x69, 0x2b, 0x24, 0x82, 0x5e, 0xd9, 0xd6, -0xa7, 0x12, 0x54, 0x1a, 0xf7, 0x55, 0x9f, 0x76, 0x50, 0xa9, 0x95, 0x84, 0xe6, 0x6b, 0x6d, -0xb5, 0x96, 0x54, 0xd6, 0xcd, 0xb3, 0xa1, 0x9b, 0x46, 0xa7, 0x94, 0x4d, 0xc4, 0x94, 0xb4, -0x98, 0xe3, 0xe1, 0xe2, 0x34, 0xd5, 0x33, 0x16, 0x07, 0x54, 0xcd, 0xb7, 0x77, 0x53, 0xdb, -0x4f, 0x4d, 0x46, 0x9d, 0xe9, 0xd4, 0x9c, 0x8a, 0x36, 0xb6, 0xb8, 0x38, 0x26, 0x6c, 0x0e, -0xff, 0x9c, 0x1b, 0x43, 0x8b, 0x80, 0xcc, 0xb9, 0x3d, 0xda, 0xc7, 0xf1, 0x8a, 0xf2, 0x6d, -0xb8, 0xd7, 0x74, 0x2f, 0x7e, 0x1e, 0xb7, 0xd3, 0x4a, 0xb4, 0xac, 0xfc, 0x79, 0x48, 0x6c, -0xbc, 0x96, 0xb6, 0x94, 0x46, 0x57, 0x2d, 0xb0, 0xa3, 0xfc, 0x1e, 0xb9, 0x52, 0x60, 0x85, -0x2d, 0x41, 0xd0, 0x43, 0x01, 0x1e, 0x1c, 0xd5, 0x7d, 0xfc, 0xf3, 0x96, 0x0d, 0xc7, 0xcb, -0x2a, 0x29, 0x9a, 0x93, 0xdd, 0x88, 0x2d, 0x37, 0x5d, 0xaa, 0xfb, 0x49, 0x68, 0xa0, 0x9c, -0x50, 0x86, 0x7f, 0x68, 0x56, 0x57, 0xf9, 0x79, 0x18, 0x39, 0xd4, 0xe0, 0x01, 0x84, 0x33, -0x61, 0xca, 0xa5, 0xd2, 0xd6, 0xe4, 0xc9, 0x8a, 0x4a, 0x23, 0x44, 0x4e, 0xbc, 0xf0, 0xdc, -0x24, 0xa1, 0xa0, 0xc4, 0xe2, 0x07, 0x3c, 0x10, 0xc4, 0xb5, 0x25, 0x4b, 0x65, 0x63, 0xf4, -0x80, 0xe7, 0xcf, 0x61, 0xb1, 0x71, 0x82, 0x21, 0x87, 0x2c, 0xf5, 0x91, 0x00, 0x32, 0x0c, -0xec, 0xa9, 0xb5, 0x9a, 0x74, 0x85, 0xe3, 0x36, 0x8f, 0x76, 0x4f, 0x9c, 0x6d, 0xce, 0xbc, -0xad, 0x0a, 0x4b, 0xed, 0x76, 0x04, 0xcb, 0xc3, 0xb9, 0x33, 0x9e, 0x01, 0x93, 0x96, 0x69, -0x7d, 0xc5, 0xa2, 0x45, 0x79, 0x9b, 0x04, 0x5c, 0x84, 0x09, 0xed, 0x88, 0x43, 0xc7, 0xab, -0x93, 0x14, 0x26, 0xa1, 0x40, 0xb5, 0xce, 0x4e, 0xbf, 0x2a, 0x42, 0x85, 0x3e, 0x2c, 0x3b, -0x54, 0xe8, 0x12, 0x1f, 0x0e, 0x97, 0x59, 0xb2, 0x27, 0x89, 0xfa, 0xf2, 0xdf, 0x8e, 0x68, -0x59, 0xdc, 0x06, 0xbc, 0xb6, 0x85, 0x0d, 0x06, 0x22, 0xec, 0xb1, 0xcb, 0xe5, 0x04, 0xe6, -0x3d, 0xb3, 0xb0, 0x41, 0x73, 0x08, 0x3f, 0x3c, 0x58, 0x86, 0x63, 0xeb, 0x50, 0xee, 0x1d, -0x2c, 0x37, 0x74, 0xa9, 0xd3, 0x18, 0xa3, 0x47, 0x6e, 0x93, 0x54, 0xad, 0x0a, 0x5d, 0xb8, -0x2a, 0x55, 0x5d, 0x78, 0xf6, 0xee, 0xbe, 0x8e, 0x3c, 0x76, 0x69, 0xb9, 0x40, 0xc2, 0x34, -0xec, 0x2a, 0xb9, 0xed, 0x7e, 0x20, 0xe4, 0x8d, 0x00, 0x38, 0xc7, 0xe6, 0x8f, 0x44, 0xa8, -0x86, 0xce, 0xeb, 0x2a, 0xe9, 0x90, 0xf1, 0x4c, 0xdf, 0x32, 0xfb, 0x73, 0x1b, 0x6d, 0x92, -0x1e, 0x95, 0xfe, 0xb4, 0xdb, 0x65, 0xdf, 0x4d, 0x23, 0x54, 0x89, 0x48, 0xbf, 0x4a, 0x2e, -0x70, 0xd6, 0xd7, 0x62, 0xb4, 0x33, 0x29, 0xb1, 0x3a, 0x33, 0x4c, 0x23, 0x6d, 0xa6, 0x76, -0xa5, 0x21, 0x63, 0x48, 0xe6, 0x90, 0x5d, 0xed, 0x90, 0x95, 0x0b, 0x7a, 0x84, 0xbe, 0xb8, -0x0d, 0x5e, 0x63, 0x0c, 0x62, 0x26, 0x4c, 0x14, 0x5a, 0xb3, 0xac, 0x23, 0xa4, 0x74, 0xa7, -0x6f, 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xa0, 0x28, 0xb7, 0xee, 0x19, 0x38, 0xf1, 0x64, -0x80, 0x82, 0x43, 0xe1, 0x41, 0x27, 0x1f, 0x1f, 0x90, 0x54, 0x7a, 0xd5, 0x23, 0x2e, 0xd1, -0x3d, 0xcb, 0x28, 0xba, 0x58, 0x7f, 0xdc, 0x7c, 0x91, 0x24, 0xe9, 0x28, 0x51, 0x83, 0x6e, -0xc5, 0x56, 0x21, 0x42, 0xed, 0xa0, 0x56, 0x22, 0xa1, 0x40, 0x80, 0x6b, 0xa8, 0xf7, 0x94, -0xca, 0x13, 0x6b, 0x0c, 0x39, 0xd9, 0xfd, 0xe9, 0xf3, 0x6f, 0xa6, 0x9e, 0xfc, 0x70, 0x8a, -0xb3, 0xbc, 0x59, 0x3c, 0x1e, 0x1d, 0x6c, 0xf9, 0x7c, 0xaf, 0xf9, 0x88, 0x71, 0x95, 0xeb, -0x57, 0x00, 0xbd, 0x9f, 0x8c, 0x4f, 0xe1, 0x24, 0x83, 0xc5, 0x22, 0xea, 0xfd, 0xd3, 0x0c, -0xe2, 0x17, 0x18, 0x7c, 0x6a, 0x4c, 0xde, 0x77, 0xb4, 0x53, 0x9b, 0x4c, 0x81, 0xcd, 0x23, -0x60, 0xaa, 0x0e, 0x25, 0x73, 0x9c, 0x02, 0x79, 0x32, 0x30, 0xdf, 0x74, 0xdf, 0x75, 0x19, -0xf4, 0xa5, 0x14, 0x5c, 0xf7, 0x7a, 0xa8, 0xa5, 0x91, 0x84, 0x7c, 0x60, 0x03, 0x06, 0x3b, -0xcd, 0x50, 0xb6, 0x27, 0x9c, 0xfe, 0xb1, 0xdd, 0xcc, 0xd3, 0xb0, 0x59, 0x24, 0xb2, 0xca, -0xe2, 0x1c, 0x81, 0x22, 0x9d, 0x07, 0x8f, 0x8e, 0xb9, 0xbe, 0x4e, 0xfa, 0xfc, 0x39, 0x65, -0xba, 0xbf, 0x9d, 0x12, 0x37, 0x5e, 0x97, 0x7e, 0xf3, 0x89, 0xf5, 0x5d, 0xf5, 0xe3, 0x09, -0x8c, 0x62, 0xb5, 0x20, 0x9d, 0x0c, 0x53, 0x8a, 0x68, 0x1b, 0xd2, 0x8f, 0x75, 0x17, 0x5d, -0xd4, 0xe5, 0xda, 0x75, 0x62, 0x19, 0x14, 0x6a, 0x26, 0x2d, 0xeb, 0xf8, 0xaf, 0x37, 0xf0, -0x6c, 0xa4, 0x55, 0xb1, 0xbc, 0xe2, 0x33, 0xc0, 0x9a, 0xca, 0xb0, 0x11, 0x49, 0x4f, 0x68, -0x9b, 0x3b, 0x6b, 0x3c, 0xcc, 0x13, 0xf6, 0xc7, 0x85, 0x61, 0x68, 0x42, 0xae, 0xbb, 0xdd, -0xcd, 0x45, 0x16, 0x29, 0x1d, 0xea, 0xdb, 0xc8, 0x03, 0x94, 0x3c, 0xee, 0x4f, 0x82, 0x11, -0xc3, 0xec, 0x28, 0xbd, 0x97, 0x05, 0x99, 0xde, 0xd7, 0xbb, 0x5e, 0x22, 0x1f, 0xd4, 0xeb, -0x64, 0xd9, 0x92, 0xd9, 0x85, 0xb7, 0x6a, 0x05, 0x6a, 0xe4, 0x24, 0x41, 0xf1, 0xcd, 0xf0, -0xd8, 0x3f, 0xf8, 0x9e, 0x0e, 0xcd, 0x0b, 0x7a, 0x70, 0x6b, 0x5a, 0x75, 0x0a, 0x6a, 0x33, -0x88, 0xec, 0x17, 0x75, 0x08, 0x70, 0x10, 0x2f, 0x24, 0xcf, 0xc4, 0xe9, 0x42, 0x00, 0x61, -0x94, 0xca, 0x1f, 0x3a, 0x76, 0x06, 0xfa, 0xd2, 0x48, 0x81, 0xf0, 0x77, 0x60, 0x03, 0x45, -0xd9, 0x61, 0xf4, 0xa4, 0x6f, 0x3d, 0xd9, 0x30, 0xc3, 0x04, 0x6b, 0x54, 0x2a, 0xb7, 0xec, -0x3b, 0xf4, 0x4b, 0xf5, 0x68, 0x52, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xa5, -0xa9, 0xb1, 0xe0, 0x23, 0xc4, 0x0a, 0x77, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xa5, 0xa9, 0xb1, -0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0xeb, 0x54, 0x0b, -0x75, 0x68, 0x52, 0x07, 0x8c, 0x9a, 0x97, 0x8d, 0x79, 0x70, 0x62, 0x46, 0xef, 0x5c, 0x1b, -0x95, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x67, 0x4c, 0x1a, 0xb6, -0xcf, 0xfd, 0x78, 0x53, 0x24, 0xab, 0xb5, 0xc9, 0xf1, 0x60, 0x23, 0xa5, 0xc8, 0x12, 0x87, -0x6d, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xc7, 0x0c, 0x9a, 0x97, 0xac, -0xda, 0x36, 0xee, 0x5e, 0x3e, 0xdf, 0x1d, 0xb8, 0xf2, 0x66, 0x2f, 0xbd, 0xf8, 0x72, 0x47, -0xed, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8c, 0x7b, 0x55, 0x09, 0x90, 0xa2, 0xc6, 0xef, -0x3d, 0xf8, 0x53, 0x24, 0xab, 0xd4, 0x2a, 0xb7, 0xec, 0x5a, 0x36, 0xee, 0x5e, 0x3e, 0xdf, -0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x59, 0x30, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x53, 0x05, 0x69, -0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, 0x19, 0xb0, 0xe2, 0x27, 0xcc, 0xfb, 0x74, -0x4b, 0x14, 0x8b, 0x94, 0x8b, 0x75, 0x68, 0x33, 0xc5, 0x08, 0x92, 0x87, 0x8c, 0x9a, 0xb6, -0xcf, 0x1c, 0xba, 0xd7, 0x0d, 0x98, 0xb2, 0xe6, 0x2f, 0xdc, 0x1b, 0x95, 0x89, 0x71, 0x60, -0x23, 0xc4, 0x0a, 0x96, 0x8f, 0x9c, 0xba, 0xf6, 0x6e, 0x3f, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, -0x26, 0xaf, 0xbd, 0xf8, 0x72, 0x66, 0x2f, 0xdc, 0x1b, 0xb4, 0xcb, 0x14, 0x8b, 0x94, 0xaa, -0xb7, 0xcd, 0xf9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6f, 0x3d, 0xd9, 0x30, 0xe2, 0x27, 0xcc, -0xfb, 0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x70, 0x43, 0x04, 0x6b, 0x35, 0xc9, 0xf1, -0x60, 0x23, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, 0x6d, 0x58, 0x32, 0xe6, 0x2f, 0xbd, -0xf8, 0x72, 0x66, 0x4e, 0x1e, 0xbe, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x1d, 0x99, 0x91, 0xa0, -0xa3, 0xc4, 0x0a, 0x77, 0x4d, 0x18, 0x93, 0xa4, 0xab, 0xd4, 0x0b, 0x75, 0x49, 0x10, 0xa2, -0xc6, 0xef, 0x3d, 0xf8, 0x53, 0x24, 0xab, 0xb5, 0xe8, 0x33, 0xe4, 0x4a, 0x16, 0xae, 0xde, -0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xb3, 0xc5, 0x08, 0x73, 0x45, 0xe9, 0x31, 0xc1, 0xe1, 0x21, -0xa1, 0xa1, 0xa1, 0xc0, 0x02, 0x86, 0x6f, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, 0x93, 0xa4, 0xca, -0x16, 0xae, 0xde, 0x1f, 0x9d, 0x99, 0xb0, 0xe2, 0x46, 0xef, 0x3d, 0xf8, 0x72, 0x47, 0x0c, -0x9a, 0xb6, 0xcf, 0xfd, 0x59, 0x11, 0xa0, 0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0x08, 0x92, 0x87, -0x6d, 0x39, 0xf0, 0x43, 0x04, 0x8a, 0x96, 0xae, 0xde, 0x3e, 0xdf, 0x1d, 0x99, 0x91, 0xa0, -0xc2, 0x06, 0x6f, 0x3d, 0xf8, 0x72, 0x47, 0x0c, 0x9a, 0x97, 0x8d, 0x98, 0x93, 0x85, 0x88, -0x73, 0x45, 0xe9, 0x31, 0xe0, 0x23, 0xa5, 0xa9, 0xd0, 0x03, 0x84, 0x8a, 0x96, 0xae, 0xde, -0x1f, 0xbc, 0xdb, 0x15, 0xa8, 0xd2, 0x26, 0xce, 0xff, 0x5d, 0x19, 0x91, 0x81, 0x80, 0x82, -0x67, 0x2d, 0xd8, 0x13, 0xa4, 0xab, 0xd4, 0x0b, 0x94, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, -0xa3, 0xa5, 0xc8, 0xf3, 0x45, 0xe9, 0x50, 0x22, 0xc6, 0xef, 0x5c, 0x3a, 0xd7, 0x0d, 0x98, -0x93, 0x85, 0x88, 0x73, 0x64, 0x4a, 0xf7, 0x4d, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0x0a, 0x96, -0xae, 0xde, 0x3e, 0xfe, 0x7e, 0x7e, 0x7e, 0x5f, 0x3c, 0xfa, 0x76, 0x4f, 0xfd, 0x78, 0x72, -0x66, 0x2f, 0xbd, 0xd9, 0x30, 0xc3, 0xe5, 0x48, 0x12, 0x87, 0x8c, 0x7b, 0x55, 0x28, 0xd2, -0x07, 0x8c, 0x9a, 0x97, 0xac, 0xda, 0x17, 0x8d, 0x79, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x54, -0x0b, 0x94, 0x8b, 0x94, 0xaa, 0xd6, 0x2e, 0xbf, 0xfc, 0x5b, 0x15, 0xa8, 0xd2, 0x26, 0xaf, -0xdc, 0x1b, 0xb4, 0xea, 0x37, 0xec, 0x3b, 0xf4, 0x6a, 0x37, 0xcd, 0x18, 0x93, 0x85, 0x69, -0x31, 0xc1, 0xe1, 0x40, 0xe3, 0x25, 0xc8, 0x12, 0x87, 0x8c, 0x9a, 0xb6, 0xcf, 0xfd, 0x59, -0x11, 0xa0, 0xc2, 0x06, 0x8e, 0x7f, 0x5d, 0x38, 0xf2, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x37, -0xec, 0x5a, 0x36, 0xee, 0x3f, 0xfc, 0x7a, 0x76, 0x4f, 0x1c, 0x9b, 0x95, 0x89, 0x71, 0x41, -0x00, 0x63, 0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x0f, 0x9c, 0xba, 0xd7, 0x0d, 0x98, 0x93, 0x85, -0x69, 0x31, 0xc1, 0x00, 0x82, 0x86, 0x8e, 0x9e, 0xbe, 0xdf, 0x3c, 0xfa, 0x57, 0x2c, 0xda, -0x36, 0xee, 0x3f, 0xfc, 0x5b, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8e, 0x7f, 0x5d, -0x38, 0xf2, 0x47, 0xed, 0x58, 0x13, 0xa4, 0xca, 0xf7, 0x4d, 0xf9, 0x51, 0x01, 0x80, 0x63, -0x44, 0xeb, 0x54, 0x2a, 0xd6, 0x2e, 0xbf, 0xdd, 0x19, 0x91, 0xa0, 0xa3, 0xa5, 0xa9, 0xb1, -0xe0, 0x42, 0x06, 0x8e, 0x7f, 0x5d, 0x19, 0x91, 0xa0, 0xa3, 0xc4, 0x0a, 0x96, 0x8f, 0x7d, -0x78, 0x72, 0x47, 0x0c, 0x7b, 0x74, 0x6a, 0x56, 0x2e, 0xde, 0x1f, 0xbc, 0xfa, 0x57, 0x0d, -0x79, 0x51, 0x01, 0x61, 0x21, 0xa1, 0xc0, 0xe3, 0x25, 0xa9, 0xb1, 0xc1, 0xe1, 0x40, 0x02, -0x67, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0x93, 0xa4, 0xab, 0xd4, 0x2a, 0xd6, 0x0f, 0x9c, 0x9b, -0xb4, 0xcb, 0x14, 0xaa, 0xb7, 0xcd, 0xf9, 0x51, 0x20, 0xa3, 0xc4, 0xeb, 0x35, 0xc9, 0xf1, -0x60, 0x42, 0x06, 0x8e, 0x7f, 0x7c, 0x7a, 0x76, 0x6e, 0x3f, 0xfc, 0x7a, 0x76, 0x6e, 0x5e, -0x3e, 0xfe, 0x7e, 0x5f, 0x3c, 0xdb, 0x15, 0x89, 0x71, 0x41, 0xe1, 0x21, 0xc0, 0xe3, 0x44, -0xeb, 0x54, 0x2a, 0xb7, 0xcd, 0xf9, 0x70, 0x62, 0x27, 0xad, 0xd8, 0x32, 0xc7, 0x0c, 0x7b, -0x74, 0x4b, 0x14, 0xaa, 0xb7, 0xec, 0x3b, 0xd5, 0x28, 0xd2, 0x07, 0x6d, 0x39, 0xd1, 0x20, -0xc2, 0xe7, 0x4c, 0x1a, 0x97, 0x8d, 0x98, 0xb2, 0xc7, 0x0c, 0x59, 0x28, 0xf3, 0x9b }; +#include "progmem.h" + +#define FIRMWARE_LENGTH 4094 // clang-format off +const uint8_t firmware_data[FIRMWARE_LENGTH] PROGMEM = { + 0x01, 0x04, 0x8E, 0x96, 0x6E, 0x77, 0x3E, 0xFE, 0x7E, 0x5F, 0x1D, 0xB8, 0xF2, 0x66, 0x4E, 0xFF, + 0x5D, 0x19, 0xB0, 0xC2, 0x04, 0x69, 0x54, 0x2A, 0xD6, 0x2E, 0xBF, 0xDD, 0x19, 0xB0, 0xC3, 0xE5, + 0x29, 0xB1, 0xE0, 0x23, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x79, + 0x51, 0x20, 0xC7, 0x06, 0x8E, 0x7C, 0x7C, 0x7A, 0x76, 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0x0E, + 0x9E, 0xBE, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xA5, 0xA1, 0xA9, 0xD0, 0x22, 0xC6, 0xEF, 0x5C, 0x1B, + 0x95, 0x89, 0x90, 0xA2, 0xA7, 0xCC, 0xFB, 0x55, 0x28, 0xB3, 0xE4, 0x4A, 0xF7, 0x6C, 0x3B, 0xF4, + 0x6A, 0x56, 0x2E, 0xDE, 0x1F, 0x9D, 0xB8, 0xD3, 0x05, 0x88, 0x92, 0xA6, 0xCE, 0x1E, 0xBE, 0xDF, + 0x1D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x5C, 0x07, 0x11, 0x5D, 0x98, 0x0B, 0x9D, 0x94, 0x97, 0xEE, + 0x4E, 0x45, 0x33, 0x6B, 0x44, 0xC7, 0x29, 0x56, 0x27, 0x30, 0xC6, 0xA7, 0xD5, 0xF2, 0x56, 0xDF, + 0xB4, 0x38, 0x62, 0xCB, 0xA0, 0xB6, 0xE3, 0x0F, 0x84, 0x06, 0x24, 0x05, 0x65, 0x6F, 0x76, 0x89, + 0xB5, 0x77, 0x41, 0x27, 0x82, 0x66, 0x65, 0x82, 0xCC, 0xD5, 0xE6, 0x20, 0xD5, 0x27, 0x17, 0xC5, + 0xF8, 0x03, 0x23, 0x7C, 0x5F, 0x64, 0xA5, 0x1D, 0xC1, 0xD6, 0x36, 0xCB, 0x4C, 0xD4, 0xDB, 0x66, + 0xD7, 0x8B, 0xB1, 0x99, 0x7E, 0x6F, 0x4C, 0x36, 0x40, 0x06, 0xD6, 0xEB, 0xD7, 0xA2, 0xE4, 0xF4, + 0x95, 0x51, 0x5A, 0x54, 0x96, 0xD5, 0x53, 0x44, 0xD7, 0x8C, 0xE0, 0xB9, 0x40, 0x68, 0xD2, 0x18, + 0xE9, 0xDD, 0x9A, 0x23, 0x92, 0x48, 0xEE, 0x7F, 0x43, 0xAF, 0xEA, 0x77, 0x38, 0x84, 0x8C, 0x0A, + 0x72, 0xAF, 0x69, 0xF8, 0xDD, 0xF1, 0x24, 0x83, 0xA3, 0xF8, 0x4A, 0xBF, 0xF5, 0x94, 0x13, 0xDB, + 0xBB, 0xD8, 0xB4, 0xB3, 0xA0, 0xFB, 0x45, 0x50, 0x60, 0x30, 0x59, 0x12, 0x31, 0x71, 0xA2, 0xD3, + 0x13, 0xE7, 0xFA, 0xE7, 0xCE, 0x0F, 0x63, 0x15, 0x0B, 0x6B, 0x94, 0xBB, 0x37, 0x83, 0x26, 0x05, + 0x9D, 0xFB, 0x46, 0x92, 0xFC, 0x0A, 0x15, 0xD1, 0x0D, 0x73, 0x92, 0xD6, 0x8C, 0x1B, 0x8C, 0xB8, + 0x55, 0x8A, 0xCE, 0xBD, 0xFE, 0x8E, 0xFC, 0xED, 0x09, 0x12, 0x83, 0x91, 0x82, 0x51, 0x31, 0x23, + 0xFB, 0xB4, 0x0C, 0x76, 0xAD, 0x7C, 0xD9, 0xB4, 0x4B, 0xB2, 0x67, 0x14, 0x09, 0x9C, 0x7F, 0x0C, + 0x18, 0xBA, 0x3B, 0xD6, 0x8E, 0x14, 0x2A, 0xE4, 0x1B, 0x52, 0x9F, 0x2B, 0x7D, 0xE1, 0xFB, 0x6A, + 0x33, 0x02, 0xFA, 0xAC, 0x5A, 0xF2, 0x3E, 0x88, 0x7E, 0xAE, 0xD1, 0xF3, 0x78, 0xE8, 0x05, 0xD1, + 0xE3, 0xDC, 0x21, 0xF6, 0xE1, 0x9A, 0xBD, 0x17, 0x0E, 0xD9, 0x46, 0x9B, 0x88, 0x03, 0xEA, 0xF6, + 0x66, 0xBE, 0x0E, 0x1B, 0x50, 0x49, 0x96, 0x40, 0x97, 0xF1, 0xF1, 0xE4, 0x80, 0xA6, 0x6E, 0xE8, + 0x77, 0x34, 0xBF, 0x29, 0x40, 0x44, 0xC2, 0xFF, 0x4E, 0x98, 0xD3, 0x9C, 0xA3, 0x32, 0x2B, 0x76, + 0x51, 0x04, 0x09, 0xE7, 0xA9, 0xD1, 0xA6, 0x32, 0xB1, 0x23, 0x53, 0xE2, 0x47, 0xAB, 0xD6, 0xF5, + 0x69, 0x5C, 0x3E, 0x5F, 0xFA, 0xAE, 0x45, 0x20, 0xE5, 0xD2, 0x44, 0xFF, 0x39, 0x32, 0x6D, 0xFD, + 0x27, 0x57, 0x5C, 0xFD, 0xF0, 0xDE, 0xC1, 0xB5, 0x99, 0xE5, 0xF5, 0x1C, 0x77, 0x01, 0x75, 0xC5, + 0x6D, 0x58, 0x92, 0xF2, 0xB2, 0x47, 0x00, 0x01, 0x26, 0x96, 0x7A, 0x30, 0xFF, 0xB7, 0xF0, 0xEF, + 0x77, 0xC1, 0x8A, 0x5D, 0xDC, 0xC0, 0xD1, 0x29, 0x30, 0x1E, 0x77, 0x38, 0x7A, 0x94, 0xF1, 0xB8, + 0x7A, 0x7E, 0xEF, 0xA4, 0xD1, 0xAC, 0x31, 0x4A, 0xF2, 0x5D, 0x64, 0x3D, 0xB2, 0xE2, 0xF0, 0x08, + 0x99, 0xFC, 0x70, 0xEE, 0x24, 0xA7, 0x7E, 0xEE, 0x1E, 0x20, 0x69, 0x7D, 0x44, 0xBF, 0x87, 0x42, + 0xDF, 0x88, 0x3B, 0x0C, 0xDA, 0x42, 0xC9, 0x04, 0xF9, 0x45, 0x50, 0xFC, 0x83, 0x8F, 0x11, 0x6A, + 0x72, 0xBC, 0x99, 0x95, 0xF0, 0xAC, 0x3D, 0xA7, 0x3B, 0xCD, 0x1C, 0xE2, 0x88, 0x79, 0x37, 0x11, + 0x5F, 0x39, 0x89, 0x95, 0x0A, 0x16, 0x84, 0x7A, 0xF6, 0x8A, 0xA4, 0x28, 0xE4, 0xED, 0x83, 0x80, + 0x3B, 0xB1, 0x23, 0xA5, 0x03, 0x10, 0xF4, 0x66, 0xEA, 0xBB, 0x0C, 0x0F, 0xC5, 0xEC, 0x6C, 0x69, + 0xC5, 0xD3, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0x99, 0x88, 0x76, 0x08, 0xA0, 0xA8, 0x95, 0x7C, 0xD8, + 0x38, 0x6D, 0xCD, 0x59, 0x02, 0x51, 0x4B, 0xF1, 0xB5, 0x2B, 0x50, 0xE3, 0xB6, 0xBD, 0xD0, 0x72, + 0xCF, 0x9E, 0xFD, 0x6E, 0xBB, 0x44, 0xC8, 0x24, 0x8A, 0x77, 0x18, 0x8A, 0x13, 0x06, 0xEF, 0x97, + 0x7D, 0xFA, 0x81, 0xF0, 0x31, 0xE6, 0xFA, 0x77, 0xED, 0x31, 0x06, 0x31, 0x5B, 0x54, 0x8A, 0x9F, + 0x30, 0x68, 0xDB, 0xE2, 0x40, 0xF8, 0x4E, 0x73, 0xFA, 0xAB, 0x74, 0x8B, 0x10, 0x58, 0x13, 0xDC, + 0xD2, 0xE6, 0x78, 0xD1, 0x32, 0x2E, 0x8A, 0x9F, 0x2C, 0x58, 0x06, 0x48, 0x27, 0xC5, 0xA9, 0x5E, + 0x81, 0x47, 0x89, 0x46, 0x21, 0x91, 0x03, 0x70, 0xA4, 0x3E, 0x88, 0x9C, 0xDA, 0x33, 0x0A, 0xCE, + 0xBC, 0x8B, 0x8E, 0xCF, 0x9F, 0xD3, 0x71, 0x80, 0x43, 0xCF, 0x6B, 0xA9, 0x51, 0x83, 0x76, 0x30, + 0x82, 0xC5, 0x6A, 0x85, 0x39, 0x11, 0x50, 0x1A, 0x82, 0xDC, 0x1E, 0x1C, 0xD5, 0x7D, 0xA9, 0x71, + 0x99, 0x33, 0x47, 0x19, 0x97, 0xB3, 0x5A, 0xB1, 0xDF, 0xED, 0xA4, 0xF2, 0xE6, 0x26, 0x84, 0xA2, + 0x28, 0x9A, 0x9E, 0xDF, 0xA6, 0x6A, 0xF4, 0xD6, 0xFC, 0x2E, 0x5B, 0x9D, 0x1A, 0x2A, 0x27, 0x68, + 0xFB, 0xC1, 0x83, 0x21, 0x4B, 0x90, 0xE0, 0x36, 0xDD, 0x5B, 0x31, 0x42, 0x55, 0xA0, 0x13, 0xF7, + 0xD0, 0x89, 0x53, 0x71, 0x99, 0x57, 0x09, 0x29, 0xC5, 0xF3, 0x21, 0xF8, 0x37, 0x2F, 0x40, 0xF3, + 0xD4, 0xAF, 0x16, 0x08, 0x36, 0x02, 0xFC, 0x77, 0xC5, 0x8B, 0x04, 0x90, 0x56, 0xB9, 0xC9, 0x67, + 0x9A, 0x99, 0xE8, 0x00, 0xD3, 0x86, 0xFF, 0x97, 0x2D, 0x08, 0xE9, 0xB7, 0xB3, 0x91, 0xBC, 0xDF, + 0x45, 0xC6, 0xED, 0x0F, 0x8C, 0x4C, 0x1E, 0xE6, 0x5B, 0x6E, 0x38, 0x30, 0xE4, 0xAA, 0xE3, 0x95, + 0xDE, 0xB9, 0xE4, 0x9A, 0xF5, 0xB2, 0x55, 0x9A, 0x87, 0x9B, 0xF6, 0x6A, 0xB2, 0xF2, 0x77, 0x9A, + 0x31, 0xF4, 0x7A, 0x31, 0xD1, 0x1D, 0x04, 0xC0, 0x7C, 0x32, 0xA2, 0x9E, 0x9A, 0xF5, 0x62, 0xF8, + 0x27, 0x8D, 0xBF, 0x51, 0xFF, 0xD3, 0xDF, 0x64, 0x37, 0x3F, 0x2A, 0x6F, 0x76, 0x3A, 0x7D, 0x77, + 0x06, 0x9E, 0x77, 0x7F, 0x5E, 0xEB, 0x32, 0x51, 0xF9, 0x16, 0x66, 0x9A, 0x09, 0xF3, 0xB0, 0x08, + 0xA4, 0x70, 0x96, 0x46, 0x30, 0xFF, 0xDA, 0x4F, 0xE9, 0x1B, 0xED, 0x8D, 0xF8, 0x74, 0x1F, 0x31, + 0x92, 0xB3, 0x73, 0x17, 0x36, 0xDB, 0x91, 0x30, 0xD6, 0x88, 0x55, 0x6B, 0x34, 0x77, 0x87, 0x7A, + 0xE7, 0xEE, 0x06, 0xC6, 0x1C, 0x8C, 0x19, 0x0C, 0x48, 0x46, 0x23, 0x5E, 0x9C, 0x07, 0x5C, 0xBF, + 0xB4, 0x7E, 0xD6, 0x4F, 0x74, 0x9C, 0xE2, 0xC5, 0x50, 0x8B, 0xC5, 0x8B, 0x15, 0x90, 0x60, 0x62, + 0x57, 0x29, 0xD0, 0x13, 0x43, 0xA1, 0x80, 0x88, 0x91, 0x00, 0x44, 0xC7, 0x4D, 0x19, 0x86, 0xCC, + 0x2F, 0x2A, 0x75, 0x5A, 0xFC, 0xEB, 0x97, 0x2A, 0x70, 0xE3, 0x78, 0xD8, 0x91, 0xB0, 0x4F, 0x99, + 0x07, 0xA3, 0x95, 0xEA, 0x24, 0x21, 0xD5, 0xDE, 0x51, 0x20, 0x93, 0x27, 0x0A, 0x30, 0x73, 0xA8, + 0xFF, 0x8A, 0x97, 0xE9, 0xA7, 0x6A, 0x8E, 0x0D, 0xE8, 0xF0, 0xDF, 0xEC, 0xEA, 0xB4, 0x6C, 0x1D, + 0x39, 0x2A, 0x62, 0x2D, 0x3D, 0x5A, 0x8B, 0x65, 0xF8, 0x90, 0x05, 0x2E, 0x7E, 0x91, 0x2C, 0x78, + 0xEF, 0x8E, 0x7A, 0xC1, 0x2F, 0xAC, 0x78, 0xEE, 0xAF, 0x28, 0x45, 0x06, 0x4C, 0x26, 0xAF, 0x3B, + 0xA2, 0xDB, 0xA3, 0x93, 0x06, 0xB5, 0x3C, 0xA5, 0xD8, 0xEE, 0x8F, 0xAF, 0x25, 0xCC, 0x3F, 0x85, + 0x68, 0x48, 0xA9, 0x62, 0xCC, 0x97, 0x8F, 0x7F, 0x2A, 0xEA, 0xE0, 0x15, 0x0A, 0xAD, 0x62, 0x07, + 0xBD, 0x45, 0xF8, 0x41, 0xD8, 0x36, 0xCB, 0x4C, 0xDB, 0x6E, 0xE6, 0x3A, 0xE7, 0xDA, 0x15, 0xE9, + 0x29, 0x1E, 0x12, 0x10, 0xA0, 0x14, 0x2C, 0x0E, 0x3D, 0xF4, 0xBF, 0x39, 0x41, 0x92, 0x75, 0x0B, + 0x25, 0x7B, 0xA3, 0xCE, 0x39, 0x9C, 0x15, 0x64, 0xC8, 0xFA, 0x3D, 0xEF, 0x73, 0x27, 0xFE, 0x26, + 0x2E, 0xCE, 0xDA, 0x6E, 0xFD, 0x71, 0x8E, 0xDD, 0xFE, 0x76, 0xEE, 0xDC, 0x12, 0x5C, 0x02, 0xC5, + 0x3A, 0x4E, 0x4E, 0x4F, 0xBF, 0xCA, 0x40, 0x15, 0xC7, 0x6E, 0x8D, 0x41, 0xF1, 0x10, 0xE0, 0x4F, + 0x7E, 0x97, 0x7F, 0x1C, 0xAE, 0x47, 0x8E, 0x6B, 0xB1, 0x25, 0x31, 0xB0, 0x73, 0xC7, 0x1B, 0x97, + 0x79, 0xF9, 0x80, 0xD3, 0x66, 0x22, 0x30, 0x07, 0x74, 0x1E, 0xE4, 0xD0, 0x80, 0x21, 0xD6, 0xEE, + 0x6B, 0x6C, 0x4F, 0xBF, 0xF5, 0xB7, 0xD9, 0x09, 0x87, 0x2F, 0xA9, 0x14, 0xBE, 0x27, 0xD9, 0x72, + 0x50, 0x01, 0xD4, 0x13, 0x73, 0xA6, 0xA7, 0x51, 0x02, 0x75, 0x25, 0xE1, 0xB3, 0x45, 0x34, 0x7D, + 0xA8, 0x8E, 0xEB, 0xF3, 0x16, 0x49, 0xCB, 0x4F, 0x8C, 0xA1, 0xB9, 0x36, 0x85, 0x39, 0x75, 0x5D, + 0x08, 0x00, 0xAE, 0xEB, 0xF6, 0xEA, 0xD7, 0x13, 0x3A, 0x21, 0x5A, 0x5F, 0x30, 0x84, 0x52, 0x26, + 0x95, 0xC9, 0x14, 0xF2, 0x57, 0x55, 0x6B, 0xB1, 0x10, 0xC2, 0xE1, 0xBD, 0x3B, 0x51, 0xC0, 0xB7, + 0x55, 0x4C, 0x71, 0x12, 0x26, 0xC7, 0x0D, 0xF9, 0x51, 0xA4, 0x38, 0x02, 0x05, 0x7F, 0xB8, 0xF1, + 0x72, 0x4B, 0xBF, 0x71, 0x89, 0x14, 0xF3, 0x77, 0x38, 0xD9, 0x71, 0x24, 0xF3, 0x00, 0x11, 0xA1, + 0xD8, 0xD4, 0x69, 0x27, 0x08, 0x37, 0x35, 0xC9, 0x11, 0x9D, 0x90, 0x1C, 0x0E, 0xE7, 0x1C, 0xFF, + 0x2D, 0x1E, 0xE8, 0x92, 0xE1, 0x18, 0x10, 0x95, 0x7C, 0xE0, 0x80, 0xF4, 0x96, 0x43, 0x21, 0xF9, + 0x75, 0x21, 0x64, 0x38, 0xDD, 0x9F, 0x1E, 0x95, 0x16, 0xDA, 0x56, 0x1D, 0x4F, 0x9A, 0x53, 0xB2, + 0xE2, 0xE4, 0x18, 0xCB, 0x6B, 0x1A, 0x65, 0xEB, 0x56, 0xC6, 0x3B, 0xE5, 0xFE, 0xD8, 0x26, 0x3F, + 0x3A, 0x84, 0x59, 0x72, 0x66, 0xA2, 0xF3, 0x75, 0xFF, 0xFB, 0x60, 0xB3, 0x22, 0xAD, 0x3F, 0x2D, + 0x6B, 0xF9, 0xEB, 0xEA, 0x05, 0x7C, 0xD8, 0x8F, 0x6D, 0x2C, 0x98, 0x9E, 0x2B, 0x93, 0xF1, 0x5E, + 0x46, 0xF0, 0x87, 0x49, 0x29, 0x73, 0x68, 0xD7, 0x7F, 0xF9, 0xF0, 0xE5, 0x7D, 0xDB, 0x1D, 0x75, + 0x19, 0xF3, 0xC4, 0x58, 0x9B, 0x17, 0x88, 0xA8, 0x92, 0xE0, 0xBE, 0xBD, 0x8B, 0x1D, 0x8D, 0x9F, + 0x56, 0x76, 0xAD, 0xAF, 0x29, 0xE2, 0xD9, 0xD5, 0x52, 0xF6, 0xB5, 0x56, 0x35, 0x57, 0x3A, 0xC8, + 0xE1, 0x56, 0x43, 0x19, 0x94, 0xD3, 0x04, 0x9B, 0x6D, 0x35, 0xD8, 0x0B, 0x5F, 0x4D, 0x19, 0x8E, + 0xEC, 0xFA, 0x64, 0x91, 0x0A, 0x72, 0x20, 0x2B, 0xBC, 0x1A, 0x4A, 0xFE, 0x8B, 0xFD, 0xBB, 0xED, + 0x1B, 0x23, 0xEA, 0xAD, 0x72, 0x82, 0xA1, 0x29, 0x99, 0x71, 0xBD, 0xF0, 0x95, 0xC1, 0x03, 0xDD, + 0x7B, 0xC2, 0xB2, 0x3C, 0x28, 0x54, 0xD3, 0x68, 0xA4, 0x72, 0xC8, 0x66, 0x96, 0xE0, 0xD1, 0xD8, + 0x7F, 0xF8, 0xD1, 0x26, 0x2B, 0xF7, 0xAD, 0xBA, 0x55, 0xCA, 0x15, 0xB9, 0x32, 0xC3, 0xE5, 0x88, + 0x97, 0x8E, 0x5C, 0xFB, 0x92, 0x25, 0x8B, 0xBF, 0xA2, 0x45, 0x55, 0x7A, 0xA7, 0x6F, 0x8B, 0x57, + 0x5B, 0xCF, 0x0E, 0xCB, 0x1D, 0xFB, 0x20, 0x82, 0x77, 0xA8, 0x8C, 0xCC, 0x16, 0xCE, 0x1D, 0xFA, + 0xDE, 0xCC, 0x0B, 0x62, 0xFE, 0xCC, 0xE1, 0xB7, 0xF0, 0xC3, 0x81, 0x64, 0x73, 0x40, 0xA0, 0xC2, + 0x4D, 0x89, 0x11, 0x75, 0x33, 0x55, 0x33, 0x8D, 0xE8, 0x4A, 0xFD, 0xEA, 0x6E, 0x30, 0x0B, 0xD7, + 0x31, 0x2C, 0xDE, 0x47, 0xE3, 0xBF, 0xF8, 0x55, 0x42, 0xE2, 0x7F, 0x59, 0xE5, 0x17, 0xEF, 0x99, + 0x34, 0x69, 0x91, 0xB1, 0x23, 0x8E, 0x20, 0x87, 0x2D, 0xA8, 0xFE, 0xD5, 0x8A, 0xF3, 0x84, 0x3A, + 0xF0, 0x37, 0xE4, 0x09, 0x00, 0x54, 0xEE, 0x67, 0x49, 0x93, 0xE4, 0x81, 0x70, 0xE3, 0x90, 0x4D, + 0xEF, 0xFE, 0x41, 0xB7, 0x99, 0x7B, 0xC1, 0x83, 0xBA, 0x62, 0x12, 0x6F, 0x7D, 0xDE, 0x6B, 0xAF, + 0xDA, 0x16, 0xF9, 0x55, 0x51, 0xEE, 0xA6, 0x0C, 0x2B, 0x02, 0xA3, 0xFD, 0x8D, 0xFB, 0x30, 0x17, + 0xE4, 0x6F, 0xDF, 0x36, 0x71, 0xC4, 0xCA, 0x87, 0x25, 0x48, 0xB0, 0x47, 0xEC, 0xEA, 0xB4, 0xBF, + 0xA5, 0x4D, 0x9B, 0x9F, 0x02, 0x93, 0xC4, 0xE3, 0xE4, 0xE8, 0x42, 0x2D, 0x68, 0x81, 0x15, 0x0A, + 0xEB, 0x84, 0x5B, 0xD6, 0xA8, 0x74, 0xFB, 0x7D, 0x1D, 0xCB, 0x2C, 0xDA, 0x46, 0x2A, 0x76, 0x62, + 0xCE, 0xBC, 0x5C, 0x9E, 0x8B, 0xE7, 0xCF, 0xBE, 0x78, 0xF5, 0x7C, 0xEB, 0xB3, 0x3A, 0x9C, 0xAA, + 0x6F, 0xCC, 0x72, 0xD1, 0x59, 0xF2, 0x11, 0x23, 0xD6, 0x3F, 0x48, 0xD1, 0xB7, 0xCE, 0xB0, 0xBF, + 0xCB, 0xEA, 0x80, 0xDE, 0x57, 0xD4, 0x5E, 0x97, 0x2F, 0x75, 0xD1, 0x50, 0x8E, 0x80, 0x2C, 0x66, + 0x79, 0xBF, 0x72, 0x4B, 0xBD, 0x8A, 0x81, 0x6C, 0xD3, 0xE1, 0x01, 0xDC, 0xD2, 0x15, 0x26, 0xC5, + 0x36, 0xDA, 0x2C, 0x1A, 0xC0, 0x27, 0x94, 0xED, 0xB7, 0x9B, 0x85, 0x0B, 0x5E, 0x80, 0x97, 0xC5, + 0xEC, 0x4F, 0xEC, 0x88, 0x5D, 0x50, 0x07, 0x35, 0x47, 0xDC, 0x0B, 0x3B, 0x3D, 0xDD, 0x60, 0xAF, + 0xA8, 0x5D, 0x81, 0x38, 0x24, 0x25, 0x5D, 0x5C, 0x15, 0xD1, 0xDE, 0xB3, 0xAB, 0xEC, 0x05, 0x69, + 0xEF, 0x83, 0xED, 0x57, 0x54, 0xB8, 0x64, 0x64, 0x11, 0x16, 0x32, 0x69, 0xDA, 0x9F, 0x2D, 0x7F, + 0x36, 0xBB, 0x44, 0x5A, 0x34, 0xE8, 0x7F, 0xBF, 0x03, 0xEB, 0x00, 0x7F, 0x59, 0x68, 0x22, 0x79, + 0xCF, 0x73, 0x6C, 0x2C, 0x29, 0xA7, 0xA1, 0x5F, 0x38, 0xA1, 0x1D, 0xF0, 0x20, 0x53, 0xE0, 0x1A, + 0x63, 0x14, 0x58, 0x71, 0x10, 0xAA, 0x08, 0x0C, 0x3E, 0x16, 0x1A, 0x60, 0x22, 0x82, 0x7F, 0xBA, + 0xA4, 0x43, 0xA0, 0xD0, 0xAC, 0x1B, 0xD5, 0x6B, 0x64, 0xB5, 0x14, 0x93, 0x31, 0x9E, 0x53, 0x50, + 0xD0, 0x57, 0x66, 0xEE, 0x5A, 0x4F, 0xFB, 0x03, 0x2A, 0x69, 0x58, 0x76, 0xF1, 0x83, 0xF7, 0x4E, + 0xBA, 0x8C, 0x42, 0x06, 0x60, 0x5D, 0x6D, 0xCE, 0x60, 0x88, 0xAE, 0xA4, 0xC3, 0xF1, 0x03, 0xA5, + 0x4B, 0x98, 0xA1, 0xFF, 0x67, 0xE1, 0xAC, 0xA2, 0xB8, 0x62, 0xD7, 0x6F, 0xA0, 0x31, 0xB4, 0xD2, + 0x77, 0xAF, 0x21, 0x10, 0x06, 0xC6, 0x9A, 0xFF, 0x1D, 0x09, 0x17, 0x0E, 0x5F, 0xF1, 0xAA, 0x54, + 0x34, 0x4B, 0x45, 0x8A, 0x87, 0x63, 0xA6, 0xDC, 0xF9, 0x24, 0x30, 0x67, 0xC6, 0xB2, 0xD6, 0x61, + 0x33, 0x69, 0xEE, 0x50, 0x61, 0x57, 0x28, 0xE7, 0x7E, 0xEE, 0xEC, 0x3A, 0x5A, 0x73, 0x4E, 0xA8, + 0x8D, 0xE4, 0x18, 0xEA, 0xEC, 0x41, 0x64, 0xC8, 0xE2, 0xE8, 0x66, 0xB6, 0x2D, 0xB6, 0xFB, 0x6A, + 0x6C, 0x16, 0xB3, 0xDD, 0x46, 0x43, 0xB9, 0x73, 0x00, 0x6A, 0x71, 0xED, 0x4E, 0x9D, 0x25, 0x1A, + 0xC3, 0x3C, 0x4A, 0x95, 0x15, 0x99, 0x35, 0x81, 0x14, 0x02, 0xD6, 0x98, 0x9B, 0xEC, 0xD8, 0x23, + 0x3B, 0x84, 0x29, 0xAF, 0x0C, 0x99, 0x83, 0xA6, 0x9A, 0x34, 0x4F, 0xFA, 0xE8, 0xD0, 0x3C, 0x4B, + 0xD0, 0xFB, 0xB6, 0x68, 0xB8, 0x9E, 0x8F, 0xCD, 0xF7, 0x60, 0x2D, 0x7A, 0x22, 0xE5, 0x7D, 0xAB, + 0x65, 0x1B, 0x95, 0xA7, 0xA8, 0x7F, 0xB6, 0x77, 0x47, 0x7B, 0x5F, 0x8B, 0x12, 0x72, 0xD0, 0xD4, + 0x91, 0xEF, 0xDE, 0x19, 0x50, 0x3C, 0xA7, 0x8B, 0xC4, 0xA9, 0xB3, 0x23, 0xCB, 0x76, 0xE6, 0x81, + 0xF0, 0xC1, 0x04, 0x8F, 0xA3, 0xB8, 0x54, 0x5B, 0x97, 0xAC, 0x19, 0xFF, 0x3F, 0x55, 0x27, 0x2F, + 0xE0, 0x1D, 0x42, 0x9B, 0x57, 0xFC, 0x4B, 0x4E, 0x0F, 0xCE, 0x98, 0xA9, 0x43, 0x57, 0x03, 0xBD, + 0xE7, 0xC8, 0x94, 0xDF, 0x6E, 0x36, 0x73, 0x32, 0xB4, 0xEF, 0x2E, 0x85, 0x7A, 0x6E, 0xFC, 0x6C, + 0x18, 0x82, 0x75, 0x35, 0x90, 0x07, 0xF3, 0xE4, 0x9F, 0x3E, 0xDC, 0x68, 0xF3, 0xB5, 0xF3, 0x19, + 0x80, 0x92, 0x06, 0x99, 0xA2, 0xE8, 0x6F, 0xFF, 0x2E, 0x7F, 0xAE, 0x42, 0xA4, 0x5F, 0xFB, 0xD4, + 0x0E, 0x81, 0x2B, 0xC3, 0x04, 0xFF, 0x2B, 0xB3, 0x74, 0x4E, 0x36, 0x5B, 0x9C, 0x15, 0x00, 0xC6, + 0x47, 0x2B, 0xE8, 0x8B, 0x3D, 0xF1, 0x9C, 0x03, 0x9A, 0x58, 0x7F, 0x9B, 0x9C, 0xBF, 0x85, 0x49, + 0x79, 0x35, 0x2E, 0x56, 0x7B, 0x41, 0x14, 0x39, 0x47, 0x83, 0x26, 0xAA, 0x07, 0x89, 0x98, 0x11, + 0x1B, 0x86, 0xE7, 0x73, 0x7A, 0xD8, 0x7D, 0x78, 0x61, 0x53, 0xE9, 0x79, 0xF5, 0x36, 0x8D, 0x44, + 0x92, 0x84, 0xF9, 0x13, 0x50, 0x58, 0x3B, 0xA4, 0x6A, 0x36, 0x65, 0x49, 0x8E, 0x3C, 0x0E, 0xF1, + 0x6F, 0xD2, 0x84, 0xC4, 0x7E, 0x8E, 0x3F, 0x39, 0xAE, 0x7C, 0x84, 0xF1, 0x63, 0x37, 0x8E, 0x3C, + 0xCC, 0x3E, 0x44, 0x81, 0x45, 0xF1, 0x4B, 0xB9, 0xED, 0x6B, 0x36, 0x5D, 0xBB, 0x20, 0x60, 0x1A, + 0x0F, 0xA3, 0xAA, 0x55, 0x77, 0x3A, 0xA9, 0xAE, 0x37, 0x4D, 0xBA, 0xB8, 0x86, 0x6B, 0xBC, 0x08, + 0x50, 0xF6, 0xCC, 0xA4, 0xBD, 0x1D, 0x40, 0x72, 0xA5, 0x86, 0xFA, 0xE2, 0x10, 0xAE, 0x3D, 0x58, + 0x4B, 0x97, 0xF3, 0x43, 0x74, 0xA9, 0x9E, 0xEB, 0x21, 0xB7, 0x01, 0xA4, 0x86, 0x93, 0x97, 0xEE, + 0x2F, 0x4F, 0x3B, 0x86, 0xA1, 0x41, 0x6F, 0x41, 0x26, 0x90, 0x78, 0x5C, 0x7F, 0x30, 0x38, 0x4B, + 0x3F, 0xAA, 0xEC, 0xED, 0x5C, 0x6F, 0x0E, 0xAD, 0x43, 0x87, 0xFD, 0x93, 0x35, 0xE6, 0x01, 0xEF, + 0x41, 0x26, 0x90, 0x99, 0x9E, 0xFB, 0x19, 0x5B, 0xAD, 0xD2, 0x91, 0x8A, 0xE0, 0x46, 0xAF, 0x65, + 0xFA, 0x4F, 0x84, 0xC1, 0xA1, 0x2D, 0xCF, 0x45, 0x8B, 0xD3, 0x85, 0x50, 0x55, 0x7C, 0xF9, 0x67, + 0x88, 0xD4, 0x4E, 0xE9, 0xD7, 0x6B, 0x61, 0x54, 0xA1, 0xA4, 0xA6, 0xA2, 0xC2, 0xBF, 0x30, 0x9C, + 0x40, 0x9F, 0x5F, 0xD7, 0x69, 0x2B, 0x24, 0x82, 0x5E, 0xD9, 0xD6, 0xA7, 0x12, 0x54, 0x1A, 0xF7, + 0x55, 0x9F, 0x76, 0x50, 0xA9, 0x95, 0x84, 0xE6, 0x6B, 0x6D, 0xB5, 0x96, 0x54, 0xD6, 0xCD, 0xB3, + 0xA1, 0x9B, 0x46, 0xA7, 0x94, 0x4D, 0xC4, 0x94, 0xB4, 0x98, 0xE3, 0xE1, 0xE2, 0x34, 0xD5, 0x33, + 0x16, 0x07, 0x54, 0xCD, 0xB7, 0x77, 0x53, 0xDB, 0x4F, 0x4D, 0x46, 0x9D, 0xE9, 0xD4, 0x9C, 0x8A, + 0x36, 0xB6, 0xB8, 0x38, 0x26, 0x6C, 0x0E, 0xFF, 0x9C, 0x1B, 0x43, 0x8B, 0x80, 0xCC, 0xB9, 0x3D, + 0xDA, 0xC7, 0xF1, 0x8A, 0xF2, 0x6D, 0xB8, 0xD7, 0x74, 0x2F, 0x7E, 0x1E, 0xB7, 0xD3, 0x4A, 0xB4, + 0xAC, 0xFC, 0x79, 0x48, 0x6C, 0xBC, 0x96, 0xB6, 0x94, 0x46, 0x57, 0x2D, 0xB0, 0xA3, 0xFC, 0x1E, + 0xB9, 0x52, 0x60, 0x85, 0x2D, 0x41, 0xD0, 0x43, 0x01, 0x1E, 0x1C, 0xD5, 0x7D, 0xFC, 0xF3, 0x96, + 0x0D, 0xC7, 0xCB, 0x2A, 0x29, 0x9A, 0x93, 0xDD, 0x88, 0x2D, 0x37, 0x5D, 0xAA, 0xFB, 0x49, 0x68, + 0xA0, 0x9C, 0x50, 0x86, 0x7F, 0x68, 0x56, 0x57, 0xF9, 0x79, 0x18, 0x39, 0xD4, 0xE0, 0x01, 0x84, + 0x33, 0x61, 0xCA, 0xA5, 0xD2, 0xD6, 0xE4, 0xC9, 0x8A, 0x4A, 0x23, 0x44, 0x4E, 0xBC, 0xF0, 0xDC, + 0x24, 0xA1, 0xA0, 0xC4, 0xE2, 0x07, 0x3C, 0x10, 0xC4, 0xB5, 0x25, 0x4B, 0x65, 0x63, 0xF4, 0x80, + 0xE7, 0xCF, 0x61, 0xB1, 0x71, 0x82, 0x21, 0x87, 0x2C, 0xF5, 0x91, 0x00, 0x32, 0x0C, 0xEC, 0xA9, + 0xB5, 0x9A, 0x74, 0x85, 0xE3, 0x36, 0x8F, 0x76, 0x4F, 0x9C, 0x6D, 0xCE, 0xBC, 0xAD, 0x0A, 0x4B, + 0xED, 0x76, 0x04, 0xCB, 0xC3, 0xB9, 0x33, 0x9E, 0x01, 0x93, 0x96, 0x69, 0x7D, 0xC5, 0xA2, 0x45, + 0x79, 0x9B, 0x04, 0x5C, 0x84, 0x09, 0xED, 0x88, 0x43, 0xC7, 0xAB, 0x93, 0x14, 0x26, 0xA1, 0x40, + 0xB5, 0xCE, 0x4E, 0xBF, 0x2A, 0x42, 0x85, 0x3E, 0x2C, 0x3B, 0x54, 0xE8, 0x12, 0x1F, 0x0E, 0x97, + 0x59, 0xB2, 0x27, 0x89, 0xFA, 0xF2, 0xDF, 0x8E, 0x68, 0x59, 0xDC, 0x06, 0xBC, 0xB6, 0x85, 0x0D, + 0x06, 0x22, 0xEC, 0xB1, 0xCB, 0xE5, 0x04, 0xE6, 0x3D, 0xB3, 0xB0, 0x41, 0x73, 0x08, 0x3F, 0x3C, + 0x58, 0x86, 0x63, 0xEB, 0x50, 0xEE, 0x1D, 0x2C, 0x37, 0x74, 0xA9, 0xD3, 0x18, 0xA3, 0x47, 0x6E, + 0x93, 0x54, 0xAD, 0x0A, 0x5D, 0xB8, 0x2A, 0x55, 0x5D, 0x78, 0xF6, 0xEE, 0xBE, 0x8E, 0x3C, 0x76, + 0x69, 0xB9, 0x40, 0xC2, 0x34, 0xEC, 0x2A, 0xB9, 0xED, 0x7E, 0x20, 0xE4, 0x8D, 0x00, 0x38, 0xC7, + 0xE6, 0x8F, 0x44, 0xA8, 0x86, 0xCE, 0xEB, 0x2A, 0xE9, 0x90, 0xF1, 0x4C, 0xDF, 0x32, 0xFB, 0x73, + 0x1B, 0x6D, 0x92, 0x1E, 0x95, 0xFE, 0xB4, 0xDB, 0x65, 0xDF, 0x4D, 0x23, 0x54, 0x89, 0x48, 0xBF, + 0x4A, 0x2E, 0x70, 0xD6, 0xD7, 0x62, 0xB4, 0x33, 0x29, 0xB1, 0x3A, 0x33, 0x4C, 0x23, 0x6D, 0xA6, + 0x76, 0xA5, 0x21, 0x63, 0x48, 0xE6, 0x90, 0x5D, 0xED, 0x90, 0x95, 0x0B, 0x7A, 0x84, 0xBE, 0xB8, + 0x0D, 0x5E, 0x63, 0x0C, 0x62, 0x26, 0x4C, 0x14, 0x5A, 0xB3, 0xAC, 0x23, 0xA4, 0x74, 0xA7, 0x6F, + 0x33, 0x30, 0x05, 0x60, 0x01, 0x42, 0xA0, 0x28, 0xB7, 0xEE, 0x19, 0x38, 0xF1, 0x64, 0x80, 0x82, + 0x43, 0xE1, 0x41, 0x27, 0x1F, 0x1F, 0x90, 0x54, 0x7A, 0xD5, 0x23, 0x2E, 0xD1, 0x3D, 0xCB, 0x28, + 0xBA, 0x58, 0x7F, 0xDC, 0x7C, 0x91, 0x24, 0xE9, 0x28, 0x51, 0x83, 0x6E, 0xC5, 0x56, 0x21, 0x42, + 0xED, 0xA0, 0x56, 0x22, 0xA1, 0x40, 0x80, 0x6B, 0xA8, 0xF7, 0x94, 0xCA, 0x13, 0x6B, 0x0C, 0x39, + 0xD9, 0xFD, 0xE9, 0xF3, 0x6F, 0xA6, 0x9E, 0xFC, 0x70, 0x8A, 0xB3, 0xBC, 0x59, 0x3C, 0x1E, 0x1D, + 0x6C, 0xF9, 0x7C, 0xAF, 0xF9, 0x88, 0x71, 0x95, 0xEB, 0x57, 0x00, 0xBD, 0x9F, 0x8C, 0x4F, 0xE1, + 0x24, 0x83, 0xC5, 0x22, 0xEA, 0xFD, 0xD3, 0x0C, 0xE2, 0x17, 0x18, 0x7C, 0x6A, 0x4C, 0xDE, 0x77, + 0xB4, 0x53, 0x9B, 0x4C, 0x81, 0xCD, 0x23, 0x60, 0xAA, 0x0E, 0x25, 0x73, 0x9C, 0x02, 0x79, 0x32, + 0x30, 0xDF, 0x74, 0xDF, 0x75, 0x19, 0xF4, 0xA5, 0x14, 0x5C, 0xF7, 0x7A, 0xA8, 0xA5, 0x91, 0x84, + 0x7C, 0x60, 0x03, 0x06, 0x3B, 0xCD, 0x50, 0xB6, 0x27, 0x9C, 0xFE, 0xB1, 0xDD, 0xCC, 0xD3, 0xB0, + 0x59, 0x24, 0xB2, 0xCA, 0xE2, 0x1C, 0x81, 0x22, 0x9D, 0x07, 0x8F, 0x8E, 0xB9, 0xBE, 0x4E, 0xFA, + 0xFC, 0x39, 0x65, 0xBA, 0xBF, 0x9D, 0x12, 0x37, 0x5E, 0x97, 0x7E, 0xF3, 0x89, 0xF5, 0x5D, 0xF5, + 0xE3, 0x09, 0x8C, 0x62, 0xB5, 0x20, 0x9D, 0x0C, 0x53, 0x8A, 0x68, 0x1B, 0xD2, 0x8F, 0x75, 0x17, + 0x5D, 0xD4, 0xE5, 0xDA, 0x75, 0x62, 0x19, 0x14, 0x6A, 0x26, 0x2D, 0xEB, 0xF8, 0xAF, 0x37, 0xF0, + 0x6C, 0xA4, 0x55, 0xB1, 0xBC, 0xE2, 0x33, 0xC0, 0x9A, 0xCA, 0xB0, 0x11, 0x49, 0x4F, 0x68, 0x9B, + 0x3B, 0x6B, 0x3C, 0xCC, 0x13, 0xF6, 0xC7, 0x85, 0x61, 0x68, 0x42, 0xAE, 0xBB, 0xDD, 0xCD, 0x45, + 0x16, 0x29, 0x1D, 0xEA, 0xDB, 0xC8, 0x03, 0x94, 0x3C, 0xEE, 0x4F, 0x82, 0x11, 0xC3, 0xEC, 0x28, + 0xBD, 0x97, 0x05, 0x99, 0xDE, 0xD7, 0xBB, 0x5E, 0x22, 0x1F, 0xD4, 0xEB, 0x64, 0xD9, 0x92, 0xD9, + 0x85, 0xB7, 0x6A, 0x05, 0x6A, 0xE4, 0x24, 0x41, 0xF1, 0xCD, 0xF0, 0xD8, 0x3F, 0xF8, 0x9E, 0x0E, + 0xCD, 0x0B, 0x7A, 0x70, 0x6B, 0x5A, 0x75, 0x0A, 0x6A, 0x33, 0x88, 0xEC, 0x17, 0x75, 0x08, 0x70, + 0x10, 0x2F, 0x24, 0xCF, 0xC4, 0xE9, 0x42, 0x00, 0x61, 0x94, 0xCA, 0x1F, 0x3A, 0x76, 0x06, 0xFA, + 0xD2, 0x48, 0x81, 0xF0, 0x77, 0x60, 0x03, 0x45, 0xD9, 0x61, 0xF4, 0xA4, 0x6F, 0x3D, 0xD9, 0x30, + 0xC3, 0x04, 0x6B, 0x54, 0x2A, 0xB7, 0xEC, 0x3B, 0xF4, 0x4B, 0xF5, 0x68, 0x52, 0x26, 0xCE, 0xFF, + 0x5D, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x23, 0xC4, 0x0A, 0x77, 0x4D, 0xF9, 0x51, + 0x20, 0xA3, 0xA5, 0xA9, 0xB1, 0xC1, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0x91, 0xA0, 0xA3, + 0xC4, 0xEB, 0x54, 0x0B, 0x75, 0x68, 0x52, 0x07, 0x8C, 0x9A, 0x97, 0x8D, 0x79, 0x70, 0x62, 0x46, + 0xEF, 0x5C, 0x1B, 0x95, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x67, 0x4C, + 0x1A, 0xB6, 0xCF, 0xFD, 0x78, 0x53, 0x24, 0xAB, 0xB5, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0x12, + 0x87, 0x6D, 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x6D, 0x58, 0x32, 0xC7, 0x0C, 0x9A, 0x97, 0xAC, + 0xDA, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x1D, 0xB8, 0xF2, 0x66, 0x2F, 0xBD, 0xF8, 0x72, 0x47, 0xED, + 0x58, 0x13, 0x85, 0x88, 0x92, 0x87, 0x8C, 0x7B, 0x55, 0x09, 0x90, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, + 0x53, 0x24, 0xAB, 0xD4, 0x2A, 0xB7, 0xEC, 0x5A, 0x36, 0xEE, 0x5E, 0x3E, 0xDF, 0x3C, 0xFA, 0x76, + 0x4F, 0xFD, 0x59, 0x30, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x53, 0x05, 0x69, 0x31, 0xC1, 0x00, 0x82, + 0x86, 0x8E, 0x7F, 0x5D, 0x19, 0xB0, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0x8B, 0x94, 0x8B, + 0x75, 0x68, 0x33, 0xC5, 0x08, 0x92, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0x1C, 0xBA, 0xD7, 0x0D, 0x98, + 0xB2, 0xE6, 0x2F, 0xDC, 0x1B, 0x95, 0x89, 0x71, 0x60, 0x23, 0xC4, 0x0A, 0x96, 0x8F, 0x9C, 0xBA, + 0xF6, 0x6E, 0x3F, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, 0x26, 0xAF, 0xBD, 0xF8, 0x72, 0x66, 0x2F, 0xDC, + 0x1B, 0xB4, 0xCB, 0x14, 0x8B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x01, 0x80, 0x82, 0x86, 0x6F, + 0x3D, 0xD9, 0x30, 0xE2, 0x27, 0xCC, 0xFB, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x70, 0x43, + 0x04, 0x6B, 0x35, 0xC9, 0xF1, 0x60, 0x23, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x58, + 0x32, 0xE6, 0x2F, 0xBD, 0xF8, 0x72, 0x66, 0x4E, 0x1E, 0xBE, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x1D, + 0x99, 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x77, 0x4D, 0x18, 0x93, 0xA4, 0xAB, 0xD4, 0x0B, 0x75, 0x49, + 0x10, 0xA2, 0xC6, 0xEF, 0x3D, 0xF8, 0x53, 0x24, 0xAB, 0xB5, 0xE8, 0x33, 0xE4, 0x4A, 0x16, 0xAE, + 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xB3, 0xC5, 0x08, 0x73, 0x45, 0xE9, 0x31, 0xC1, 0xE1, 0x21, + 0xA1, 0xA1, 0xA1, 0xC0, 0x02, 0x86, 0x6F, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0xA4, 0xCA, 0x16, + 0xAE, 0xDE, 0x1F, 0x9D, 0x99, 0xB0, 0xE2, 0x46, 0xEF, 0x3D, 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0xB6, + 0xCF, 0xFD, 0x59, 0x11, 0xA0, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0x08, 0x92, 0x87, 0x6D, 0x39, 0xF0, + 0x43, 0x04, 0x8A, 0x96, 0xAE, 0xDE, 0x3E, 0xDF, 0x1D, 0x99, 0x91, 0xA0, 0xC2, 0x06, 0x6F, 0x3D, + 0xF8, 0x72, 0x47, 0x0C, 0x9A, 0x97, 0x8D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x45, 0xE9, 0x31, 0xE0, + 0x23, 0xA5, 0xA9, 0xD0, 0x03, 0x84, 0x8A, 0x96, 0xAE, 0xDE, 0x1F, 0xBC, 0xDB, 0x15, 0xA8, 0xD2, + 0x26, 0xCE, 0xFF, 0x5D, 0x19, 0x91, 0x81, 0x80, 0x82, 0x67, 0x2D, 0xD8, 0x13, 0xA4, 0xAB, 0xD4, + 0x0B, 0x94, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xA5, 0xC8, 0xF3, 0x45, 0xE9, 0x50, 0x22, + 0xC6, 0xEF, 0x5C, 0x3A, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x88, 0x73, 0x64, 0x4A, 0xF7, 0x4D, 0xF9, + 0x51, 0x20, 0xA3, 0xC4, 0x0A, 0x96, 0xAE, 0xDE, 0x3E, 0xFE, 0x7E, 0x7E, 0x7E, 0x5F, 0x3C, 0xFA, + 0x76, 0x4F, 0xFD, 0x78, 0x72, 0x66, 0x2F, 0xBD, 0xD9, 0x30, 0xC3, 0xE5, 0x48, 0x12, 0x87, 0x8C, + 0x7B, 0x55, 0x28, 0xD2, 0x07, 0x8C, 0x9A, 0x97, 0xAC, 0xDA, 0x17, 0x8D, 0x79, 0x51, 0x20, 0xA3, + 0xC4, 0xEB, 0x54, 0x0B, 0x94, 0x8B, 0x94, 0xAA, 0xD6, 0x2E, 0xBF, 0xFC, 0x5B, 0x15, 0xA8, 0xD2, + 0x26, 0xAF, 0xDC, 0x1B, 0xB4, 0xEA, 0x37, 0xEC, 0x3B, 0xF4, 0x6A, 0x37, 0xCD, 0x18, 0x93, 0x85, + 0x69, 0x31, 0xC1, 0xE1, 0x40, 0xE3, 0x25, 0xC8, 0x12, 0x87, 0x8C, 0x9A, 0xB6, 0xCF, 0xFD, 0x59, + 0x11, 0xA0, 0xC2, 0x06, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x37, 0xEC, + 0x5A, 0x36, 0xEE, 0x3F, 0xFC, 0x7A, 0x76, 0x4F, 0x1C, 0x9B, 0x95, 0x89, 0x71, 0x41, 0x00, 0x63, + 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x0F, 0x9C, 0xBA, 0xD7, 0x0D, 0x98, 0x93, 0x85, 0x69, 0x31, 0xC1, + 0x00, 0x82, 0x86, 0x8E, 0x9E, 0xBE, 0xDF, 0x3C, 0xFA, 0x57, 0x2C, 0xDA, 0x36, 0xEE, 0x3F, 0xFC, + 0x5B, 0x15, 0x89, 0x71, 0x41, 0x00, 0x82, 0x86, 0x8E, 0x7F, 0x5D, 0x38, 0xF2, 0x47, 0xED, 0x58, + 0x13, 0xA4, 0xCA, 0xF7, 0x4D, 0xF9, 0x51, 0x01, 0x80, 0x63, 0x44, 0xEB, 0x54, 0x2A, 0xD6, 0x2E, + 0xBF, 0xDD, 0x19, 0x91, 0xA0, 0xA3, 0xA5, 0xA9, 0xB1, 0xE0, 0x42, 0x06, 0x8E, 0x7F, 0x5D, 0x19, + 0x91, 0xA0, 0xA3, 0xC4, 0x0A, 0x96, 0x8F, 0x7D, 0x78, 0x72, 0x47, 0x0C, 0x7B, 0x74, 0x6A, 0x56, + 0x2E, 0xDE, 0x1F, 0xBC, 0xFA, 0x57, 0x0D, 0x79, 0x51, 0x01, 0x61, 0x21, 0xA1, 0xC0, 0xE3, 0x25, + 0xA9, 0xB1, 0xC1, 0xE1, 0x40, 0x02, 0x67, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0x93, 0xA4, 0xAB, 0xD4, + 0x2A, 0xD6, 0x0F, 0x9C, 0x9B, 0xB4, 0xCB, 0x14, 0xAA, 0xB7, 0xCD, 0xF9, 0x51, 0x20, 0xA3, 0xC4, + 0xEB, 0x35, 0xC9, 0xF1, 0x60, 0x42, 0x06, 0x8E, 0x7F, 0x7C, 0x7A, 0x76, 0x6E, 0x3F, 0xFC, 0x7A, + 0x76, 0x6E, 0x5E, 0x3E, 0xFE, 0x7E, 0x5F, 0x3C, 0xDB, 0x15, 0x89, 0x71, 0x41, 0xE1, 0x21, 0xC0, + 0xE3, 0x44, 0xEB, 0x54, 0x2A, 0xB7, 0xCD, 0xF9, 0x70, 0x62, 0x27, 0xAD, 0xD8, 0x32, 0xC7, 0x0C, + 0x7B, 0x74, 0x4B, 0x14, 0xAA, 0xB7, 0xEC, 0x3B, 0xD5, 0x28, 0xD2, 0x07, 0x6D, 0x39, 0xD1, 0x20, + 0xC2, 0xE7, 0x4C, 0x1A, 0x97, 0x8D, 0x98, 0xB2, 0xC7, 0x0C, 0x59, 0x28, 0xF3, 0x9B +}; From 2ec268bd21c6bb8d6afbd4908fb0289b0d1c6bd2 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sun, 24 Oct 2021 20:39:41 +0100 Subject: [PATCH 0028/1136] Begin to carve out platform/protocol API - Migrate keyboard_* calls (#14888) --- quantum/keyboard.c | 6 ++++++ quantum/main.c | 15 ++++++++++++++- tmk_core/protocol/chibios/chibios.c | 15 +++------------ tmk_core/protocol/lufa/lufa.c | 19 ++++--------------- tmk_core/protocol/vusb/protocol.c | 7 ------- 5 files changed, 27 insertions(+), 35 deletions(-) diff --git a/quantum/keyboard.c b/quantum/keyboard.c index f2a0889c12bc..f8e36994d298 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -335,6 +335,12 @@ void keyboard_init(void) { #ifdef DIP_SWITCH_ENABLE dip_switch_init(); #endif +#ifdef SLEEP_LED_ENABLE + sleep_led_init(); +#endif +#ifdef VIRTSER_ENABLE + virtser_init(); +#endif #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE) debug_enable = true; diff --git a/quantum/main.c b/quantum/main.c index 2cbcd73d8ffa..a896a67c6674 100644 --- a/quantum/main.c +++ b/quantum/main.c @@ -20,7 +20,18 @@ void platform_setup(void); void protocol_setup(void); void protocol_init(void); -void protocol_task(void); +void protocol_pre_task(void); +void protocol_post_task(void); + +// Bodge as refactoring vusb sucks.... +void protocol_task(void) __attribute__((weak)); +void protocol_task(void) { + protocol_pre_task(); + + keyboard_task(); + + protocol_post_task(); +} /** \brief Main * @@ -30,8 +41,10 @@ int main(void) __attribute__((weak)); int main(void) { platform_setup(); protocol_setup(); + keyboard_setup(); protocol_init(); + keyboard_init(); /* Main loop */ while (true) { diff --git a/tmk_core/protocol/chibios/chibios.c b/tmk_core/protocol/chibios/chibios.c index c860328c807e..98b3305089e7 100644 --- a/tmk_core/protocol/chibios/chibios.c +++ b/tmk_core/protocol/chibios/chibios.c @@ -138,8 +138,6 @@ void protocol_setup(void) { // TESTING // chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); - - keyboard_setup(); } void protocol_init(void) { @@ -176,18 +174,10 @@ void protocol_init(void) { print("USB configured.\n"); - /* init TMK modules */ - keyboard_init(); host_set_driver(driver); - -#ifdef SLEEP_LED_ENABLE - sleep_led_init(); -#endif - - print("Keyboard start.\n"); } -void protocol_task(void) { +void protocol_pre_task(void) { usb_event_queue_task(); #if !defined(NO_USB_STARTUP_CHECK) @@ -210,8 +200,9 @@ void protocol_task(void) { # endif /* MOUSEKEY_ENABLE */ } #endif +} - keyboard_task(); +void protocol_post_task(void) { #ifdef CONSOLE_ENABLE console_task(); #endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 753762358d57..80781d2f370b 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -1070,7 +1070,6 @@ void protocol_setup(void) { setup_mcu(); usb_device_state_init(); - keyboard_setup(); } void protocol_init(void) { @@ -1095,21 +1094,11 @@ void protocol_init(void) { #else USB_USBTask(); #endif - /* init modules */ - keyboard_init(); - host_set_driver(&lufa_driver); -#ifdef SLEEP_LED_ENABLE - sleep_led_init(); -#endif -#ifdef VIRTSER_ENABLE - virtser_init(); -#endif - - print("Keyboard start.\n"); + host_set_driver(&lufa_driver); } -void protocol_task(void) { +void protocol_pre_task(void) { #if !defined(NO_USB_STARTUP_CHECK) if (USB_DeviceState == DEVICE_STATE_Suspended) { print("[s]"); @@ -1133,9 +1122,9 @@ void protocol_task(void) { suspend_wakeup_init(); } #endif +} - keyboard_task(); - +void protocol_post_task(void) { #ifdef MIDI_ENABLE MIDI_Device_USBTask(&USB_MIDI_Interface); #endif diff --git a/tmk_core/protocol/vusb/protocol.c b/tmk_core/protocol/vusb/protocol.c index 89dc795b2165..947c3383f1c1 100644 --- a/tmk_core/protocol/vusb/protocol.c +++ b/tmk_core/protocol/vusb/protocol.c @@ -111,22 +111,15 @@ void protocol_setup(void) { // clock prescaler clock_prescale_set(clock_div_1); #endif - keyboard_setup(); } void protocol_init(void) { setup_usb(); sei(); - keyboard_init(); - host_set_driver(vusb_driver()); wait_ms(50); - -#ifdef SLEEP_LED_ENABLE - sleep_led_init(); -#endif } void protocol_task(void) { From 0002acd4a319d4b692fd9665f14b60e4936dcd83 Mon Sep 17 00:00:00 2001 From: coliss86 Date: Mon, 25 Oct 2021 00:32:42 +0200 Subject: [PATCH 0029/1136] Fix Typo in documentation (#14942) --- docs/cli_tab_complete.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli_tab_complete.md b/docs/cli_tab_complete.md index 2217d4fd3bc6..200477624ed9 100644 --- a/docs/cli_tab_complete.md +++ b/docs/cli_tab_complete.md @@ -18,7 +18,7 @@ If you put `qmk_firmware` into another location you will need to adjust this pat If you want the tab completion available to all users of the system you can add a symlink to the `qmk_tab_complete.sh` script: - `ln -s ~/qmk_firmware/util/qmk_tab_complete.sh /etc/profile.d/qmk_tab_complete.sh` + ln -s ~/qmk_firmware/util/qmk_tab_complete.sh /etc/profile.d/qmk_tab_complete.sh ### System Wide Copy From 6e8eb2cf542d38332ef460d4f88eed281aed9188 Mon Sep 17 00:00:00 2001 From: Lucas Rodrigues Date: Mon, 25 Oct 2021 02:05:12 -0300 Subject: [PATCH 0030/1136] [Keyboard] temporary fix for SpiderIsland 78 (#14935) (#14941) --- keyboards/spiderisland/split78/config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/keyboards/spiderisland/split78/config.h b/keyboards/spiderisland/split78/config.h index e15e5d193d38..b67b3fafffcc 100644 --- a/keyboards/spiderisland/split78/config.h +++ b/keyboards/spiderisland/split78/config.h @@ -35,3 +35,5 @@ along with this program. If not, see . #define BACKLIGHT_BREATHING #define DEBOUNCE 50 + +#define I2C_START_RETRY_COUNT 1 From 028edfc2df5bc291773e8c7cc19ed38c9b9470dc Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Mon, 25 Oct 2021 21:14:46 -0700 Subject: [PATCH 0031/1136] Remove unused KEYBOARD_LOCK_ENABLE from rules (#14920) --- keyboards/dk60/rules.mk | 1 - keyboards/fjlabs/ad65/rules.mk | 1 - keyboards/fjlabs/bks65/rules.mk | 1 - keyboards/fjlabs/bks65solder/rules.mk | 1 - keyboards/fjlabs/bolsa65/rules.mk | 1 - keyboards/fjlabs/kf87/rules.mk | 1 - keyboards/fjlabs/ldk65/rules.mk | 1 - keyboards/fjlabs/ready100/rules.mk | 1 - keyboards/fjlabs/tf60ansi/rules.mk | 1 - keyboards/fjlabs/tf60v2/rules.mk | 1 - keyboards/fjlabs/tf65rgbv2/rules.mk | 4 ++-- keyboards/gh60/revc/keymaps/danbee/rules.mk | 1 - keyboards/gh60/revc/rules.mk | 1 - keyboards/handwired/arrow_pad/rules.mk | 1 - keyboards/handwired/retro_refit/rules.mk | 1 - keyboards/idb/idb_60/rules.mk | 1 - keyboards/jd40/rules.mk | 1 - keyboards/kc60/keymaps/stanleylai/rules.mk | 2 -- keyboards/kc60/keymaps/wigguno/rules.mk | 2 -- keyboards/kc60/rules.mk | 1 - keyboards/keybee/keybee65/rules.mk | 1 - keyboards/lucid/alexa/rules.mk | 1 - keyboards/lucid/kbd8x_hs/rules.mk | 1 - keyboards/lucid/phantom_hs/rules.mk | 1 - keyboards/lucid/phantom_solder/rules.mk | 1 - keyboards/ok60/rules.mk | 1 - keyboards/thevankeyboards/minivan/keymaps/danbee/rules.mk | 1 - keyboards/undead60m/rules.mk | 1 - keyboards/wolf/ts60/rules.mk | 4 ++-- show_options.mk | 1 - users/bcat/rules.mk | 1 - 31 files changed, 4 insertions(+), 35 deletions(-) diff --git a/keyboards/dk60/rules.mk b/keyboards/dk60/rules.mk index c34ea2677ea3..c3c93b823cdc 100644 --- a/keyboards/dk60/rules.mk +++ b/keyboards/dk60/rules.mk @@ -19,5 +19,4 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes UNICODE_ENABLE = yes diff --git a/keyboards/fjlabs/ad65/rules.mk b/keyboards/fjlabs/ad65/rules.mk index 58e569b7393f..4f8739075909 100644 --- a/keyboards/fjlabs/ad65/rules.mk +++ b/keyboards/fjlabs/ad65/rules.mk @@ -22,4 +22,3 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes diff --git a/keyboards/fjlabs/bks65/rules.mk b/keyboards/fjlabs/bks65/rules.mk index 37fccd0e9b25..3dc41b847c80 100644 --- a/keyboards/fjlabs/bks65/rules.mk +++ b/keyboards/fjlabs/bks65/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 65_ansi diff --git a/keyboards/fjlabs/bks65solder/rules.mk b/keyboards/fjlabs/bks65solder/rules.mk index 37fccd0e9b25..3dc41b847c80 100644 --- a/keyboards/fjlabs/bks65solder/rules.mk +++ b/keyboards/fjlabs/bks65solder/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 65_ansi diff --git a/keyboards/fjlabs/bolsa65/rules.mk b/keyboards/fjlabs/bolsa65/rules.mk index 956c2f9ce0d3..cc8bfbe21048 100644 --- a/keyboards/fjlabs/bolsa65/rules.mk +++ b/keyboards/fjlabs/bolsa65/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 65_ansi_blocker diff --git a/keyboards/fjlabs/kf87/rules.mk b/keyboards/fjlabs/kf87/rules.mk index e8e606b5b15f..ed2c3a4fb5db 100644 --- a/keyboards/fjlabs/kf87/rules.mk +++ b/keyboards/fjlabs/kf87/rules.mk @@ -22,4 +22,3 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes diff --git a/keyboards/fjlabs/ldk65/rules.mk b/keyboards/fjlabs/ldk65/rules.mk index 2bee6a4b919f..dbfecbc773ee 100644 --- a/keyboards/fjlabs/ldk65/rules.mk +++ b/keyboards/fjlabs/ldk65/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 65_ansi diff --git a/keyboards/fjlabs/ready100/rules.mk b/keyboards/fjlabs/ready100/rules.mk index fb8e1bc71e6e..029a96b33dcd 100644 --- a/keyboards/fjlabs/ready100/rules.mk +++ b/keyboards/fjlabs/ready100/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 64_ansi diff --git a/keyboards/fjlabs/tf60ansi/rules.mk b/keyboards/fjlabs/tf60ansi/rules.mk index 6e16f42b85e6..dbd20b9e1e5e 100644 --- a/keyboards/fjlabs/tf60ansi/rules.mk +++ b/keyboards/fjlabs/tf60ansi/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 60_ansi diff --git a/keyboards/fjlabs/tf60v2/rules.mk b/keyboards/fjlabs/tf60v2/rules.mk index bf43d35264d0..db42667cfce5 100644 --- a/keyboards/fjlabs/tf60v2/rules.mk +++ b/keyboards/fjlabs/tf60v2/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 60_ansi_arrow diff --git a/keyboards/fjlabs/tf65rgbv2/rules.mk b/keyboards/fjlabs/tf65rgbv2/rules.mk index 1ec4ee2ac21b..4e9cde50cc27 100644 --- a/keyboards/fjlabs/tf65rgbv2/rules.mk +++ b/keyboards/fjlabs/tf65rgbv2/rules.mk @@ -22,6 +22,6 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes -LAYOUTS = 65_ansi \ No newline at end of file + +LAYOUTS = 65_ansi diff --git a/keyboards/gh60/revc/keymaps/danbee/rules.mk b/keyboards/gh60/revc/keymaps/danbee/rules.mk index b1434f75c84b..0a5b666e8557 100644 --- a/keyboards/gh60/revc/keymaps/danbee/rules.mk +++ b/keyboards/gh60/revc/keymaps/danbee/rules.mk @@ -1,2 +1 @@ MOUSEKEY_ENABLE = no -KEYBOARD_LOCK_ENABLE = yes diff --git a/keyboards/gh60/revc/rules.mk b/keyboards/gh60/revc/rules.mk index 30057a45714a..da3aaf323781 100644 --- a/keyboards/gh60/revc/rules.mk +++ b/keyboards/gh60/revc/rules.mk @@ -12,7 +12,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control # CONSOLE_ENABLE = yes # Console for debug # COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE # SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work diff --git a/keyboards/handwired/arrow_pad/rules.mk b/keyboards/handwired/arrow_pad/rules.mk index e58bcc03a400..d6180989bf82 100644 --- a/keyboards/handwired/arrow_pad/rules.mk +++ b/keyboards/handwired/arrow_pad/rules.mk @@ -12,7 +12,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = yes # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work diff --git a/keyboards/handwired/retro_refit/rules.mk b/keyboards/handwired/retro_refit/rules.mk index a37162eff849..d06879ab1381 100644 --- a/keyboards/handwired/retro_refit/rules.mk +++ b/keyboards/handwired/retro_refit/rules.mk @@ -12,7 +12,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = yes # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE # SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work diff --git a/keyboards/idb/idb_60/rules.mk b/keyboards/idb/idb_60/rules.mk index 0ec5c6a83160..a2363cbb5ea5 100644 --- a/keyboards/idb/idb_60/rules.mk +++ b/keyboards/idb/idb_60/rules.mk @@ -11,7 +11,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = no # Console for debug COMMAND_ENABLE = no # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = no # Allow locking of keyboard via magic key SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality diff --git a/keyboards/jd40/rules.mk b/keyboards/jd40/rules.mk index 358097e80d3a..f344e4fc77dc 100644 --- a/keyboards/jd40/rules.mk +++ b/keyboards/jd40/rules.mk @@ -12,7 +12,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control # CONSOLE_ENABLE = yes # Console for debug # COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE # SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work diff --git a/keyboards/kc60/keymaps/stanleylai/rules.mk b/keyboards/kc60/keymaps/stanleylai/rules.mk index 39223abfa622..3951663c7cc1 100644 --- a/keyboards/kc60/keymaps/stanleylai/rules.mk +++ b/keyboards/kc60/keymaps/stanleylai/rules.mk @@ -8,7 +8,6 @@ MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = no # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable WS2812 underglow RGB strip MIDI_ENABLE = no # MIDI controls @@ -19,4 +18,3 @@ AUDIO_ENABLE = no # Audio output on port C6 SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work NKRO_ENABLE = yes # USB Nkey Rollover - diff --git a/keyboards/kc60/keymaps/wigguno/rules.mk b/keyboards/kc60/keymaps/wigguno/rules.mk index 43fcc254d1fc..97ab96173962 100644 --- a/keyboards/kc60/keymaps/wigguno/rules.mk +++ b/keyboards/kc60/keymaps/wigguno/rules.mk @@ -8,7 +8,6 @@ MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = no # Console for debug(+400) COMMAND_ENABLE = no # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work @@ -18,4 +17,3 @@ MIDI_ENABLE = no # MIDI controls UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 - diff --git a/keyboards/kc60/rules.mk b/keyboards/kc60/rules.mk index 1f63f24f1580..a00cd5e8087f 100644 --- a/keyboards/kc60/rules.mk +++ b/keyboards/kc60/rules.mk @@ -19,6 +19,5 @@ NKRO_ENABLE = no # USB Nkey Rollover BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key LAYOUTS = 60_ansi diff --git a/keyboards/keybee/keybee65/rules.mk b/keyboards/keybee/keybee65/rules.mk index 17b1906d46c6..fb898d093f0b 100644 --- a/keyboards/keybee/keybee65/rules.mk +++ b/keyboards/keybee/keybee65/rules.mk @@ -19,7 +19,6 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes ENCODER_ENABLE = no RGB_MATRIX_ENABLE = yes RGB_MATRIX_DRIVER = WS2812 diff --git a/keyboards/lucid/alexa/rules.mk b/keyboards/lucid/alexa/rules.mk index 16bcdf2cfc09..1d161000509d 100644 --- a/keyboards/lucid/alexa/rules.mk +++ b/keyboards/lucid/alexa/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 65_ansi_blocker 65_ansi_blocker_split_bs diff --git a/keyboards/lucid/kbd8x_hs/rules.mk b/keyboards/lucid/kbd8x_hs/rules.mk index ca14808aa499..916eb9fbbda2 100644 --- a/keyboards/lucid/kbd8x_hs/rules.mk +++ b/keyboards/lucid/kbd8x_hs/rules.mk @@ -22,4 +22,3 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes diff --git a/keyboards/lucid/phantom_hs/rules.mk b/keyboards/lucid/phantom_hs/rules.mk index b1d63c682288..a49a628735b9 100644 --- a/keyboards/lucid/phantom_hs/rules.mk +++ b/keyboards/lucid/phantom_hs/rules.mk @@ -22,6 +22,5 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes LAYOUTS = 65_ansi_blocker diff --git a/keyboards/lucid/phantom_solder/rules.mk b/keyboards/lucid/phantom_solder/rules.mk index 58e569b7393f..4f8739075909 100644 --- a/keyboards/lucid/phantom_solder/rules.mk +++ b/keyboards/lucid/phantom_solder/rules.mk @@ -22,4 +22,3 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes diff --git a/keyboards/ok60/rules.mk b/keyboards/ok60/rules.mk index e1e858b349b3..b8967270096a 100644 --- a/keyboards/ok60/rules.mk +++ b/keyboards/ok60/rules.mk @@ -12,7 +12,6 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control # CONSOLE_ENABLE = yes # Console for debug # COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable the RGB backlight diff --git a/keyboards/thevankeyboards/minivan/keymaps/danbee/rules.mk b/keyboards/thevankeyboards/minivan/keymaps/danbee/rules.mk index b1434f75c84b..0a5b666e8557 100644 --- a/keyboards/thevankeyboards/minivan/keymaps/danbee/rules.mk +++ b/keyboards/thevankeyboards/minivan/keymaps/danbee/rules.mk @@ -1,2 +1 @@ MOUSEKEY_ENABLE = no -KEYBOARD_LOCK_ENABLE = yes diff --git a/keyboards/undead60m/rules.mk b/keyboards/undead60m/rules.mk index b88f8c161d3f..1bc6b6534e84 100644 --- a/keyboards/undead60m/rules.mk +++ b/keyboards/undead60m/rules.mk @@ -19,6 +19,5 @@ NKRO_ENABLE = no # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes ENCODER_ENABLE = yes LTO_ENABLE = yes diff --git a/keyboards/wolf/ts60/rules.mk b/keyboards/wolf/ts60/rules.mk index bd19f3c36e19..8edf0f7658d5 100644 --- a/keyboards/wolf/ts60/rules.mk +++ b/keyboards/wolf/ts60/rules.mk @@ -22,6 +22,6 @@ NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output -KEYBOARD_LOCK_ENABLE = yes -LAYOUTS = 60_ansi \ No newline at end of file + +LAYOUTS = 60_ansi diff --git a/show_options.mk b/show_options.mk index b17d8c7d9dde..60ae850cf855 100644 --- a/show_options.mk +++ b/show_options.mk @@ -65,7 +65,6 @@ OTHER_OPTION_NAMES = \ HAPTIC_ENABLE \ HHKB_RN42_ENABLE \ ISSI_ENABLE \ - KEYBOARD_LOCK_ENABLE \ KEYLOGGER_ENABLE \ LCD_BACKLIGHT_ENABLE \ MACROS_ENABLED \ diff --git a/users/bcat/rules.mk b/users/bcat/rules.mk index 6d748875a4f8..651ee96fe07e 100644 --- a/users/bcat/rules.mk +++ b/users/bcat/rules.mk @@ -29,7 +29,6 @@ SLEEP_LED_ENABLE = no # Disable other unused options on all keyboards. AUTO_SHIFT_ENABLE = no COMBO_ENABLE = no -KEYBOARD_LOCK_ENABLE = no KEY_LOCK_ENABLE = no LEADER_ENABLE = no SWAP_HANDS_ENABLE = no From d595dce89f431bd28728b814c92481ed101de8a7 Mon Sep 17 00:00:00 2001 From: GG <72414103+spbgzh@users.noreply.github.com> Date: Wed, 27 Oct 2021 02:03:52 +0300 Subject: [PATCH 0032/1136] [Keyboard] Add zoom65 (#14926) --- keyboards/meletrix/zoom65/config.h | 51 ++ keyboards/meletrix/zoom65/info.json | 467 ++++++++++++++++++ .../meletrix/zoom65/keymaps/65_ansi/keymap.c | 34 ++ .../meletrix/zoom65/keymaps/65_ansi/readme.md | 1 + .../meletrix/zoom65/keymaps/65_iso/keymap.c | 34 ++ .../meletrix/zoom65/keymaps/65_iso/readme.md | 1 + .../zoom65/keymaps/65_split_bs/keymap.c | 34 ++ .../zoom65/keymaps/65_split_bs/readme.md | 1 + .../zoom65/keymaps/65_split_lshift/keymap.c | 34 ++ .../zoom65/keymaps/65_split_lshift/readme.md | 1 + .../zoom65/keymaps/65_split_space/keymap.c | 34 ++ .../zoom65/keymaps/65_split_space/readme.md | 1 + .../meletrix/zoom65/keymaps/default/keymap.c | 34 ++ .../meletrix/zoom65/keymaps/default/readme.md | 1 + .../meletrix/zoom65/keymaps/via/keymap.c | 48 ++ .../meletrix/zoom65/keymaps/via/readme.md | 1 + .../meletrix/zoom65/keymaps/via/rules.mk | 2 + keyboards/meletrix/zoom65/readme.md | 26 + keyboards/meletrix/zoom65/rules.mk | 24 + keyboards/meletrix/zoom65/zoom65.c | 66 +++ keyboards/meletrix/zoom65/zoom65.h | 187 +++++++ 21 files changed, 1082 insertions(+) create mode 100644 keyboards/meletrix/zoom65/config.h create mode 100644 keyboards/meletrix/zoom65/info.json create mode 100644 keyboards/meletrix/zoom65/keymaps/65_ansi/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/65_ansi/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/65_iso/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/65_iso/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/65_split_bs/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/65_split_bs/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/65_split_lshift/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/65_split_lshift/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/65_split_space/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/65_split_space/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/default/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/default/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/via/keymap.c create mode 100644 keyboards/meletrix/zoom65/keymaps/via/readme.md create mode 100644 keyboards/meletrix/zoom65/keymaps/via/rules.mk create mode 100644 keyboards/meletrix/zoom65/readme.md create mode 100644 keyboards/meletrix/zoom65/rules.mk create mode 100644 keyboards/meletrix/zoom65/zoom65.c create mode 100644 keyboards/meletrix/zoom65/zoom65.h diff --git a/keyboards/meletrix/zoom65/config.h b/keyboards/meletrix/zoom65/config.h new file mode 100644 index 000000000000..4eb85aeb4960 --- /dev/null +++ b/keyboards/meletrix/zoom65/config.h @@ -0,0 +1,51 @@ +/* Copyright 2021 meletrix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x806B +#define PRODUCT_ID 0x0004 +#define DEVICE_VER 0x0001 +#define MANUFACTURER meletrix +#define PRODUCT zoom65 + +/* key matrix size */ +#define MATRIX_ROWS 5 +#define MATRIX_COLS 15 + +#define MATRIX_ROW_PINS { F0, E6, D5, F1, F4 } +#define MATRIX_COL_PINS { C7, D3, D2, D1, D0, B7, B3, B2, C6, B6, B5, B4, D7, D6, D4 } + +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Enable encoder */ +#define ENCODERS_PAD_A { B1 } +#define ENCODERS_PAD_B { B0 } + +#define ENCODERS 1 +// Note: array is { col, row ) +#define ENCODERS_CW_KEY { { 5, 4 } } +#define ENCODERS_CCW_KEY { { 3, 4 } } + +#define LED_CAPS_LOCK_PIN F7 +#define LED_PIN_ON_STATE 0 + diff --git a/keyboards/meletrix/zoom65/info.json b/keyboards/meletrix/zoom65/info.json new file mode 100644 index 000000000000..49535c106e93 --- /dev/null +++ b/keyboards/meletrix/zoom65/info.json @@ -0,0 +1,467 @@ +{ + "keyboard_name": "zoom65", + "url": "https://zoom65.com/", + "maintainer": "qmk", + "layouts": { + "LAYOUT_all": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "1", "x": 1, "y": 0 }, + { "label": "2", "x": 2, "y": 0 }, + { "label": "3", "x": 3, "y": 0 }, + { "label": "4", "x": 4, "y": 0 }, + { "label": "5", "x": 5, "y": 0 }, + { "label": "6", "x": 6, "y": 0 }, + { "label": "7", "x": 7, "y": 0 }, + { "label": "8", "x": 8, "y": 0 }, + { "label": "9", "x": 9, "y": 0 }, + { "label": "0", "x": 10, "y": 0 }, + { "label": "-", "x": 11, "y": 0 }, + { "label": "=", "x": 12, "y": 0 }, + { "label": "Backspace", "x": 13, "y": 0 }, + { "label": "EncoderRotateL", "x": 15, "y": 0, "w": 0.5 }, + { "label": "EncoderClick", "x": 15.5, "y": 0 }, + { "label": "EncoderRotateR", "x": 16.5, "y": 0, "w": 0.5 }, + + { "label": "Tab", "x": 0, "y": 1, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 1 }, + { "label": "W", "x": 2.5, "y": 1 }, + { "label": "E", "x": 3.5, "y": 1 }, + { "label": "R", "x": 4.5, "y": 1 }, + { "label": "T", "x": 5.5, "y": 1 }, + { "label": "Y", "x": 6.5, "y": 1 }, + { "label": "U", "x": 7.5, "y": 1 }, + { "label": "I", "x": 8.5, "y": 1 }, + { "label": "O", "x": 9.5, "y": 1 }, + { "label": "P", "x": 10.5, "y": 1 }, + { "label": "[", "x": 11.5, "y": 1 }, + { "label": "]", "x": 12.5, "y": 1 }, + { "label": "\\", "x": 13.5, "y": 1, "w": 1.5 }, + { "label": "Delete", "x": 15, "y": 1 }, + + { "label": "Caps Lock", "x": 0, "y": 2, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 2 }, + { "label": "S", "x": 2.75, "y": 2 }, + { "label": "D", "x": 3.75, "y": 2 }, + { "label": "F", "x": 4.75, "y": 2 }, + { "label": "G", "x": 5.75, "y": 2 }, + { "label": "H", "x": 6.75, "y": 2 }, + { "label": "J", "x": 7.75, "y": 2 }, + { "label": "K", "x": 8.75, "y": 2 }, + { "label": "L", "x": 9.75, "y": 2 }, + { "label": ";", "x": 10.75, "y": 2 }, + { "label": "'", "x": 11.75, "y": 2 }, + { "label": "Enter", "x": 12.75, "y": 2, "w": 2.25 }, + { "label": "Backspace", "x": 14, "y": 0 }, + { "label": "PageUp", "x": 15, "y": 2 }, + + { "label": "Shift1", "x": 0, "y": 3, "w": 1.25 }, + { "label": "Shift2", "x": 1.25, "y": 3 }, + { "label": "Z", "x": 2.25, "y": 3 }, + { "label": "X", "x": 3.25, "y": 3 }, + { "label": "C", "x": 4.25, "y": 3 }, + { "label": "V", "x": 5.25, "y": 3 }, + { "label": "B", "x": 6.25, "y": 3 }, + { "label": "N", "x": 7.25, "y": 3 }, + { "label": "M", "x": 8.25, "y": 3 }, + { "label": ",", "x": 9.25, "y": 3 }, + { "label": ".", "x": 10.25, "y": 3 }, + { "label": "/", "x": 11.25, "y": 3 }, + { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 }, + { "label": "\u2191", "x": 14, "y": 3 }, + { "label": "End", "x": 15, "y": 3 }, + + { "label": "Ctrl", "x": 0, "y": 4, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 4, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 4, "w": 1.25 }, + { "x": 3.75, "y": 4, "w": 2.25 }, + { "x": 6, "y": 4, "w": 1.25 }, + { "x": 7.25, "y": 4, "w": 2.75 }, + { "label": "Alt", "x": 10, "y": 4, "w": 1.25 }, + { "label": "Fn", "x": 11.25, "y": 4, "w": 1.25 }, + { "label": "\u2190", "x": 13, "y": 4 }, + { "label": "\u2193", "x": 14, "y": 4 }, + { "label": "\u2192", "x": 15, "y": 4 } + ] + }, + "LAYOUT_65_ansi_blocker": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "1", "x": 1, "y": 0 }, + { "label": "2", "x": 2, "y": 0 }, + { "label": "3", "x": 3, "y": 0 }, + { "label": "4", "x": 4, "y": 0 }, + { "label": "5", "x": 5, "y": 0 }, + { "label": "6", "x": 6, "y": 0 }, + { "label": "7", "x": 7, "y": 0 }, + { "label": "8", "x": 8, "y": 0 }, + { "label": "9", "x": 9, "y": 0 }, + { "label": "0", "x": 10, "y": 0 }, + { "label": "-", "x": 11, "y": 0 }, + { "label": "=", "x": 12, "y": 0 }, + { "label": "Backspace", "x": 13, "y": 0, "w": 2 }, + { "label": "Encode", "x": 15, "y": 0 }, + + { "label": "Tab", "x": 0, "y": 1, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 1 }, + { "label": "W", "x": 2.5, "y": 1 }, + { "label": "E", "x": 3.5, "y": 1 }, + { "label": "R", "x": 4.5, "y": 1 }, + { "label": "T", "x": 5.5, "y": 1 }, + { "label": "Y", "x": 6.5, "y": 1 }, + { "label": "U", "x": 7.5, "y": 1 }, + { "label": "I", "x": 8.5, "y": 1 }, + { "label": "O", "x": 9.5, "y": 1 }, + { "label": "P", "x": 10.5, "y": 1 }, + { "label": "[", "x": 11.5, "y": 1 }, + { "label": "]", "x": 12.5, "y": 1 }, + { "label": "\\", "x": 13.5, "y": 1, "w": 1.5 }, + { "label": "Delete", "x": 15, "y": 1 }, + + { "label": "Caps Lock", "x": 0, "y": 2, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 2 }, + { "label": "S", "x": 2.75, "y": 2 }, + { "label": "D", "x": 3.75, "y": 2 }, + { "label": "F", "x": 4.75, "y": 2 }, + { "label": "G", "x": 5.75, "y": 2 }, + { "label": "H", "x": 6.75, "y": 2 }, + { "label": "J", "x": 7.75, "y": 2 }, + { "label": "K", "x": 8.75, "y": 2 }, + { "label": "L", "x": 9.75, "y": 2 }, + { "label": ";", "x": 10.75, "y": 2 }, + { "label": "'", "x": 11.75, "y": 2 }, + { "label": "Enter", "x": 12.75, "y": 2, "w": 2.25 }, + { "label": "PageUp", "x": 15, "y": 2 }, + + { "label": "Shift", "x": 0, "y": 3, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 3 }, + { "label": "X", "x": 3.25, "y": 3 }, + { "label": "C", "x": 4.25, "y": 3 }, + { "label": "V", "x": 5.25, "y": 3 }, + { "label": "B", "x": 6.25, "y": 3 }, + { "label": "N", "x": 7.25, "y": 3 }, + { "label": "M", "x": 8.25, "y": 3 }, + { "label": ",", "x": 9.25, "y": 3 }, + { "label": ".", "x": 10.25, "y": 3 }, + { "label": "/", "x": 11.25, "y": 3 }, + { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 }, + { "label": "\u2191", "x": 14, "y": 3 }, + { "label": "End", "x": 15, "y": 3 }, + + { "label": "Ctrl", "x": 0, "y": 4, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 4, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 4, "w": 1.25 }, + { "x": 3.75, "y": 4, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 4, "w": 1.25 }, + { "label": "Fn", "x": 11.25, "y": 4, "w": 1.25 }, + { "label": "\u2190", "x": 13, "y": 4 }, + { "label": "\u2193", "x": 14, "y": 4 }, + { "label": "\u2192", "x": 15, "y": 4 } + ] + }, + "LAYOUT_65_iso_blocker": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "1", "x": 1, "y": 0 }, + { "label": "2", "x": 2, "y": 0 }, + { "label": "3", "x": 3, "y": 0 }, + { "label": "4", "x": 4, "y": 0 }, + { "label": "5", "x": 5, "y": 0 }, + { "label": "6", "x": 6, "y": 0 }, + { "label": "7", "x": 7, "y": 0 }, + { "label": "8", "x": 8, "y": 0 }, + { "label": "9", "x": 9, "y": 0 }, + { "label": "0", "x": 10, "y": 0 }, + { "label": "-", "x": 11, "y": 0 }, + { "label": "=", "x": 12, "y": 0 }, + { "label": "Backspace", "x": 13, "y": 0, "w": 2 }, + { "label": "Encode", "x": 15, "y": 0 }, + + { "label": "Tab", "x": 0, "y": 1, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 1 }, + { "label": "W", "x": 2.5, "y": 1 }, + { "label": "E", "x": 3.5, "y": 1 }, + { "label": "R", "x": 4.5, "y": 1 }, + { "label": "T", "x": 5.5, "y": 1 }, + { "label": "Y", "x": 6.5, "y": 1 }, + { "label": "U", "x": 7.5, "y": 1 }, + { "label": "I", "x": 8.5, "y": 1 }, + { "label": "O", "x": 9.5, "y": 1 }, + { "label": "P", "x": 10.5, "y": 1 }, + { "label": "[", "x": 11.5, "y": 1 }, + { "label": "]", "x": 12.5, "y": 1 }, + { "label": "ISO", "x": 13.75, "y": 1, "w": 1.25, "h": 2 }, + { "label": "Delete", "x": 15, "y": 1 }, + + { "label": "Caps Lock", "x": 0, "y": 2, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 2 }, + { "label": "S", "x": 2.75, "y": 2 }, + { "label": "D", "x": 3.75, "y": 2 }, + { "label": "F", "x": 4.75, "y": 2 }, + { "label": "G", "x": 5.75, "y": 2 }, + { "label": "H", "x": 6.75, "y": 2 }, + { "label": "J", "x": 7.75, "y": 2 }, + { "label": "K", "x": 8.75, "y": 2 }, + { "label": "L", "x": 9.75, "y": 2 }, + { "label": ";", "x": 10.75, "y": 2 }, + { "label": "'", "x": 11.75, "y": 2 }, + { "label": "\\", "x": 12.75, "y": 2 }, + { "label": "PageUp", "x": 15, "y": 2 }, + + { "label": "Shift", "x": 0, "y": 3, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 3 }, + { "label": "X", "x": 3.25, "y": 3 }, + { "label": "C", "x": 4.25, "y": 3 }, + { "label": "V", "x": 5.25, "y": 3 }, + { "label": "B", "x": 6.25, "y": 3 }, + { "label": "N", "x": 7.25, "y": 3 }, + { "label": "M", "x": 8.25, "y": 3 }, + { "label": ",", "x": 9.25, "y": 3 }, + { "label": ".", "x": 10.25, "y": 3 }, + { "label": "/", "x": 11.25, "y": 3 }, + { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 }, + { "label": "\u2191", "x": 14, "y": 3 }, + { "label": "End", "x": 15, "y": 3 }, + + { "label": "Ctrl", "x": 0, "y": 4, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 4, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 4, "w": 1.25 }, + { "x": 3.75, "y": 4, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 4, "w": 1.25 }, + { "label": "Fn", "x": 11.25, "y": 4, "w": 1.25 }, + { "label": "\u2190", "x": 13, "y": 4 }, + { "label": "\u2193", "x": 14, "y": 4 }, + { "label": "\u2192", "x": 15, "y": 4 } + ] + }, + "LAYOUT_65_ansi_split_bs": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "1", "x": 1, "y": 0 }, + { "label": "2", "x": 2, "y": 0 }, + { "label": "3", "x": 3, "y": 0 }, + { "label": "4", "x": 4, "y": 0 }, + { "label": "5", "x": 5, "y": 0 }, + { "label": "6", "x": 6, "y": 0 }, + { "label": "7", "x": 7, "y": 0 }, + { "label": "8", "x": 8, "y": 0 }, + { "label": "9", "x": 9, "y": 0 }, + { "label": "0", "x": 10, "y": 0 }, + { "label": "-", "x": 11, "y": 0 }, + { "label": "=", "x": 12, "y": 0 }, + { "label": "Backspace", "x": 13, "y": 0 }, + { "label": "Encode", "x": 15, "y": 0 }, + + { "label": "Tab", "x": 0, "y": 1, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 1 }, + { "label": "W", "x": 2.5, "y": 1 }, + { "label": "E", "x": 3.5, "y": 1 }, + { "label": "R", "x": 4.5, "y": 1 }, + { "label": "T", "x": 5.5, "y": 1 }, + { "label": "Y", "x": 6.5, "y": 1 }, + { "label": "U", "x": 7.5, "y": 1 }, + { "label": "I", "x": 8.5, "y": 1 }, + { "label": "O", "x": 9.5, "y": 1 }, + { "label": "P", "x": 10.5, "y": 1 }, + { "label": "[", "x": 11.5, "y": 1 }, + { "label": "]", "x": 12.5, "y": 1 }, + { "label": "\\", "x": 13.5, "y": 1, "w": 1.5 }, + { "label": "Delete", "x": 15, "y": 1 }, + + { "label": "Caps Lock", "x": 0, "y": 2, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 2 }, + { "label": "S", "x": 2.75, "y": 2 }, + { "label": "D", "x": 3.75, "y": 2 }, + { "label": "F", "x": 4.75, "y": 2 }, + { "label": "G", "x": 5.75, "y": 2 }, + { "label": "H", "x": 6.75, "y": 2 }, + { "label": "J", "x": 7.75, "y": 2 }, + { "label": "K", "x": 8.75, "y": 2 }, + { "label": "L", "x": 9.75, "y": 2 }, + { "label": ";", "x": 10.75, "y": 2 }, + { "label": "'", "x": 11.75, "y": 2 }, + { "label": "Enter", "x": 12.75, "y": 2, "w": 2.25 }, + { "label": "Backspace", "x": 14, "y": 0 }, + { "label": "PageUp", "x": 15, "y": 2 }, + + { "label": "Shift", "x": 0, "y": 3, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 3 }, + { "label": "X", "x": 3.25, "y": 3 }, + { "label": "C", "x": 4.25, "y": 3 }, + { "label": "V", "x": 5.25, "y": 3 }, + { "label": "B", "x": 6.25, "y": 3 }, + { "label": "N", "x": 7.25, "y": 3 }, + { "label": "M", "x": 8.25, "y": 3 }, + { "label": ",", "x": 9.25, "y": 3 }, + { "label": ".", "x": 10.25, "y": 3 }, + { "label": "/", "x": 11.25, "y": 3 }, + { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 }, + { "label": "\u2191", "x": 14, "y": 3 }, + { "label": "End", "x": 15, "y": 3 }, + + { "label": "Ctrl", "x": 0, "y": 4, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 4, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 4, "w": 1.25 }, + { "x": 3.75, "y": 4, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 4, "w": 1.25 }, + { "label": "Fn", "x": 11.25, "y": 4, "w": 1.25 }, + { "label": "\u2190", "x": 13, "y": 4 }, + { "label": "\u2193", "x": 14, "y": 4 }, + { "label": "\u2192", "x": 15, "y": 4 } + ] + }, + "LAYOUT_65_ansi_split_lshift": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "1", "x": 1, "y": 0 }, + { "label": "2", "x": 2, "y": 0 }, + { "label": "3", "x": 3, "y": 0 }, + { "label": "4", "x": 4, "y": 0 }, + { "label": "5", "x": 5, "y": 0 }, + { "label": "6", "x": 6, "y": 0 }, + { "label": "7", "x": 7, "y": 0 }, + { "label": "8", "x": 8, "y": 0 }, + { "label": "9", "x": 9, "y": 0 }, + { "label": "0", "x": 10, "y": 0 }, + { "label": "-", "x": 11, "y": 0 }, + { "label": "=", "x": 12, "y": 0 }, + { "label": "Backspace", "x": 13, "y": 0, "w": 2 }, + { "label": "Encode", "x": 15, "y": 0 }, + + { "label": "Tab", "x": 0, "y": 1, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 1 }, + { "label": "W", "x": 2.5, "y": 1 }, + { "label": "E", "x": 3.5, "y": 1 }, + { "label": "R", "x": 4.5, "y": 1 }, + { "label": "T", "x": 5.5, "y": 1 }, + { "label": "Y", "x": 6.5, "y": 1 }, + { "label": "U", "x": 7.5, "y": 1 }, + { "label": "I", "x": 8.5, "y": 1 }, + { "label": "O", "x": 9.5, "y": 1 }, + { "label": "P", "x": 10.5, "y": 1 }, + { "label": "[", "x": 11.5, "y": 1 }, + { "label": "]", "x": 12.5, "y": 1 }, + { "label": "\\", "x": 13.5, "y": 1, "w": 1.5 }, + { "label": "Delete", "x": 15, "y": 1 }, + + { "label": "Caps Lock", "x": 0, "y": 2, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 2 }, + { "label": "S", "x": 2.75, "y": 2 }, + { "label": "D", "x": 3.75, "y": 2 }, + { "label": "F", "x": 4.75, "y": 2 }, + { "label": "G", "x": 5.75, "y": 2 }, + { "label": "H", "x": 6.75, "y": 2 }, + { "label": "J", "x": 7.75, "y": 2 }, + { "label": "K", "x": 8.75, "y": 2 }, + { "label": "L", "x": 9.75, "y": 2 }, + { "label": ";", "x": 10.75, "y": 2 }, + { "label": "'", "x": 11.75, "y": 2 }, + { "label": "Enter", "x": 12.75, "y": 2, "w": 2.25 }, + { "label": "PageUp", "x": 15, "y": 2 }, + + { "label": "Shift1", "x": 0, "y": 3, "w": 1.25 }, + { "label": "Shift2", "x": 1.25, "y": 3 }, + { "label": "Z", "x": 2.25, "y": 3 }, + { "label": "X", "x": 3.25, "y": 3 }, + { "label": "C", "x": 4.25, "y": 3 }, + { "label": "V", "x": 5.25, "y": 3 }, + { "label": "B", "x": 6.25, "y": 3 }, + { "label": "N", "x": 7.25, "y": 3 }, + { "label": "M", "x": 8.25, "y": 3 }, + { "label": ",", "x": 9.25, "y": 3 }, + { "label": ".", "x": 10.25, "y": 3 }, + { "label": "/", "x": 11.25, "y": 3 }, + { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 }, + { "label": "\u2191", "x": 14, "y": 3 }, + { "label": "End", "x": 15, "y": 3 }, + + { "label": "Ctrl", "x": 0, "y": 4, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 4, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 4, "w": 1.25 }, + { "x": 3.75, "y": 4, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 4, "w": 1.25 }, + { "label": "Fn", "x": 11.25, "y": 4, "w": 1.25 }, + { "label": "\u2190", "x": 13, "y": 4 }, + { "label": "\u2193", "x": 14, "y": 4 }, + { "label": "\u2192", "x": 15, "y": 4 } + ] + }, + "LAYOUT_65_split_space": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "1", "x": 1, "y": 0 }, + { "label": "2", "x": 2, "y": 0 }, + { "label": "3", "x": 3, "y": 0 }, + { "label": "4", "x": 4, "y": 0 }, + { "label": "5", "x": 5, "y": 0 }, + { "label": "6", "x": 6, "y": 0 }, + { "label": "7", "x": 7, "y": 0 }, + { "label": "8", "x": 8, "y": 0 }, + { "label": "9", "x": 9, "y": 0 }, + { "label": "0", "x": 10, "y": 0 }, + { "label": "-", "x": 11, "y": 0 }, + { "label": "=", "x": 12, "y": 0 }, + { "label": "Backspace", "x": 13, "y": 0, "w": 2 }, + { "label": "Encode", "x": 15, "y": 0 }, + + { "label": "Tab", "x": 0, "y": 1, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 1 }, + { "label": "W", "x": 2.5, "y": 1 }, + { "label": "E", "x": 3.5, "y": 1 }, + { "label": "R", "x": 4.5, "y": 1 }, + { "label": "T", "x": 5.5, "y": 1 }, + { "label": "Y", "x": 6.5, "y": 1 }, + { "label": "U", "x": 7.5, "y": 1 }, + { "label": "I", "x": 8.5, "y": 1 }, + { "label": "O", "x": 9.5, "y": 1 }, + { "label": "P", "x": 10.5, "y": 1 }, + { "label": "[", "x": 11.5, "y": 1 }, + { "label": "]", "x": 12.5, "y": 1 }, + { "label": "\\", "x": 13.5, "y": 1, "w": 1.5 }, + { "label": "Delete", "x": 15, "y": 1 }, + + { "label": "Caps Lock", "x": 0, "y": 2, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 2 }, + { "label": "S", "x": 2.75, "y": 2 }, + { "label": "D", "x": 3.75, "y": 2 }, + { "label": "F", "x": 4.75, "y": 2 }, + { "label": "G", "x": 5.75, "y": 2 }, + { "label": "H", "x": 6.75, "y": 2 }, + { "label": "J", "x": 7.75, "y": 2 }, + { "label": "K", "x": 8.75, "y": 2 }, + { "label": "L", "x": 9.75, "y": 2 }, + { "label": ";", "x": 10.75, "y": 2 }, + { "label": "'", "x": 11.75, "y": 2 }, + { "label": "Enter", "x": 12.75, "y": 2, "w": 2.25 }, + { "label": "PageUp", "x": 15, "y": 2 }, + + { "label": "Shift", "x": 0, "y": 3, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 3 }, + { "label": "X", "x": 3.25, "y": 3 }, + { "label": "C", "x": 4.25, "y": 3 }, + { "label": "V", "x": 5.25, "y": 3 }, + { "label": "B", "x": 6.25, "y": 3 }, + { "label": "N", "x": 7.25, "y": 3 }, + { "label": "M", "x": 8.25, "y": 3 }, + { "label": ",", "x": 9.25, "y": 3 }, + { "label": ".", "x": 10.25, "y": 3 }, + { "label": "/", "x": 11.25, "y": 3 }, + { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 }, + { "label": "\u2191", "x": 14, "y": 3 }, + { "label": "End", "x": 15, "y": 3 }, + + { "label": "Ctrl", "x": 0, "y": 4, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 4, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 4, "w": 1.25 }, + { "x": 3.75, "y": 4, "w": 2.25 }, + { "x": 6, "y": 4, "w": 1.25 }, + { "x": 7.25, "y": 4, "w": 2.75 }, + { "label": "Alt", "x": 10, "y": 4, "w": 1.25 }, + { "label": "Fn", "x": 11.25, "y": 4, "w": 1.25 }, + { "label": "\u2190", "x": 13, "y": 4 }, + { "label": "\u2193", "x": 14, "y": 4 }, + { "label": "\u2192", "x": 15, "y": 4 } + ] + } + } +} diff --git a/keyboards/meletrix/zoom65/keymaps/65_ansi/keymap.c b/keyboards/meletrix/zoom65/keymaps/65_ansi/keymap.c new file mode 100644 index 000000000000..07d58e9d2b9d --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_ansi/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi_blocker( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_MUTE, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_ansi_blocker( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/65_ansi/readme.md b/keyboards/meletrix/zoom65/keymaps/65_ansi/readme.md new file mode 100644 index 000000000000..f9dd323673e4 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_ansi/readme.md @@ -0,0 +1 @@ +# The 65_ansi_blocker keymap for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/65_iso/keymap.c b/keyboards/meletrix/zoom65/keymaps/65_iso/keymap.c new file mode 100644 index 000000000000..ccdfb6fc2ffe --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_iso/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_iso_blocker( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_MUTE, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_ENT, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_BSLS, KC_PGUP, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_iso_blocker( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/65_iso/readme.md b/keyboards/meletrix/zoom65/keymaps/65_iso/readme.md new file mode 100644 index 000000000000..fd70c9505056 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_iso/readme.md @@ -0,0 +1 @@ +# The 65_iso_blocker for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/65_split_bs/keymap.c b/keyboards/meletrix/zoom65/keymaps/65_split_bs/keymap.c new file mode 100644 index 000000000000..a930987720c8 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_split_bs/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi_split_bs( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_MUTE, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_BSPC, KC_PGUP, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_ansi_split_bs( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/65_split_bs/readme.md b/keyboards/meletrix/zoom65/keymaps/65_split_bs/readme.md new file mode 100644 index 000000000000..34c59ba014c3 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_split_bs/readme.md @@ -0,0 +1 @@ +# The 65_split_bs keymap for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/65_split_lshift/keymap.c b/keyboards/meletrix/zoom65/keymaps/65_split_lshift/keymap.c new file mode 100644 index 000000000000..91c917951685 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_split_lshift/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi_split_lshift( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_MUTE, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, + KC_LSFT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_ansi_split_lshift( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/65_split_lshift/readme.md b/keyboards/meletrix/zoom65/keymaps/65_split_lshift/readme.md new file mode 100644 index 000000000000..e56989b24a61 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_split_lshift/readme.md @@ -0,0 +1 @@ +# The 65_split_lshift keymap for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/65_split_space/keymap.c b/keyboards/meletrix/zoom65/keymaps/65_split_space/keymap.c new file mode 100644 index 000000000000..b63aff9a9e55 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_split_space/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_split_space( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_MUTE, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_split_space( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/65_split_space/readme.md b/keyboards/meletrix/zoom65/keymaps/65_split_space/readme.md new file mode 100644 index 000000000000..4bd0ee67dbc9 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/65_split_space/readme.md @@ -0,0 +1 @@ +# The 65_split_space keymap for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/default/keymap.c b/keyboards/meletrix/zoom65/keymaps/default/keymap.c new file mode 100644 index 000000000000..a0a62d296753 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/default/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_all( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_VOLD, KC_MUTE, KC_VOLU, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_BSPC, KC_PGUP, + KC_LSFT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_all( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPRV, KC_MPLY, KC_MNXT, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/default/readme.md b/keyboards/meletrix/zoom65/keymaps/default/readme.md new file mode 100644 index 000000000000..32dfecc2657c --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/via/keymap.c b/keyboards/meletrix/zoom65/keymaps/via/keymap.c new file mode 100644 index 000000000000..f70382290661 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/via/keymap.c @@ -0,0 +1,48 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_all( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_VOLD, KC_MUTE, KC_VOLU, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_BSPC, KC_PGUP, + KC_LSFT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_all( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MPRV, KC_MPLY, KC_MNXT, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + [2] = LAYOUT_all( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + [3] = LAYOUT_all( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/meletrix/zoom65/keymaps/via/readme.md b/keyboards/meletrix/zoom65/keymaps/via/readme.md new file mode 100644 index 000000000000..5bc43e82b3be --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/via/readme.md @@ -0,0 +1 @@ +# The via keymap for zoom65 diff --git a/keyboards/meletrix/zoom65/keymaps/via/rules.mk b/keyboards/meletrix/zoom65/keymaps/via/rules.mk new file mode 100644 index 000000000000..43061db1dd46 --- /dev/null +++ b/keyboards/meletrix/zoom65/keymaps/via/rules.mk @@ -0,0 +1,2 @@ +VIA_ENABLE = yes +LTO_ENABLE = yes \ No newline at end of file diff --git a/keyboards/meletrix/zoom65/readme.md b/keyboards/meletrix/zoom65/readme.md new file mode 100644 index 000000000000..dc56f6994989 --- /dev/null +++ b/keyboards/meletrix/zoom65/readme.md @@ -0,0 +1,26 @@ +# zoom65 + +![zoom65](https://i.imgur.com/NIbreqdh.jpeg) + +Meletrix's first mass-produced mechanical keyboard. +More Info at [zoom](https://zoom65.com/). +​ +* Keyboard Maintainer: [spbgzh](https://github.com/spbgzh) +* Hardware Supported: zoom65 Standard +* Hardware Availability: [zoom](https://zoom65.com/) +​ +Make example for this keyboard (after setting up your build environment): + + make meletrix/zoom65:default + +Flashing example for this keyboard: + + make meletrix/zoom65:default:flash + +To reset the board into bootloader mode, do one of the following: + +* Tap the Reset switch mounted on the PCB +* In the case of the default keymap, use the key combination Fn + End +* Hold the Esc key while connecting the USB cable (also erases persistent settings) + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/meletrix/zoom65/rules.mk b/keyboards/meletrix/zoom65/rules.mk new file mode 100644 index 000000000000..b481714b7237 --- /dev/null +++ b/keyboards/meletrix/zoom65/rules.mk @@ -0,0 +1,24 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +ENCODER_ENABLE = yes # Enable Encoder + +LAYOUT = 65_ansi_blocker 65_iso_blocker diff --git a/keyboards/meletrix/zoom65/zoom65.c b/keyboards/meletrix/zoom65/zoom65.c new file mode 100644 index 000000000000..f69ed547eff3 --- /dev/null +++ b/keyboards/meletrix/zoom65/zoom65.c @@ -0,0 +1,66 @@ +/* Copyright 2021 meletrix + * + * 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 . + */ + +#include "zoom65.h" + +#ifdef VIA_ENABLE +static uint8_t encoder_state[ENCODERS] = {0}; +static keypos_t encoder_cw[ENCODERS] = ENCODERS_CW_KEY; +static keypos_t encoder_ccw[ENCODERS] = ENCODERS_CCW_KEY; + +void encoder_action_unregister(void) +{ + for (int index = 0; index < ENCODERS; ++index) + { + if (encoder_state[index]) + { + keyevent_t encoder_event = (keyevent_t){ + .key = encoder_state[index] >> 1 ? encoder_cw[index] : encoder_ccw[index], + .pressed = false, + .time = (timer_read() | 1)}; + encoder_state[index] = 0; + action_exec(encoder_event); + } + } +} +void encoder_action_register(uint8_t index, bool clockwise) +{ + keyevent_t encoder_event = (keyevent_t){ + .key = clockwise ? encoder_cw[index] : encoder_ccw[index], + .pressed = true, + .time = (timer_read() | 1)}; + encoder_state[index] = (clockwise ^ 1) | (clockwise << 1); + action_exec(encoder_event); +} + +void matrix_scan_kb(void) +{ + encoder_action_unregister(); + matrix_scan_user(); +} + +bool encoder_update_kb(uint8_t index, bool clockwise) +{ + encoder_action_register(index, clockwise); + return true; +}; +#else +bool encoder_update_kb(uint8_t index, bool clockwise) { + if (!encoder_update_user(index, clockwise)) { return false; } + tap_code_delay(clockwise ? KC_VOLU : KC_VOLD, 10); + return true; +} +#endif diff --git a/keyboards/meletrix/zoom65/zoom65.h b/keyboards/meletrix/zoom65/zoom65.h new file mode 100644 index 000000000000..400fdcbf3b0f --- /dev/null +++ b/keyboards/meletrix/zoom65/zoom65.h @@ -0,0 +1,187 @@ +/* Copyright 2021 meletrix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + + +/* Standard Arrangement + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ + * │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │2d │ ◯ ISO + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┐ ┌─────┐ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │ │1d │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ ┌──┴┐ │ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2e │ │2c │ │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤ └───┴────┘ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │ + * ├────┼───┴┬──┴─┬─┴───┴──┬┴───┼───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤ + * │40 │41 │42 │44 │46 │48 │4a │4b │ │4c │4d │4e │ + * └────┴────┴────┴────────┴────┴──────────┴────┴────┘ └───┴───┴───┘ + */ +#define LAYOUT_all( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K43, K0E, K45, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \ + K40, K41, K42, K44, K46, K48, K4A, K4B, K4C, K4D, K4E \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \ + { K40, K41, K42, K43, K44, K45, K46, KC_NO, K48, KC_NO, K4A, K4B, K4C, K4D, K4E }, \ +} + + +/* LAYOUT_65_ansi_blocker + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │ ◯ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┐ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2e │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤ + * │30 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤ + * │40 │41 │42 │46 │4a │4b │ │4c │4d │4e │ + * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘ + */ +#define LAYOUT_65_ansi_blocker( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \ + K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \ + K40, K41, K42, K46, K4A, K4B, K4C, K4D, K4E \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KC_NO, K2E }, \ + { K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \ + { K40, K41, K42, KC_NO, KC_NO, KC_NO, K46, KC_NO, KC_NO, KC_NO, K4A, K4B, K4C, K4D, K4E }, \ +} + + +/* LAYOUT_65_iso_blocker + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │ ◯ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┐ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ ├───┤ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │ │2e │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴┬───┼───┤ + * │30 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤ + * │40 │41 │42 │46 │4a │4b │ │4c │4d │4e │ + * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘ + */ +#define LAYOUT_65_iso_blocker( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \ + K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \ + K40, K41, K42, K46, K4A, K4B, K4C, K4D, K4E \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KC_NO, K2E }, \ + { K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \ + { K40, K41, K42, KC_NO, KC_NO, KC_NO, K46, KC_NO, KC_NO, KC_NO, K4A, K4B, K4C, K4D, K4E }, \ +} + + +/* LAYOUT_65_ansi_split_bs + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ + * │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │2d │ ◯ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┼───┐ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2e │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤ + * │30 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤ + * │40 │41 │42 │46 │4a │4b │ │4c │4d │4e │ + * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘ + */ +#define LAYOUT_65_ansi_split_bs( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, \ + K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \ + K40, K41, K42, K46, K4A, K4B, K4C, K4D, K4E \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E }, \ + { K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \ + { K40, K41, K42, KC_NO, KC_NO, KC_NO, K46, KC_NO, KC_NO, KC_NO, K4A, K4B, K4C, K4D, K4E }, \ +} + + +/* LAYOUT_65_ansi_split_lshift + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │ ◯ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┐ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2e │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤ + * │40 │41 │42 │46 │4a │4b │ │4c │4d │4e │ + * └────┴────┴────┴────────────────────────┴────┴────┘ └───┴───┴───┘ + */ +#define LAYOUT_65_ansi_split_lshift( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \ + K40, K41, K42, K46, K4A, K4B, K4C, K4D, K4E \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KC_NO, K2E }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \ + { K40, K41, K42, KC_NO, KC_NO, KC_NO, K46, KC_NO, KC_NO, KC_NO, K4A, K4B, K4C, K4D, K4E }, \ +} + + +/* LAYOUT_65_split_space + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ + * │00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0a │0b │0c │0d │ ◯ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┼───┐ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │1e │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┼───┤ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2e │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┼───┤ + * │30 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │3d │3e │ + * ├────┬───┴┬──┴─┬─┴───┴──┬┴───┼───┴───┴──┬┴───┼───┴┬─┬───┼───┼───┤ + * │40 │41 │42 │44 │46 │48 │4a │4b │ │4c │4d │4e │ + * └────┴────┴────┴────────┴────┴──────────┴────┴────┘ └───┴───┴───┘ + */ +#define LAYOUT_65_split_space( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \ + K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \ + K40, K41, K42, K44, K46, K48, K4A, K4B, K4C, K4D, K4E \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, KC_NO, K2E }, \ + { K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \ + { K40, K41, K42, KC_NO, K44, KC_NO, K46, KC_NO, K48, KC_NO, K4A, K4B, K4C, K4D, K4E }, \ +} From eb8174bc405b464be5c9116e8641851a858dcae3 Mon Sep 17 00:00:00 2001 From: GG <72414103+spbgzh@users.noreply.github.com> Date: Wed, 27 Oct 2021 02:04:39 +0300 Subject: [PATCH 0033/1136] [Keyboard] Add Mammoth75x (#14925) --- keyboards/wuque/mammoth75x/config.h | 57 ++ keyboards/wuque/mammoth75x/info.json | 571 ++++++++++++++++++ .../wuque/mammoth75x/keymaps/75_ansi/keymap.c | 36 ++ .../mammoth75x/keymaps/75_ansi/readme.md | 1 + .../mammoth75x/keymaps/75_split_bs/keymap.c | 36 ++ .../mammoth75x/keymaps/75_split_bs/readme.md | 1 + .../keymaps/75_split_lshift/keymap.c | 36 ++ .../keymaps/75_split_lshift/readme.md | 1 + .../keymaps/75_split_rshift/keymap.c | 36 ++ .../keymaps/75_split_rshift/readme.md | 1 + .../keymaps/75_split_space/keymap.c | 36 ++ .../keymaps/75_split_space/readme.md | 1 + .../wuque/mammoth75x/keymaps/default/keymap.c | 36 ++ .../mammoth75x/keymaps/default/readme.md | 1 + .../wuque/mammoth75x/keymaps/via/keymap.c | 52 ++ .../wuque/mammoth75x/keymaps/via/readme.md | 1 + .../wuque/mammoth75x/keymaps/via/rules.mk | 2 + keyboards/wuque/mammoth75x/mammoth75x.c | 67 ++ keyboards/wuque/mammoth75x/mammoth75x.h | 223 +++++++ keyboards/wuque/mammoth75x/readme.md | 25 + keyboards/wuque/mammoth75x/rules.mk | 22 + 21 files changed, 1242 insertions(+) create mode 100644 keyboards/wuque/mammoth75x/config.h create mode 100644 keyboards/wuque/mammoth75x/info.json create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_ansi/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_ansi/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_bs/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_bs/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_lshift/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_lshift/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_rshift/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_rshift/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_space/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/75_split_space/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/default/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/default/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/via/keymap.c create mode 100644 keyboards/wuque/mammoth75x/keymaps/via/readme.md create mode 100644 keyboards/wuque/mammoth75x/keymaps/via/rules.mk create mode 100644 keyboards/wuque/mammoth75x/mammoth75x.c create mode 100644 keyboards/wuque/mammoth75x/mammoth75x.h create mode 100644 keyboards/wuque/mammoth75x/readme.md create mode 100644 keyboards/wuque/mammoth75x/rules.mk diff --git a/keyboards/wuque/mammoth75x/config.h b/keyboards/wuque/mammoth75x/config.h new file mode 100644 index 000000000000..019a70f50d97 --- /dev/null +++ b/keyboards/wuque/mammoth75x/config.h @@ -0,0 +1,57 @@ +/* +Copyright 2021 wuquestudio + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xA06B +#define PRODUCT_ID 0x0004 +#define DEVICE_VER 0x0001 +#define MANUFACTURER wuque studio +#define PRODUCT mammoth75x + +/* key matrix size */ +#define MATRIX_ROWS 6 +#define MATRIX_COLS 16 + +#define MATRIX_ROW_PINS { B0, C7, D2, F7, D1, D0 } +#define MATRIX_COL_PINS { D3, D5, D4, D6, D7, B4, B5, E6, F0, F1, F4, F5, F6, C6, B7, B3 } + +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE + +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* Enable encoder */ +#define ENCODERS_PAD_A { B2 } +#define ENCODERS_PAD_B { B1 } + +#define ENCODERS 1 +// Note: array is { col, row ) +#define ENCODERS_CW_KEY { { 5, 5 } } +#define ENCODERS_CCW_KEY { { 3, 5 } } + +#define LED_CAPS_LOCK_PIN B6 +#define LED_PIN_ON_STATE 0 diff --git a/keyboards/wuque/mammoth75x/info.json b/keyboards/wuque/mammoth75x/info.json new file mode 100644 index 000000000000..4e65f8353729 --- /dev/null +++ b/keyboards/wuque/mammoth75x/info.json @@ -0,0 +1,571 @@ +{ + "keyboard_name": "mammoth75x", + "url": "https://shop.wuquestudio.com/", + "maintainer": "spbgzh", + "layouts": { + "LAYOUT_all": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "F1", "x": 1.5, "y": 0 }, + { "label": "F2", "x": 2.5, "y": 0 }, + { "label": "F3", "x": 3.5, "y": 0 }, + { "label": "F4", "x": 4.5, "y": 0 }, + { "label": "F5", "x": 6, "y": 0 }, + { "label": "F6", "x": 7, "y": 0 }, + { "label": "F7", "x": 8, "y": 0 }, + { "label": "F8", "x": 9, "y": 0 }, + { "label": "F9", "x": 10.5, "y": 0 }, + { "label": "F10", "x": 11.5, "y": 0 }, + { "label": "F11", "x": 12.5, "y": 0 }, + { "label": "F12", "x": 13.5, "y": 0 }, + { "label": "Delete", "x": 15, "y": 0 }, + { "label": "EncoderRotateL", "x": 15.25, "y": 1.25, "w": 0.25 }, + { "label": "EncoderClick", "x": 15.75, "y": 1.25 }, + { "label": "EncoderRotateR", "x": 16.75, "y": 1.25, "w": 0.25 }, + + { "label": "~", "x": 0, "y": 1.25 }, + { "label": "1", "x": 1, "y": 1.25 }, + { "label": "2", "x": 2, "y": 1.25 }, + { "label": "3", "x": 3, "y": 1.25 }, + { "label": "4", "x": 4, "y": 1.25 }, + { "label": "5", "x": 5, "y": 1.25 }, + { "label": "6", "x": 6, "y": 1.25 }, + { "label": "7", "x": 7, "y": 1.25 }, + { "label": "8", "x": 8, "y": 1.25 }, + { "label": "9", "x": 9, "y": 1.25 }, + { "label": "0", "x": 10, "y": 1.25 }, + { "label": "-", "x": 11, "y": 1.25 }, + { "label": "=", "x": 12, "y": 1.25 }, + { "label": "Backspace", "x": 13, "y": 1.25 }, + + { "label": "Tab", "x": 0, "y": 2.25, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 2.25 }, + { "label": "W", "x": 2.5, "y": 2.25 }, + { "label": "E", "x": 3.5, "y": 2.25 }, + { "label": "R", "x": 4.5, "y": 2.25 }, + { "label": "T", "x": 5.5, "y": 2.25 }, + { "label": "Y", "x": 6.5, "y": 2.25 }, + { "label": "U", "x": 7.5, "y": 2.25 }, + { "label": "I", "x": 8.5, "y": 2.25 }, + { "label": "O", "x": 9.5, "y": 2.25 }, + { "label": "P", "x": 10.5, "y": 2.25 }, + { "label": "[", "x": 11.5, "y": 2.25 }, + { "label": "]", "x": 12.5, "y": 2.25 }, + { "label": "\\", "x": 13.5,"y": 2.25, "w": 1.5 }, + { "label": "Home", "x": 15.25, "y": 2.25 }, + { "label": "PageUp", "x": 16.25, "y": 2.25 }, + + { "label": "Caps Lock", "x": 0, "y": 3.25, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 3.25 }, + { "label": "S", "x": 2.75, "y": 3.25 }, + { "label": "D", "x": 3.75, "y": 3.25 }, + { "label": "F", "x": 4.75, "y": 3.25 }, + { "label": "G", "x": 5.75, "y": 3.25 }, + { "label": "H", "x": 6.75, "y": 3.25 }, + { "label": "J", "x": 7.75, "y": 3.25 }, + { "label": "K", "x": 8.75, "y": 3.25 }, + { "label": "L", "x": 9.75, "y": 3.25 }, + { "label": ";", "x": 10.75, "y": 3.25 }, + { "label": "'", "x": 11.75, "y": 3.25 }, + { "label": "Enter", "x": 12.75, "y": 3.25, "w": 2.25 }, + { "label": "Backspace1", "x": 14, "y": 1.25 }, + { "label": "End", "x": 15.25, "y": 3.25 }, + { "label": "PageDown", "x": 16.25, "y": 3.25 }, + + { "label": "Shift1", "x": 0, "y": 4.25, "w": 1.25 }, + { "label": "Shift2", "x": 1.25, "y": 4.25 }, + { "label": "Z", "x": 2.25, "y": 4.25 }, + { "label": "X", "x": 3.25, "y": 4.25 }, + { "label": "C", "x": 4.25, "y": 4.25 }, + { "label": "V", "x": 5.25, "y": 4.25 }, + { "label": "B", "x": 6.25, "y": 4.25 }, + { "label": "N", "x": 7.25, "y": 4.25 }, + { "label": "M", "x": 8.25, "y": 4.25 }, + { "label": ",", "x": 9.25, "y": 4.25 }, + { "label": ".", "x": 10.25, "y": 4.25 }, + { "label": "/", "x": 11.25, "y": 4.25 }, + { "label": "Shift1", "x": 12.25, "y": 4.25, "w": 1.75 }, + { "label": "Shift2", "x": 14, "y": 4.25 }, + { "label": "\u2191", "x": 15.25, "y": 4.25 }, + + { "label": "Ctrl", "x": 0, "y": 5.25, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 5.25, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 3.75, "y": 5.25, "w": 2.25 }, + { "label": "Space","x": 6, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 7.25, "y": 5.25, "w": 2.75 }, + { "label": "Alt", "x": 10, "y": 5.25, "w": 1.25 }, + { "label": "Ctrl", "x": 11.25, "y": 5.25, "w": 1.25 }, + { "label": "Menu", "x": 12.5, "y": 5.25, "w": 1.25 }, + { "label": "\u2190", "x": 14.25, "y": 5.25 }, + { "label": "\u2193", "x": 15.25, "y": 5.25 }, + { "label": "\u2192", "x": 16.25, "y": 5.25 } + ] + }, + "LAYOUT_75_ansi": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "F1", "x": 1.5, "y": 0 }, + { "label": "F2", "x": 2.5, "y": 0 }, + { "label": "F3", "x": 3.5, "y": 0 }, + { "label": "F4", "x": 4.5, "y": 0 }, + { "label": "F5", "x": 6, "y": 0 }, + { "label": "F6", "x": 7, "y": 0 }, + { "label": "F7", "x": 8, "y": 0 }, + { "label": "F8", "x": 9, "y": 0 }, + { "label": "F9", "x": 10.5, "y": 0 }, + { "label": "F10", "x": 11.5, "y": 0 }, + { "label": "F11", "x": 12.5, "y": 0 }, + { "label": "F12", "x": 13.5, "y": 0 }, + { "label": "Delete", "x": 15, "y": 0 }, + { "label": "EncoderClick", "x": 15.75, "y": 1.25 }, + + { "label": "~", "x": 0, "y": 1.25 }, + { "label": "1", "x": 1, "y": 1.25 }, + { "label": "2", "x": 2, "y": 1.25 }, + { "label": "3", "x": 3, "y": 1.25 }, + { "label": "4", "x": 4, "y": 1.25 }, + { "label": "5", "x": 5, "y": 1.25 }, + { "label": "6", "x": 6, "y": 1.25 }, + { "label": "7", "x": 7, "y": 1.25 }, + { "label": "8", "x": 8, "y": 1.25 }, + { "label": "9", "x": 9, "y": 1.25 }, + { "label": "0", "x": 10, "y": 1.25 }, + { "label": "-", "x": 11, "y": 1.25 }, + { "label": "=", "x": 12, "y": 1.25 }, + { "label": "Backspace", "x": 13, "y": 1.25, "w":2}, + + { "label": "Tab", "x": 0, "y": 2.25, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 2.25 }, + { "label": "W", "x": 2.5, "y": 2.25 }, + { "label": "E", "x": 3.5, "y": 2.25 }, + { "label": "R", "x": 4.5, "y": 2.25 }, + { "label": "T", "x": 5.5, "y": 2.25 }, + { "label": "Y", "x": 6.5, "y": 2.25 }, + { "label": "U", "x": 7.5, "y": 2.25 }, + { "label": "I", "x": 8.5, "y": 2.25 }, + { "label": "O", "x": 9.5, "y": 2.25 }, + { "label": "P", "x": 10.5, "y": 2.25 }, + { "label": "[", "x": 11.5, "y": 2.25 }, + { "label": "]", "x": 12.5, "y": 2.25 }, + { "label": "\\", "x": 13.5,"y": 2.25, "w": 1.5 }, + { "label": "Home", "x": 15.25, "y": 2.25 }, + { "label": "PageUp", "x": 16.25, "y": 2.25 }, + + { "label": "Caps Lock", "x": 0, "y": 3.25, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 3.25 }, + { "label": "S", "x": 2.75, "y": 3.25 }, + { "label": "D", "x": 3.75, "y": 3.25 }, + { "label": "F", "x": 4.75, "y": 3.25 }, + { "label": "G", "x": 5.75, "y": 3.25 }, + { "label": "H", "x": 6.75, "y": 3.25 }, + { "label": "J", "x": 7.75, "y": 3.25 }, + { "label": "K", "x": 8.75, "y": 3.25 }, + { "label": "L", "x": 9.75, "y": 3.25 }, + { "label": ";", "x": 10.75, "y": 3.25 }, + { "label": "'", "x": 11.75, "y": 3.25 }, + { "label": "Enter", "x": 12.75, "y": 3.25, "w": 2.25 }, + { "label": "End", "x": 15.25, "y": 3.25 }, + { "label": "PageDown", "x": 16.25, "y": 3.25 }, + + { "label": "Shift", "x": 0, "y": 4.25, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 4.25 }, + { "label": "X", "x": 3.25, "y": 4.25 }, + { "label": "C", "x": 4.25, "y": 4.25 }, + { "label": "V", "x": 5.25, "y": 4.25 }, + { "label": "B", "x": 6.25, "y": 4.25 }, + { "label": "N", "x": 7.25, "y": 4.25 }, + { "label": "M", "x": 8.25, "y": 4.25 }, + { "label": ",", "x": 9.25, "y": 4.25 }, + { "label": ".", "x": 10.25, "y": 4.25 }, + { "label": "/", "x": 11.25, "y": 4.25 }, + { "label": "Shift", "x": 12.25, "y": 4.25, "w": 2.75 }, + { "label": "\u2191", "x": 15.25, "y": 4.25 }, + + { "label": "Ctrl", "x": 0, "y": 5.25, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 5.25, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 3.75, "y": 5.25, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 5.25, "w": 1.25 }, + { "label": "Ctrl", "x": 11.25, "y": 5.25, "w": 1.25 }, + { "label": "Menu", "x": 12.5, "y": 5.25, "w": 1.25 }, + { "label": "\u2190", "x": 14.25, "y": 5.25 }, + { "label": "\u2193", "x": 15.25, "y": 5.25 }, + { "label": "\u2192", "x": 16.25, "y": 5.25 } + ] + }, + "LAYOUT_75_ansi_split_lshift": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "F1", "x": 1.5, "y": 0 }, + { "label": "F2", "x": 2.5, "y": 0 }, + { "label": "F3", "x": 3.5, "y": 0 }, + { "label": "F4", "x": 4.5, "y": 0 }, + { "label": "F5", "x": 6, "y": 0 }, + { "label": "F6", "x": 7, "y": 0 }, + { "label": "F7", "x": 8, "y": 0 }, + { "label": "F8", "x": 9, "y": 0 }, + { "label": "F9", "x": 10.5, "y": 0 }, + { "label": "F10", "x": 11.5, "y": 0 }, + { "label": "F11", "x": 12.5, "y": 0 }, + { "label": "F12", "x": 13.5, "y": 0 }, + { "label": "Delete", "x": 15, "y": 0 }, + { "label": "EncoderClick", "x": 15.75, "y": 1.25 }, + + { "label": "~", "x": 0, "y": 1.25 }, + { "label": "1", "x": 1, "y": 1.25 }, + { "label": "2", "x": 2, "y": 1.25 }, + { "label": "3", "x": 3, "y": 1.25 }, + { "label": "4", "x": 4, "y": 1.25 }, + { "label": "5", "x": 5, "y": 1.25 }, + { "label": "6", "x": 6, "y": 1.25 }, + { "label": "7", "x": 7, "y": 1.25 }, + { "label": "8", "x": 8, "y": 1.25 }, + { "label": "9", "x": 9, "y": 1.25 }, + { "label": "0", "x": 10, "y": 1.25 }, + { "label": "-", "x": 11, "y": 1.25 }, + { "label": "=", "x": 12, "y": 1.25 }, + { "label": "Backspace", "x": 13, "y": 1.25, "w":2}, + + { "label": "Tab", "x": 0, "y": 2.25, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 2.25 }, + { "label": "W", "x": 2.5, "y": 2.25 }, + { "label": "E", "x": 3.5, "y": 2.25 }, + { "label": "R", "x": 4.5, "y": 2.25 }, + { "label": "T", "x": 5.5, "y": 2.25 }, + { "label": "Y", "x": 6.5, "y": 2.25 }, + { "label": "U", "x": 7.5, "y": 2.25 }, + { "label": "I", "x": 8.5, "y": 2.25 }, + { "label": "O", "x": 9.5, "y": 2.25 }, + { "label": "P", "x": 10.5, "y": 2.25 }, + { "label": "[", "x": 11.5, "y": 2.25 }, + { "label": "]", "x": 12.5, "y": 2.25 }, + { "label": "\\", "x": 13.5,"y": 2.25, "w": 1.5 }, + { "label": "Home", "x": 15.25, "y": 2.25 }, + { "label": "PageUp", "x": 16.25, "y": 2.25 }, + + { "label": "Caps Lock", "x": 0, "y": 3.25, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 3.25 }, + { "label": "S", "x": 2.75, "y": 3.25 }, + { "label": "D", "x": 3.75, "y": 3.25 }, + { "label": "F", "x": 4.75, "y": 3.25 }, + { "label": "G", "x": 5.75, "y": 3.25 }, + { "label": "H", "x": 6.75, "y": 3.25 }, + { "label": "J", "x": 7.75, "y": 3.25 }, + { "label": "K", "x": 8.75, "y": 3.25 }, + { "label": "L", "x": 9.75, "y": 3.25 }, + { "label": ";", "x": 10.75, "y": 3.25 }, + { "label": "'", "x": 11.75, "y": 3.25 }, + { "label": "Enter", "x": 12.75, "y": 3.25, "w": 2.25 }, + { "label": "End", "x": 15.25, "y": 3.25 }, + { "label": "PageDown", "x": 16.25, "y": 3.25 }, + + { "label": "Shift1", "x": 0, "y": 4.25, "w": 1.25 }, + { "label": "Shift2", "x": 1.25, "y": 4.25 }, + { "label": "Z", "x": 2.25, "y": 4.25 }, + { "label": "X", "x": 3.25, "y": 4.25 }, + { "label": "C", "x": 4.25, "y": 4.25 }, + { "label": "V", "x": 5.25, "y": 4.25 }, + { "label": "B", "x": 6.25, "y": 4.25 }, + { "label": "N", "x": 7.25, "y": 4.25 }, + { "label": "M", "x": 8.25, "y": 4.25 }, + { "label": ",", "x": 9.25, "y": 4.25 }, + { "label": ".", "x": 10.25, "y": 4.25 }, + { "label": "/", "x": 11.25, "y": 4.25 }, + { "label": "Shift", "x": 12.25, "y": 4.25, "w": 2.75 }, + { "label": "\u2191", "x": 15.25, "y": 4.25 }, + + { "label": "Ctrl", "x": 0, "y": 5.25, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 5.25, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 3.75, "y": 5.25, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 5.25, "w": 1.25 }, + { "label": "Ctrl", "x": 11.25, "y": 5.25, "w": 1.25 }, + { "label": "Menu", "x": 12.5, "y": 5.25, "w": 1.25 }, + { "label": "\u2190", "x": 14.25, "y": 5.25 }, + { "label": "\u2193", "x": 15.25, "y": 5.25 }, + { "label": "\u2192", "x": 16.25, "y": 5.25 } + ] + }, + "LAYOUT_75_ansi_split_rshift": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "F1", "x": 1.5, "y": 0 }, + { "label": "F2", "x": 2.5, "y": 0 }, + { "label": "F3", "x": 3.5, "y": 0 }, + { "label": "F4", "x": 4.5, "y": 0 }, + { "label": "F5", "x": 6, "y": 0 }, + { "label": "F6", "x": 7, "y": 0 }, + { "label": "F7", "x": 8, "y": 0 }, + { "label": "F8", "x": 9, "y": 0 }, + { "label": "F9", "x": 10.5, "y": 0 }, + { "label": "F10", "x": 11.5, "y": 0 }, + { "label": "F11", "x": 12.5, "y": 0 }, + { "label": "F12", "x": 13.5, "y": 0 }, + { "label": "Delete", "x": 15, "y": 0 }, + { "label": "EncoderClick", "x": 15.75, "y": 1.25 }, + + { "label": "~", "x": 0, "y": 1.25 }, + { "label": "1", "x": 1, "y": 1.25 }, + { "label": "2", "x": 2, "y": 1.25 }, + { "label": "3", "x": 3, "y": 1.25 }, + { "label": "4", "x": 4, "y": 1.25 }, + { "label": "5", "x": 5, "y": 1.25 }, + { "label": "6", "x": 6, "y": 1.25 }, + { "label": "7", "x": 7, "y": 1.25 }, + { "label": "8", "x": 8, "y": 1.25 }, + { "label": "9", "x": 9, "y": 1.25 }, + { "label": "0", "x": 10, "y": 1.25 }, + { "label": "-", "x": 11, "y": 1.25 }, + { "label": "=", "x": 12, "y": 1.25 }, + { "label": "Backspace", "x": 13, "y": 1.25, "w":2}, + + { "label": "Tab", "x": 0, "y": 2.25, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 2.25 }, + { "label": "W", "x": 2.5, "y": 2.25 }, + { "label": "E", "x": 3.5, "y": 2.25 }, + { "label": "R", "x": 4.5, "y": 2.25 }, + { "label": "T", "x": 5.5, "y": 2.25 }, + { "label": "Y", "x": 6.5, "y": 2.25 }, + { "label": "U", "x": 7.5, "y": 2.25 }, + { "label": "I", "x": 8.5, "y": 2.25 }, + { "label": "O", "x": 9.5, "y": 2.25 }, + { "label": "P", "x": 10.5, "y": 2.25 }, + { "label": "[", "x": 11.5, "y": 2.25 }, + { "label": "]", "x": 12.5, "y": 2.25 }, + { "label": "\\", "x": 13.5,"y": 2.25, "w": 1.5 }, + { "label": "Home", "x": 15.25, "y": 2.25 }, + { "label": "PageUp", "x": 16.25, "y": 2.25 }, + + { "label": "Caps Lock", "x": 0, "y": 3.25, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 3.25 }, + { "label": "S", "x": 2.75, "y": 3.25 }, + { "label": "D", "x": 3.75, "y": 3.25 }, + { "label": "F", "x": 4.75, "y": 3.25 }, + { "label": "G", "x": 5.75, "y": 3.25 }, + { "label": "H", "x": 6.75, "y": 3.25 }, + { "label": "J", "x": 7.75, "y": 3.25 }, + { "label": "K", "x": 8.75, "y": 3.25 }, + { "label": "L", "x": 9.75, "y": 3.25 }, + { "label": ";", "x": 10.75, "y": 3.25 }, + { "label": "'", "x": 11.75, "y": 3.25 }, + { "label": "Enter", "x": 12.75, "y": 3.25, "w": 2.25 }, + { "label": "End", "x": 15.25, "y": 3.25 }, + { "label": "PageDown", "x": 16.25, "y": 3.25 }, + + { "label": "Shift", "x": 0, "y": 4.25, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 4.25 }, + { "label": "X", "x": 3.25, "y": 4.25 }, + { "label": "C", "x": 4.25, "y": 4.25 }, + { "label": "V", "x": 5.25, "y": 4.25 }, + { "label": "B", "x": 6.25, "y": 4.25 }, + { "label": "N", "x": 7.25, "y": 4.25 }, + { "label": "M", "x": 8.25, "y": 4.25 }, + { "label": ",", "x": 9.25, "y": 4.25 }, + { "label": ".", "x": 10.25, "y": 4.25 }, + { "label": "/", "x": 11.25, "y": 4.25 }, + { "label": "Shift1", "x": 12.25, "y": 4.25, "w": 1.75 }, + { "label": "Shift2", "x": 14, "y": 4.25 }, + { "label": "\u2191", "x": 15.25, "y": 4.25 }, + + { "label": "Ctrl", "x": 0, "y": 5.25, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 5.25, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 3.75, "y": 5.25, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 5.25, "w": 1.25 }, + { "label": "Ctrl", "x": 11.25, "y": 5.25, "w": 1.25 }, + { "label": "Menu", "x": 12.5, "y": 5.25, "w": 1.25 }, + { "label": "\u2190", "x": 14.25, "y": 5.25 }, + { "label": "\u2193", "x": 15.25, "y": 5.25 }, + { "label": "\u2192", "x": 16.25, "y": 5.25 } + ] + }, + "LAYOUT_75_ansi_split_bs": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "F1", "x": 1.5, "y": 0 }, + { "label": "F2", "x": 2.5, "y": 0 }, + { "label": "F3", "x": 3.5, "y": 0 }, + { "label": "F4", "x": 4.5, "y": 0 }, + { "label": "F5", "x": 6, "y": 0 }, + { "label": "F6", "x": 7, "y": 0 }, + { "label": "F7", "x": 8, "y": 0 }, + { "label": "F8", "x": 9, "y": 0 }, + { "label": "F9", "x": 10.5, "y": 0 }, + { "label": "F10", "x": 11.5, "y": 0 }, + { "label": "F11", "x": 12.5, "y": 0 }, + { "label": "F12", "x": 13.5, "y": 0 }, + { "label": "Delete", "x": 15, "y": 0 }, + { "label": "EncoderClick", "x": 15.75, "y": 1.25 }, + + { "label": "~", "x": 0, "y": 1.25 }, + { "label": "1", "x": 1, "y": 1.25 }, + { "label": "2", "x": 2, "y": 1.25 }, + { "label": "3", "x": 3, "y": 1.25 }, + { "label": "4", "x": 4, "y": 1.25 }, + { "label": "5", "x": 5, "y": 1.25 }, + { "label": "6", "x": 6, "y": 1.25 }, + { "label": "7", "x": 7, "y": 1.25 }, + { "label": "8", "x": 8, "y": 1.25 }, + { "label": "9", "x": 9, "y": 1.25 }, + { "label": "0", "x": 10, "y": 1.25 }, + { "label": "-", "x": 11, "y": 1.25 }, + { "label": "=", "x": 12, "y": 1.25 }, + { "label": "Backspace", "x": 13, "y": 1.25}, + + { "label": "Tab", "x": 0, "y": 2.25, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 2.25 }, + { "label": "W", "x": 2.5, "y": 2.25 }, + { "label": "E", "x": 3.5, "y": 2.25 }, + { "label": "R", "x": 4.5, "y": 2.25 }, + { "label": "T", "x": 5.5, "y": 2.25 }, + { "label": "Y", "x": 6.5, "y": 2.25 }, + { "label": "U", "x": 7.5, "y": 2.25 }, + { "label": "I", "x": 8.5, "y": 2.25 }, + { "label": "O", "x": 9.5, "y": 2.25 }, + { "label": "P", "x": 10.5, "y": 2.25 }, + { "label": "[", "x": 11.5, "y": 2.25 }, + { "label": "]", "x": 12.5, "y": 2.25 }, + { "label": "\\", "x": 13.5,"y": 2.25, "w": 1.5 }, + { "label": "Home", "x": 15.25, "y": 2.25 }, + { "label": "PageUp", "x": 16.25, "y": 2.25 }, + + { "label": "Caps Lock", "x": 0, "y": 3.25, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 3.25 }, + { "label": "S", "x": 2.75, "y": 3.25 }, + { "label": "D", "x": 3.75, "y": 3.25 }, + { "label": "F", "x": 4.75, "y": 3.25 }, + { "label": "G", "x": 5.75, "y": 3.25 }, + { "label": "H", "x": 6.75, "y": 3.25 }, + { "label": "J", "x": 7.75, "y": 3.25 }, + { "label": "K", "x": 8.75, "y": 3.25 }, + { "label": "L", "x": 9.75, "y": 3.25 }, + { "label": ";", "x": 10.75, "y": 3.25 }, + { "label": "'", "x": 11.75, "y": 3.25 }, + { "label": "Enter", "x": 12.75, "y": 3.25, "w": 2.25 }, + { "label": "Backspace1", "x": 14, "y": 1.25 }, + { "label": "End", "x": 15.25, "y": 3.25 }, + { "label": "PageDown", "x": 16.25, "y": 3.25 }, + + { "label": "Shift", "x": 0, "y": 4.25, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 4.25 }, + { "label": "X", "x": 3.25, "y": 4.25 }, + { "label": "C", "x": 4.25, "y": 4.25 }, + { "label": "V", "x": 5.25, "y": 4.25 }, + { "label": "B", "x": 6.25, "y": 4.25 }, + { "label": "N", "x": 7.25, "y": 4.25 }, + { "label": "M", "x": 8.25, "y": 4.25 }, + { "label": ",", "x": 9.25, "y": 4.25 }, + { "label": ".", "x": 10.25, "y": 4.25 }, + { "label": "/", "x": 11.25, "y": 4.25 }, + { "label": "Shift", "x": 12.25, "y": 4.25, "w": 2.75 }, + { "label": "\u2191", "x": 15.25, "y": 4.25 }, + + { "label": "Ctrl", "x": 0, "y": 5.25, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 5.25, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 3.75, "y": 5.25, "w": 6.25 }, + { "label": "Alt", "x": 10, "y": 5.25, "w": 1.25 }, + { "label": "Ctrl", "x": 11.25, "y": 5.25, "w": 1.25 }, + { "label": "Menu", "x": 12.5, "y": 5.25, "w": 1.25 }, + { "label": "\u2190", "x": 14.25, "y": 5.25 }, + { "label": "\u2193", "x": 15.25, "y": 5.25 }, + { "label": "\u2192", "x": 16.25, "y": 5.25 } + ] + }, + "LAYOUT_75_ansi_split_space": { + "layout": [ + { "label": "Esc", "x": 0, "y": 0 }, + { "label": "F1", "x": 1.5, "y": 0 }, + { "label": "F2", "x": 2.5, "y": 0 }, + { "label": "F3", "x": 3.5, "y": 0 }, + { "label": "F4", "x": 4.5, "y": 0 }, + { "label": "F5", "x": 6, "y": 0 }, + { "label": "F6", "x": 7, "y": 0 }, + { "label": "F7", "x": 8, "y": 0 }, + { "label": "F8", "x": 9, "y": 0 }, + { "label": "F9", "x": 10.5, "y": 0 }, + { "label": "F10", "x": 11.5, "y": 0 }, + { "label": "F11", "x": 12.5, "y": 0 }, + { "label": "F12", "x": 13.5, "y": 0 }, + { "label": "Delete", "x": 15, "y": 0 }, + { "label": "EncoderClick", "x": 15.75, "y": 1.25 }, + + { "label": "~", "x": 0, "y": 1.25 }, + { "label": "1", "x": 1, "y": 1.25 }, + { "label": "2", "x": 2, "y": 1.25 }, + { "label": "3", "x": 3, "y": 1.25 }, + { "label": "4", "x": 4, "y": 1.25 }, + { "label": "5", "x": 5, "y": 1.25 }, + { "label": "6", "x": 6, "y": 1.25 }, + { "label": "7", "x": 7, "y": 1.25 }, + { "label": "8", "x": 8, "y": 1.25 }, + { "label": "9", "x": 9, "y": 1.25 }, + { "label": "0", "x": 10, "y": 1.25 }, + { "label": "-", "x": 11, "y": 1.25 }, + { "label": "=", "x": 12, "y": 1.25 }, + { "label": "Backspace", "x": 13, "y": 1.25, "w":2}, + + { "label": "Tab", "x": 0, "y": 2.25, "w": 1.5 }, + { "label": "Q", "x": 1.5, "y": 2.25 }, + { "label": "W", "x": 2.5, "y": 2.25 }, + { "label": "E", "x": 3.5, "y": 2.25 }, + { "label": "R", "x": 4.5, "y": 2.25 }, + { "label": "T", "x": 5.5, "y": 2.25 }, + { "label": "Y", "x": 6.5, "y": 2.25 }, + { "label": "U", "x": 7.5, "y": 2.25 }, + { "label": "I", "x": 8.5, "y": 2.25 }, + { "label": "O", "x": 9.5, "y": 2.25 }, + { "label": "P", "x": 10.5, "y": 2.25 }, + { "label": "[", "x": 11.5, "y": 2.25 }, + { "label": "]", "x": 12.5, "y": 2.25 }, + { "label": "\\", "x": 13.5,"y": 2.25, "w": 1.5 }, + { "label": "Home", "x": 15.25, "y": 2.25 }, + { "label": "PageUp", "x": 16.25, "y": 2.25 }, + + { "label": "Caps Lock", "x": 0, "y": 3.25, "w": 1.75 }, + { "label": "A", "x": 1.75, "y": 3.25 }, + { "label": "S", "x": 2.75, "y": 3.25 }, + { "label": "D", "x": 3.75, "y": 3.25 }, + { "label": "F", "x": 4.75, "y": 3.25 }, + { "label": "G", "x": 5.75, "y": 3.25 }, + { "label": "H", "x": 6.75, "y": 3.25 }, + { "label": "J", "x": 7.75, "y": 3.25 }, + { "label": "K", "x": 8.75, "y": 3.25 }, + { "label": "L", "x": 9.75, "y": 3.25 }, + { "label": ";", "x": 10.75, "y": 3.25 }, + { "label": "'", "x": 11.75, "y": 3.25 }, + { "label": "Enter", "x": 12.75, "y": 3.25, "w": 2.25 }, + { "label": "End", "x": 15.25, "y": 3.25 }, + { "label": "PageDown", "x": 16.25, "y": 3.25 }, + + { "label": "Shift", "x": 0, "y": 4.25, "w": 2.25 }, + { "label": "Z", "x": 2.25, "y": 4.25 }, + { "label": "X", "x": 3.25, "y": 4.25 }, + { "label": "C", "x": 4.25, "y": 4.25 }, + { "label": "V", "x": 5.25, "y": 4.25 }, + { "label": "B", "x": 6.25, "y": 4.25 }, + { "label": "N", "x": 7.25, "y": 4.25 }, + { "label": "M", "x": 8.25, "y": 4.25 }, + { "label": ",", "x": 9.25, "y": 4.25 }, + { "label": ".", "x": 10.25, "y": 4.25 }, + { "label": "/", "x": 11.25, "y": 4.25 }, + { "label": "Shift", "x": 12.25, "y": 4.25, "w": 2.75 }, + { "label": "\u2191", "x": 15.25, "y": 4.25 }, + + { "label": "Ctrl", "x": 0, "y": 5.25, "w": 1.25 }, + { "label": "Win", "x": 1.25, "y": 5.25, "w": 1.25 }, + { "label": "Alt", "x": 2.5, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 3.75, "y": 5.25, "w": 2.25 }, + { "label": "Space","x": 6, "y": 5.25, "w": 1.25 }, + { "label": "Space","x": 7.25, "y": 5.25, "w": 2.75 }, + { "label": "Alt", "x": 10, "y": 5.25, "w": 1.25 }, + { "label": "Ctrl", "x": 11.25, "y": 5.25, "w": 1.25 }, + { "label": "Menu", "x": 12.5, "y": 5.25, "w": 1.25 }, + { "label": "\u2190", "x": 14.25, "y": 5.25 }, + { "label": "\u2193", "x": 15.25, "y": 5.25 }, + { "label": "\u2192", "x": 16.25, "y": 5.25 } + ] + } + } +} diff --git a/keyboards/wuque/mammoth75x/keymaps/75_ansi/keymap.c b/keyboards/wuque/mammoth75x/keymaps/75_ansi/keymap.c new file mode 100644 index 000000000000..a35038348ea8 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_ansi/keymap.c @@ -0,0 +1,36 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_75_ansi( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_END, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_75_ansi( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/75_ansi/readme.md b/keyboards/wuque/mammoth75x/keymaps/75_ansi/readme.md new file mode 100644 index 000000000000..b6b384197aff --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_ansi/readme.md @@ -0,0 +1 @@ +# The 75_ansi keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_bs/keymap.c b/keyboards/wuque/mammoth75x/keymaps/75_split_bs/keymap.c new file mode 100644 index 000000000000..c1717e6d2218 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_bs/keymap.c @@ -0,0 +1,36 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_75_ansi_split_bs( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_BSPC, KC_END, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_75_ansi_split_bs( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_bs/readme.md b/keyboards/wuque/mammoth75x/keymaps/75_split_bs/readme.md new file mode 100644 index 000000000000..ef0bf98c57f8 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_bs/readme.md @@ -0,0 +1 @@ +# The 75_split_bs keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_lshift/keymap.c b/keyboards/wuque/mammoth75x/keymaps/75_split_lshift/keymap.c new file mode 100644 index 000000000000..611e1a2642c6 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_lshift/keymap.c @@ -0,0 +1,36 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_75_ansi_split_lshift( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_END, KC_PGDN, + KC_LSFT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_75_ansi_split_lshift( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_lshift/readme.md b/keyboards/wuque/mammoth75x/keymaps/75_split_lshift/readme.md new file mode 100644 index 000000000000..cd6640f912b3 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_lshift/readme.md @@ -0,0 +1 @@ +# The 75_split_lshift keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_rshift/keymap.c b/keyboards/wuque/mammoth75x/keymaps/75_split_rshift/keymap.c new file mode 100644 index 000000000000..1debfe81b74c --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_rshift/keymap.c @@ -0,0 +1,36 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_75_ansi_split_rshift( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_END, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_75_ansi_split_rshift( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_rshift/readme.md b/keyboards/wuque/mammoth75x/keymaps/75_split_rshift/readme.md new file mode 100644 index 000000000000..cd6640f912b3 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_rshift/readme.md @@ -0,0 +1 @@ +# The 75_split_lshift keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_space/keymap.c b/keyboards/wuque/mammoth75x/keymaps/75_split_space/keymap.c new file mode 100644 index 000000000000..2182216060c8 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_space/keymap.c @@ -0,0 +1,36 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_75_ansi_split_space( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_END, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_75_ansi_split_space( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/75_split_space/readme.md b/keyboards/wuque/mammoth75x/keymaps/75_split_space/readme.md new file mode 100644 index 000000000000..c2057660f9f5 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/75_split_space/readme.md @@ -0,0 +1 @@ +# The 75_split_space keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/default/keymap.c b/keyboards/wuque/mammoth75x/keymaps/default/keymap.c new file mode 100644 index 000000000000..9f998a3dd6ba --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/default/keymap.c @@ -0,0 +1,36 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_all( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_VOLD, KC_MUTE,KC_VOLU, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_BSPC, KC_END, KC_PGDN, + KC_LSFT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_all( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/default/readme.md b/keyboards/wuque/mammoth75x/keymaps/default/readme.md new file mode 100644 index 000000000000..73cba9c7b900 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/via/keymap.c b/keyboards/wuque/mammoth75x/keymaps/via/keymap.c new file mode 100644 index 000000000000..d35ff6bccc2a --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/via/keymap.c @@ -0,0 +1,52 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_all( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_VOLD, KC_MUTE,KC_VOLU, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_INS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_BSPC, KC_END, KC_PGDN, + KC_LSFT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_RALT, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_all( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + [2] = LAYOUT_all( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + [3] = LAYOUT_all( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/wuque/mammoth75x/keymaps/via/readme.md b/keyboards/wuque/mammoth75x/keymaps/via/readme.md new file mode 100644 index 000000000000..e6ea1cf87d99 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/via/readme.md @@ -0,0 +1 @@ +# The via keymap for mammoth75x diff --git a/keyboards/wuque/mammoth75x/keymaps/via/rules.mk b/keyboards/wuque/mammoth75x/keymaps/via/rules.mk new file mode 100644 index 000000000000..36b7ba9cbc98 --- /dev/null +++ b/keyboards/wuque/mammoth75x/keymaps/via/rules.mk @@ -0,0 +1,2 @@ +VIA_ENABLE = yes +LTO_ENABLE = yes diff --git a/keyboards/wuque/mammoth75x/mammoth75x.c b/keyboards/wuque/mammoth75x/mammoth75x.c new file mode 100644 index 000000000000..6f14657f8899 --- /dev/null +++ b/keyboards/wuque/mammoth75x/mammoth75x.c @@ -0,0 +1,67 @@ +/* Copyright 2021 wuquestudio + * + * 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 . + */ + +#include "mammoth75x.h" + +#ifdef VIA_ENABLE +static uint8_t encoder_state[ENCODERS] = {0}; +static keypos_t encoder_cw[ENCODERS] = ENCODERS_CW_KEY; +static keypos_t encoder_ccw[ENCODERS] = ENCODERS_CCW_KEY; + +void encoder_action_unregister(void) +{ + for (int index = 0; index < ENCODERS; ++index) + { + if (encoder_state[index]) + { + keyevent_t encoder_event = (keyevent_t){ + .key = encoder_state[index] >> 1 ? encoder_cw[index] : encoder_ccw[index], + .pressed = false, + .time = (timer_read() | 1)}; + encoder_state[index] = 0; + action_exec(encoder_event); + } + } +} +void encoder_action_register(uint8_t index, bool clockwise) +{ + keyevent_t encoder_event = (keyevent_t){ + .key = clockwise ? encoder_cw[index] : encoder_ccw[index], + .pressed = true, + .time = (timer_read() | 1)}; + encoder_state[index] = (clockwise ^ 1) | (clockwise << 1); + action_exec(encoder_event); +} + +void matrix_scan_kb(void) +{ + encoder_action_unregister(); + matrix_scan_user(); +} + +bool encoder_update_kb(uint8_t index, bool clockwise) +{ + encoder_action_register(index, clockwise); + return true; +}; +#else +bool encoder_update_kb(uint8_t index, bool clockwise) { + if (!encoder_update_user(index, clockwise)) { return false; } + tap_code_delay(clockwise ? KC_VOLU : KC_VOLD, 10); + return true; +} +#endif + diff --git a/keyboards/wuque/mammoth75x/mammoth75x.h b/keyboards/wuque/mammoth75x/mammoth75x.h new file mode 100644 index 000000000000..a3ab71caa168 --- /dev/null +++ b/keyboards/wuque/mammoth75x/mammoth75x.h @@ -0,0 +1,223 @@ +/* Copyright 2021 wuquestudio + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + + +/* Standard Arrangement + * ┌───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┐ + * │00 ││01 │02 │03 │04 ││05 │06 │07 │08 ││09 │0a │0b │0c ││0d │ + * └───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┘ + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ ◯ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │3d │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤ ┌───┬───┐ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │ │2e │2f │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ├───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │ │3e │3f │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤ └───┴───┘ + * │40 │41 │42 │43 │44 │45 │46 │47 │48 │49 │4a │4b │4c │4d │ ┌───┐ + * ├────┼───┴┬──┴─┬─┴───┴──┬┴───┼───┴───┴──┬┴───┼───┴┬────┬┴───┘ │4e │ + * │50 │51 │52 │54 │56 │58 │5a │5b │5c │ ┌───┼───┼───┐ + * └────┴────┴────┴────────┴────┴──────────┴────┴────┴────┘ │5d │5e │5f │ + * └───┴───┴───┘ + */ +#define LAYOUT_all( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K53, K0E, K55, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K3F, \ + K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4D, K4E, \ + K50, K51, K52, K54, K56, K58, K5A, K5B, K5C, K5D, K5E, K5F \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, KC_NO }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, KC_NO, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K3F }, \ + { K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4D, K4E, KC_NO }, \ + { K50, K51, K52, K53, K54, K55, K56, KC_NO, K58, KC_NO, K5A, K5B, K5C, K5D, K5E, K5F }, \ +} + + +/* LAYOUT_75_ansi + * ┌───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┐ + * │00 ││01 │02 │03 │04 ││05 │06 │07 │08 ││09 │0a │0b │0c ││0d │ + * └───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┘ + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ◯ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ┌───┬───┐ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │ │2e │2f │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ├───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │ │3e │3f │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ └───┴───┘ + * │40 │42 │43 │44 │45 │46 │47 │48 │49 │4a │4b │4c │ ┌───┐ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┘ │4e │ + * │50 │51 │52 │56 │5a │5b │5c │ ┌───┼───┼───┐ + * └────┴────┴────┴────────────────────────┴────┴────┴────┘ │5d │5e │5f │ + * └───┴───┴───┘ + */ +#define LAYOUT_75_ansi( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3E, K3F, \ + K40, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4E, \ + K50, K51, K52, K56, K5A, K5B, K5C, K5D, K5E, K5F \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, KC_NO }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, KC_NO, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KC_NO, K3E, K3F }, \ + { K40, KC_NO, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, KC_NO, K4E, KC_NO }, \ + { K50, K51, K52, KC_NO, KC_NO, KC_NO, K56, KC_NO, KC_NO, KC_NO, K5A, K5B, K5C, K5D, K5E, K5F }, \ +} + + +/* LAYOUT_75_ansi_split_lshift + * ┌───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┐ + * │00 ││01 │02 │03 │04 ││05 │06 │07 │08 ││09 │0a │0b │0c ││0d │ + * └───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┘ + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ◯ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ┌───┬───┐ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │ │2e │2f │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ├───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │ │3e │3f │ + * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ └───┴───┘ + * │40 │41 │42 │43 │44 │45 │46 │47 │48 │49 │4a │4b │4c │ ┌───┐ + * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┘ │4e │ + * │50 │51 │52 │56 │5a │5b │5c │ ┌───┼───┼───┐ + * └────┴────┴────┴────────────────────────┴────┴────┴────┘ │5d │5e │5f │ + * └───┴───┴───┘ + */ +#define LAYOUT_75_ansi_split_lshift( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3E, K3F, \ + K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4E, \ + K50, K51, K52, K56, K5A, K5B, K5C, K5D, K5E, K5F \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, KC_NO }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, KC_NO, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KC_NO, K3E, K3F }, \ + { K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, KC_NO, K4E, KC_NO }, \ + { K50, K51, K52, KC_NO, KC_NO, KC_NO, K56, KC_NO, KC_NO, KC_NO, K5A, K5B, K5C, K5D, K5E, K5F }, \ +} + + +/* LAYOUT_75_ansi_split_rshift + * ┌───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┐ + * │00 ││01 │02 │03 │04 ││05 │06 │07 │08 ││09 │0a │0b │0c ││0d │ + * └───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┘ + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ◯ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ┌───┬───┐ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │ │2e │2f │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ├───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │ │3e │3f │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤ └───┴───┘ + * │40 │42 │43 │44 │45 │46 │47 │48 │49 │4a │4b │4c │4d │ ┌───┐ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬┴───┘ │4e │ + * │50 │51 │52 │56 │5a │5b │5c │ ┌───┼───┼───┐ + * └────┴────┴────┴────────────────────────┴────┴────┴────┘ │5d │5e │5f │ + * └───┴───┴───┘ + */ +#define LAYOUT_75_ansi_split_rshift( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3E, K3F, \ + K40, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4D, K4E, \ + K50, K51, K52, K56, K5A, K5B, K5C, K5D, K5E, K5F \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, KC_NO }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, KC_NO, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KC_NO, K3E, K3F }, \ + { K40, KC_NO, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4D, K4E, KC_NO }, \ + { K50, K51, K52, KC_NO, KC_NO, KC_NO, K56, KC_NO, KC_NO, KC_NO, K5A, K5B, K5C, K5D, K5E, K5F }, \ +} + + +/* LAYOUT_75_ansi_split_bs + * ┌───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┐ + * │00 ││01 │02 │03 │04 ││05 │06 │07 │08 ││09 │0a │0b │0c ││0d │ + * └───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┘ + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ ◯ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │3d │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤ ┌───┬───┐ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │ │2e │2f │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ├───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │ │3e │3f │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ └───┴───┘ + * │40 │42 │43 │44 │45 │46 │47 │48 │49 │4a │4b │4c │ ┌───┐ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┘ │4e │ + * │50 │51 │52 │56 │5a │5b │5c │ ┌───┼───┼───┐ + * └────┴────┴────┴────────────────────────┴────┴────┴────┘ │5d │5e │5f │ + * └───┴───┴───┘ + */ +#define LAYOUT_75_ansi_split_bs( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K3F, \ + K40, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4E, \ + K50, K51, K52, K56, K5A, K5B, K5C, K5D, K5E, K5F \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, KC_NO }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, KC_NO, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K3F }, \ + { K40, KC_NO, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, KC_NO, K4E, KC_NO }, \ + { K50, K51, K52, KC_NO, KC_NO, KC_NO, K56, KC_NO, KC_NO, KC_NO, K5A, K5B, K5C, K5D, K5E, K5F }, \ +} + + +/* LAYOUT_75_ansi_split_space + * ┌───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┬───┬───┬───┐┌───┐ + * │00 ││01 │02 │03 │04 ││05 │06 │07 │08 ││09 │0a │0b │0c ││0d │ + * └───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┴───┴───┴───┘└───┘ + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ◯ + * │10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1a │1b │1c │1d │ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ┌───┬───┐ + * │20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2a │2b │2c │2d │ │2e │2f │ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ├───┼───┤ + * │30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3a │3b │3c │ │3e │3f │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ └───┴───┘ + * │40 │42 │43 │44 │45 │46 │47 │48 │49 │4a │4b │4c │ ┌───┐ + * ├────┬───┴┬──┴─┬─┴───┴──┬┴───┼───┴───┴──┬┴───┼───┴┬────┬────┘ │4e │ + * │50 │51 │52 │54 │56 │58 │5a │5b │5c │ ┌───┼───┼───┐ + * └────┴────┴────┴────────┴────┴──────────┴────┴────┴────┘ │5d │5e │5f │ + * └───┴───┴───┘ + */ +#define LAYOUT_75_ansi_split_space( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3E, K3F, \ + K40, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4E, \ + K50, K51, K52, K54, K56, K58, K5A, K5B, K5C, K5D, K5E, K5F \ +) { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, KC_NO }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, KC_NO, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, KC_NO, K3E, K3F }, \ + { K40, KC_NO, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, KC_NO, K4E, KC_NO }, \ + { K50, K51, K52, KC_NO, K54, KC_NO, K56, KC_NO, K58, KC_NO, K5A, K5B, K5C, K5D, K5E, K5F }, \ +} diff --git a/keyboards/wuque/mammoth75x/readme.md b/keyboards/wuque/mammoth75x/readme.md new file mode 100644 index 000000000000..9528552fb17e --- /dev/null +++ b/keyboards/wuque/mammoth75x/readme.md @@ -0,0 +1,25 @@ +# mammoth75x +​ +![mammoth75x](https://i.imgur.com/mhIKh2P.jpeg) +​ +More Info at [wuquestudio](https://shop.wuquestudio.com/). +​ +* Keyboard Maintainer: [spbgzh](https://github.com/spbgzh) +* Hardware Supported: mammoth75x Standard +* Hardware Availability: [mammoth75x](https://shop.wuquestudio.com/) +​ +Make example for this keyboard (after setting up your build environment): + + make wuque/mammoth75x:default + +Flashing example for this keyboard: + + make wuque/mammoth75x:default:flash + +To reset the board into bootloader mode, do one of the following: + +* Tap the Reset switch mounted on the PCB +* In the case of the default keymap, use the key combination Fn + PageUp +* Hold the Esc key while connecting the USB cable (also erases persistent settings) + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/wuque/mammoth75x/rules.mk b/keyboards/wuque/mammoth75x/rules.mk new file mode 100644 index 000000000000..d34c14e73faa --- /dev/null +++ b/keyboards/wuque/mammoth75x/rules.mk @@ -0,0 +1,22 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +ENCODER_ENABLE = yes # Enable Encoder From 0f96364daf418c395e583ae639fdd74e71c74142 Mon Sep 17 00:00:00 2001 From: David Martinz Date: Tue, 26 Oct 2021 20:05:37 -0300 Subject: [PATCH 0034/1136] [Keymap] Adding a new keymap for bm60poker and some led configs (#14918) --- .../bm60poker/keymaps/david/keymap.c | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 keyboards/kprepublic/bm60poker/keymaps/david/keymap.c diff --git a/keyboards/kprepublic/bm60poker/keymaps/david/keymap.c b/keyboards/kprepublic/bm60poker/keymaps/david/keymap.c new file mode 100644 index 000000000000..5050b25a909e --- /dev/null +++ b/keyboards/kprepublic/bm60poker/keymaps/david/keymap.c @@ -0,0 +1,58 @@ +/* Copyright 2021 David Martinz + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_60_ansi(KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, + KC_RSFT, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(1), KC_RCTL), + [1] = LAYOUT_60_ansi(KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, + RESET, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_UP, KC_INS, KC_HOME, KC_END, + KC_TRNS, KC_MUTE, KC_VOLD, KC_VOLU, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_PGDN, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS) +}; + +#ifdef RGB_MATRIX_ENABLE +void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { + // caps lock white + if (host_keyboard_led_state().caps_lock) { + RGB_MATRIX_INDICATOR_SET_COLOR(28, 200, 200, 200); + } + + // layer state + switch (get_highest_layer(layer_state)) { + case 0: + // RGB_MATRIX_INDICATOR_SET_COLOR(59, 0, 0, 0); + break; + case 1: + RGB_MATRIX_INDICATOR_SET_COLOR(59, 128, 0, 0); + break; + case 2: + RGB_MATRIX_INDICATOR_SET_COLOR(59, 0, 128, 0); + break; + case 3: + RGB_MATRIX_INDICATOR_SET_COLOR(59, 0, 0, 128); + break; + default: + // white + RGB_MATRIX_INDICATOR_SET_COLOR(59, 128, 128, 128); + break; + } +} +#endif From 015c4cf5beab530916b6c539583f9b7179bf42d3 Mon Sep 17 00:00:00 2001 From: MasterSpoon <84671859+MasterSpoon@users.noreply.github.com> Date: Wed, 27 Oct 2021 09:10:48 +1000 Subject: [PATCH 0035/1136] Update mcu_selection.mk with current ChibiOS path (#14909) --- quantum/mcu_selection.mk | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk index f7eaeec8ac44..3b86433a8690 100644 --- a/quantum/mcu_selection.mk +++ b/quantum/mcu_selection.mk @@ -122,7 +122,7 @@ ifneq ($(findstring STM32F042, $(MCU)),) MCU_SERIES = STM32F0xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32F042x6 @@ -154,7 +154,7 @@ ifneq ($(findstring STM32F072, $(MCU)),) MCU_SERIES = STM32F0xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32F072xB @@ -186,7 +186,7 @@ ifneq ($(findstring STM32F103, $(MCU)),) MCU_SERIES = STM32F1xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32F103x8 @@ -218,7 +218,7 @@ ifneq ($(findstring STM32F303, $(MCU)),) MCU_SERIES = STM32F3xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32F303xC @@ -250,7 +250,7 @@ ifneq ($(findstring STM32F401, $(MCU)),) MCU_SERIES = STM32F4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ ifeq ($(strip $(BOOTLOADER)), tinyuf2) MCU_LDSCRIPT ?= STM32F401xC_tinyuf2 @@ -287,7 +287,7 @@ ifneq ($(findstring STM32F407, $(MCU)),) MCU_SERIES = STM32F4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32F407xE @@ -319,7 +319,7 @@ ifneq ($(findstring STM32F411, $(MCU)),) MCU_SERIES = STM32F4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ ifeq ($(strip $(BOOTLOADER)), tinyuf2) MCU_LDSCRIPT ?= STM32F411xE_tinyuf2 @@ -356,8 +356,7 @@ ifneq ($(findstring STM32F446, $(MCU)),) MCU_SERIES = STM32F4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /os/common/startup/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32F446xE @@ -386,7 +385,7 @@ ifneq ($(findstring STM32G431, $(MCU)),) MCU_SERIES = STM32G4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32G431xB @@ -418,7 +417,7 @@ ifneq ($(findstring STM32G474, $(MCU)),) MCU_SERIES = STM32G4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32G474xE @@ -450,7 +449,7 @@ ifneq (,$(filter $(MCU),STM32L433 STM32L443)) MCU_SERIES = STM32L4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32L432xC @@ -484,7 +483,7 @@ ifneq (,$(filter $(MCU),STM32L412 STM32L422)) MCU_SERIES = STM32L4xx # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ # or /ld/ MCU_LDSCRIPT ?= STM32L412xB From e90e633c3bc45b0abca3c194d1dc231956230138 Mon Sep 17 00:00:00 2001 From: MakotoKurauchi Date: Wed, 27 Oct 2021 08:28:41 +0900 Subject: [PATCH 0036/1136] [Keymap] Add via keymap for meishi2 (#14892) Co-authored-by: Ryan --- keyboards/meishi2/keymaps/via/keymap.c | 31 ++++++++++++++++++++++++++ keyboards/meishi2/keymaps/via/rules.mk | 3 +++ 2 files changed, 34 insertions(+) create mode 100644 keyboards/meishi2/keymaps/via/keymap.c create mode 100644 keyboards/meishi2/keymaps/via/rules.mk diff --git a/keyboards/meishi2/keymaps/via/keymap.c b/keyboards/meishi2/keymaps/via/keymap.c new file mode 100644 index 000000000000..be706ea09a63 --- /dev/null +++ b/keyboards/meishi2/keymaps/via/keymap.c @@ -0,0 +1,31 @@ +/* Copyright 2019 Biacco42 + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( /* Base */ + LCTL(KC_Z), LCTL(KC_X), LCTL(KC_C), LCTL(KC_V) + ), + [1] = LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + [2] = LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + [3] = LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), +}; diff --git a/keyboards/meishi2/keymaps/via/rules.mk b/keyboards/meishi2/keymaps/via/rules.mk new file mode 100644 index 000000000000..c859353a464c --- /dev/null +++ b/keyboards/meishi2/keymaps/via/rules.mk @@ -0,0 +1,3 @@ +VIA_ENABLE = yes +CONSOLE_ENABLE = no +COMMAND_ENABLE = no From 2938c4e0594778ccf8b3a72f7e2cbb357bd67ede Mon Sep 17 00:00:00 2001 From: npspears <40127181+npspears@users.noreply.github.com> Date: Tue, 26 Oct 2021 18:34:21 -0500 Subject: [PATCH 0037/1136] [Keyboard] add support for Phoenix45_Ortho PCB (#14798) Co-authored-by: Drashna Jaelre --- .../checkerboards/phoenix45_ortho/config.h | 52 +++++++++++++++++ .../checkerboards/phoenix45_ortho/info.json | 16 +++++ .../phoenix45_ortho/keymaps/2x3u/config.h | 19 ++++++ .../phoenix45_ortho/keymaps/2x3u/keymap.c | 46 +++++++++++++++ .../phoenix45_ortho/keymaps/6u/config.h | 19 ++++++ .../phoenix45_ortho/keymaps/6u/keymap.c | 46 +++++++++++++++ .../phoenix45_ortho/keymaps/default/config.h | 19 ++++++ .../phoenix45_ortho/keymaps/default/keymap.c | 46 +++++++++++++++ .../phoenix45_ortho/keymaps/via/config.h | 19 ++++++ .../phoenix45_ortho/keymaps/via/keymap.c | 52 +++++++++++++++++ .../phoenix45_ortho/keymaps/via/rules.mk | 1 + .../phoenix45_ortho/phoenix45_ortho.c | 29 ++++++++++ .../phoenix45_ortho/phoenix45_ortho.h | 58 +++++++++++++++++++ .../checkerboards/phoenix45_ortho/readme.md | 17 ++++++ .../checkerboards/phoenix45_ortho/rules.mk | 26 +++++++++ 15 files changed, 465 insertions(+) create mode 100644 keyboards/checkerboards/phoenix45_ortho/config.h create mode 100644 keyboards/checkerboards/phoenix45_ortho/info.json create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/config.h create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/keymap.c create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/6u/config.h create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/6u/keymap.c create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/default/config.h create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/default/keymap.c create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/via/config.h create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/via/keymap.c create mode 100644 keyboards/checkerboards/phoenix45_ortho/keymaps/via/rules.mk create mode 100644 keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.c create mode 100644 keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.h create mode 100644 keyboards/checkerboards/phoenix45_ortho/readme.md create mode 100644 keyboards/checkerboards/phoenix45_ortho/rules.mk diff --git a/keyboards/checkerboards/phoenix45_ortho/config.h b/keyboards/checkerboards/phoenix45_ortho/config.h new file mode 100644 index 000000000000..ebd954be33af --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/config.h @@ -0,0 +1,52 @@ +/* Copyright 2021 Nathan Spears + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x7070 +#define PRODUCT_ID 0x1849 +#define DEVICE_VER 0x0001 +#define MANUFACTURER Nasp +#define PRODUCT PHOENIX45_ORTHO + +/* key matrix size */ +#define MATRIX_ROWS 4 +#define MATRIX_COLS 13 + +/* key matrix pins */ +#define MATRIX_ROW_PINS { D2, D1, D0, C4 } +#define MATRIX_COL_PINS { D3, C2, C5, B0, D6, D5, D4, B4, B5, B6, B7, C7, C6 } +#define UNUSED_PINS + +/* COL2ROW or ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE + +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* encoder pads */ +#define ENCODERS_PAD_A { B1 } +#define ENCODERS_PAD_B { B2 } +#define ENCODER_RESOLUTION 4 diff --git a/keyboards/checkerboards/phoenix45_ortho/info.json b/keyboards/checkerboards/phoenix45_ortho/info.json new file mode 100644 index 000000000000..f5c02caeff90 --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/info.json @@ -0,0 +1,16 @@ +{ + "keyboard_name": "Phoenix45_Ortho", + "url": "www.checkerboards.xyz", + "maintainer": "nasp", + "layouts": { + "LAYOUT_ortho_2x225u": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.5}, {"x":3.75, "y":3, "w":2.25}, {"label":"Fn", "x":6, "y":3}, {"x":7, "y":3, "w":2.25}, {"label":"Meta", "x":9.25, "y":3, "w":1.5}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] + }, + "LAYOUT_ortho_2x3u": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":3}, {"x":6.5, "y":3, "w":3}, {"label":"Meta", "x":9.5, "y":3, "w":1.25}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] + }, +"LAYOUT_ortho_6u": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.25}, {"label":"", "x":3.5, "y":3, "w":6}, {"label":"Meta", "x":9.5, "y":3, "w":1.25}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] + } + } +} \ No newline at end of file diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/config.h b/keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/config.h new file mode 100644 index 000000000000..b1498826ee3e --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/config.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Nathan Spears + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define TAPPING_TOGGLE 2 diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/keymap.c b/keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/keymap.c new file mode 100644 index 000000000000..d72c7fecc123 --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/2x3u/keymap.c @@ -0,0 +1,46 @@ +/* Copyright 2021 Nathan Spears + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +// Defines for task manager and such +#define CALTDEL LCTL(LALT(KC_DEL)) +#define TSKMGR LCTL(LSFT(KC_ESC)) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT_ortho_2x3u( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_PGUP, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + CTL_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_PGDN, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_HOME, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, + KC_GRV, KC_LGUI, KC_LALT, TT(1), LT(2, KC_SPC), CALTDEL, KC_RALT, KC_CAPS + ), + + [1] = LAYOUT_ortho_2x3u( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_SLSH, KC_1, KC_2, KC_3, KC_4, KC_5, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS, + _______, _______, _______, _______, _______, _______, _______, _______, KC_PPLS, KC_EQL, _______, _______, _______, + KC_ESC, CALTDEL, TSKMGR, _______, _______, KC_NUBS, KC_GRV, _______ + ), + + [2] = LAYOUT_ortho_2x3u( + _______, _______, _______, KC_UP, _______, _______, _______, _______, KC_UNDS, _______, KC_LBRC, KC_RBRC, _______, + _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, KC_MINS, _______, KC_LCBR, KC_RCBR, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + RESET, _______, _______, _______, _______, _______, _______, _______ + ) +}; + diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/6u/config.h b/keyboards/checkerboards/phoenix45_ortho/keymaps/6u/config.h new file mode 100644 index 000000000000..b1498826ee3e --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/6u/config.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Nathan Spears + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define TAPPING_TOGGLE 2 diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/6u/keymap.c b/keyboards/checkerboards/phoenix45_ortho/keymaps/6u/keymap.c new file mode 100644 index 000000000000..53bc6a3286ba --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/6u/keymap.c @@ -0,0 +1,46 @@ +/* Copyright 2021 Nathan Spears + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +// Defines for task manager and such +#define CALTDEL LCTL(LALT(KC_DEL)) +#define TSKMGR LCTL(LSFT(KC_ESC)) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT_ortho_6u( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_PGUP, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + CTL_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_PGDN, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, TT(2), KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, + KC_GRV, KC_LGUI, KC_LALT, LT(1, KC_SPC), CALTDEL, KC_RALT, KC_CAPS + ), + + [1] = LAYOUT_ortho_6u( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_SLSH, KC_1, KC_2, KC_3, KC_4, KC_5, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS, + _______, _______, _______, _______, _______, _______, _______, _______, KC_PPLS, KC_EQL, _______, _______, _______, + KC_ESC, CALTDEL, TSKMGR, _______, KC_NUBS, KC_GRV, _______ + ), + + [2] = LAYOUT_ortho_6u( + _______, _______, _______, KC_UP, _______, _______, _______, _______, KC_UNDS, _______, KC_LBRC, KC_RBRC, _______, + _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, KC_MINS, _______, KC_LCBR, KC_RCBR, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + RESET, _______, _______, _______, _______, _______, _______ + ) +}; + diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/default/config.h b/keyboards/checkerboards/phoenix45_ortho/keymaps/default/config.h new file mode 100644 index 000000000000..b1498826ee3e --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/default/config.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Nathan Spears + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define TAPPING_TOGGLE 2 diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/default/keymap.c b/keyboards/checkerboards/phoenix45_ortho/keymaps/default/keymap.c new file mode 100644 index 000000000000..cfe0615dee14 --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/default/keymap.c @@ -0,0 +1,46 @@ +/* Copyright 2021 Nathan Spears + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +// Defines for task manager and such +#define CALTDEL LCTL(LALT(KC_DEL)) +#define TSKMGR LCTL(LSFT(KC_ESC)) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT_ortho_2x225u( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_PGUP, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + CTL_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_PGDN, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_HOME, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, + KC_GRV, KC_LGUI, KC_LALT, TT(1), CALTDEL, LT(2, KC_SPC), CALTDEL, KC_RALT, KC_CAPS + ), + + [1] = LAYOUT_ortho_2x225u( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_SLSH, KC_1, KC_2, KC_3, KC_4, KC_5, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS, + _______, _______, _______, _______, _______, _______, _______, _______, KC_PPLS, KC_EQL, _______, _______, _______, + KC_ESC, CALTDEL, TSKMGR, _______, _______, _______, KC_NUBS, KC_GRV, _______ + ), + + [2] = LAYOUT_ortho_2x225u( + _______, _______, _______, KC_UP, _______, _______, _______, _______, KC_UNDS, _______, KC_LBRC, KC_RBRC, _______, + _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, KC_MINS, _______, KC_LCBR, KC_RCBR, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + RESET, _______, _______, _______, _______, _______, _______, _______, _______ + ) +}; + diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/via/config.h b/keyboards/checkerboards/phoenix45_ortho/keymaps/via/config.h new file mode 100644 index 000000000000..b1498826ee3e --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/via/config.h @@ -0,0 +1,19 @@ +/* Copyright 2021 Nathan Spears + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define TAPPING_TOGGLE 2 diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/via/keymap.c b/keyboards/checkerboards/phoenix45_ortho/keymaps/via/keymap.c new file mode 100644 index 000000000000..9bd72c06cf5a --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/via/keymap.c @@ -0,0 +1,52 @@ +/* Copyright 2021 Nathan Spears + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +// Defines for task manager and such +#define CALTDEL LCTL(LALT(KC_DEL)) +#define TSKMGR LCTL(LSFT(KC_ESC)) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT_ortho_2x225u( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_PGUP, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + CTL_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_PGDN, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_HOME, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, + KC_GRV, KC_LGUI, KC_LALT, TT(1), CALTDEL, LT(2, KC_SPC), CALTDEL, KC_RALT, KC_CAPS + ), + + [1] = LAYOUT_ortho_2x225u( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + KC_SLSH, KC_1, KC_2, KC_3, KC_4, KC_5, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSLS, + _______, _______, _______, _______, _______, _______, _______, _______, KC_PPLS, KC_EQL, _______, _______, _______, + KC_ESC, CALTDEL, TSKMGR, _______, _______, _______, KC_NUBS, KC_GRV, _______ + ), + + [2] = LAYOUT_ortho_2x225u( + _______, _______, _______, KC_UP, _______, _______, _______, _______, KC_UNDS, _______, KC_LBRC, KC_RBRC, _______, + _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, KC_MINS, _______, KC_LCBR, KC_RCBR, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + RESET, _______, _______, _______, _______, _______, _______, _______, _______ + ), + + [3] = LAYOUT_ortho_2x225u( + _______, _______, _______, KC_UP, _______, _______, _______, _______, KC_UNDS, _______, KC_LBRC, KC_RBRC, _______, + _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, KC_MINS, _______, KC_LCBR, KC_RCBR, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + RESET, _______, _______, _______, _______, _______, _______, _______, _______ + ) +}; diff --git a/keyboards/checkerboards/phoenix45_ortho/keymaps/via/rules.mk b/keyboards/checkerboards/phoenix45_ortho/keymaps/via/rules.mk new file mode 100644 index 000000000000..69de2e4c5a0c --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.c b/keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.c new file mode 100644 index 000000000000..89ce3f5ce91a --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.c @@ -0,0 +1,29 @@ +/* Copyright 2021 Nathan Spears + * + * 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 . + */ + +#include "phoenix45_ortho.h" + +bool encoder_update_kb(uint8_t index, bool clockwise) { + if (!encoder_update_user(index, clockwise)) { return false; } + if (index == 0) { + if (clockwise) { + tap_code_delay(KC_VOLD, 10); + } else { + tap_code_delay(KC_VOLU, 10); + } + } + return true; +} diff --git a/keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.h b/keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.h new file mode 100644 index 000000000000..8abf2875a9f8 --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/phoenix45_ortho.h @@ -0,0 +1,58 @@ +/* Copyright 2021 Nathan Spears + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + +#define XXX KC_NO + + +#define LAYOUT_ortho_2x225u( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, \ + k30, k31, k32, k34, k36, k38, k39, k3B, k3C \ +) { \ + { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C }, \ + { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C }, \ + { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C }, \ + { k30, k31, k32, XXX, k34, XXX, k36, XXX, k38, k39, XXX, k3B, k3C } \ +} + +#define LAYOUT_ortho_2x3u( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, \ + k30, k31, k32, k34, k38, k39, k3B, k3C \ +) { \ + { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C }, \ + { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C }, \ + { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C }, \ + { k30, k31, k32, XXX, k34, XXX, XXX, XXX, k38, k39, XXX, k3B, k3C } \ +} + +#define LAYOUT_ortho_6u( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, kOC, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, \ + k30, k31, k32, k36, k39, k3B, k3C \ +) { \ + { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, kOC }, \ + { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k2C }, \ + { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k3C }, \ + { k30, k31, k32, XXX, XXX, XXX, k36, XXX, XXX, k39, XXX, k3B, k3C } \ +} diff --git a/keyboards/checkerboards/phoenix45_ortho/readme.md b/keyboards/checkerboards/phoenix45_ortho/readme.md new file mode 100644 index 000000000000..46e158c0aac2 --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/readme.md @@ -0,0 +1,17 @@ +# Phoenix45_Ortho + +![Phoenix45_Ortho](https://i.imgur.com/OvgOhIe.png) + +The Phoenix45_Ortho PCB is an ortholinear alternative to Mechvault's Phoenix45. It should also work in the JD45. + +* Keyboard Maintainer: [Nasp](https://github.com/npspears) +* Hardware Supported: Phoenix45 +* Hardware Availability: https://www.checkerboards.xyz/phoenix45-ortho.html + +Make example for this keyboard (after setting up your build environment): + + make checkerboards/phoenix45_ortho:default + +To put the PCB into bootloader mode, short the two pin holes together that are just beneath diode #23. + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). \ No newline at end of file diff --git a/keyboards/checkerboards/phoenix45_ortho/rules.mk b/keyboards/checkerboards/phoenix45_ortho/rules.mk new file mode 100644 index 000000000000..128b76058d32 --- /dev/null +++ b/keyboards/checkerboards/phoenix45_ortho/rules.mk @@ -0,0 +1,26 @@ +# MCU name +MCU = atmega32u2 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = no # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +UNICODE_ENABLE = yes # Unicode +ENCODER_ENABLE = yes # Encoder enable + +# Disable unsupported hardware +AUDIO_SUPPORTED = no +BACKLIGHT_SUPPORTED = no From b168fb3b2cb47f4546d5177152f6e4ee7e870269 Mon Sep 17 00:00:00 2001 From: Kyrre Havik Date: Wed, 27 Oct 2021 01:41:54 +0200 Subject: [PATCH 0038/1136] [Keyboard] Add minimon/Index tab 13x6 ortho (#14765) Co-authored-by: Joel Challis Co-authored-by: Drashna Jaelre Co-authored-by: Ryan --- keyboards/minimon/index_tab/config.h | 64 +++++++++++++++++++ keyboards/minimon/index_tab/index_tab.c | 14 ++++ keyboards/minimon/index_tab/index_tab.h | 36 +++++++++++ keyboards/minimon/index_tab/info.json | 17 +++++ .../index_tab/keymaps/default/keymap.c | 44 +++++++++++++ .../index_tab/keymaps/default/readme.md | 6 ++ .../minimon/index_tab/keymaps/via/keymap.c | 53 +++++++++++++++ .../minimon/index_tab/keymaps/via/rules.mk | 1 + keyboards/minimon/index_tab/readme.md | 35 ++++++++++ keyboards/minimon/index_tab/rules.mk | 21 ++++++ keyboards/minimon/info.json | 4 ++ keyboards/minimon/readme.md | 9 +++ 12 files changed, 304 insertions(+) create mode 100644 keyboards/minimon/index_tab/config.h create mode 100644 keyboards/minimon/index_tab/index_tab.c create mode 100644 keyboards/minimon/index_tab/index_tab.h create mode 100644 keyboards/minimon/index_tab/info.json create mode 100644 keyboards/minimon/index_tab/keymaps/default/keymap.c create mode 100644 keyboards/minimon/index_tab/keymaps/default/readme.md create mode 100644 keyboards/minimon/index_tab/keymaps/via/keymap.c create mode 100644 keyboards/minimon/index_tab/keymaps/via/rules.mk create mode 100644 keyboards/minimon/index_tab/readme.md create mode 100644 keyboards/minimon/index_tab/rules.mk create mode 100644 keyboards/minimon/info.json create mode 100644 keyboards/minimon/readme.md diff --git a/keyboards/minimon/index_tab/config.h b/keyboards/minimon/index_tab/config.h new file mode 100644 index 000000000000..fc02185545d3 --- /dev/null +++ b/keyboards/minimon/index_tab/config.h @@ -0,0 +1,64 @@ +/* +Copyright 2020 Kyrre Havik Eriksen + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x4B49 +#define PRODUCT_ID 0x1306 +#define DEVICE_VER 0x0001 +#define PRODUCT Index Tab + +/* key matrix size */ +#define MATRIX_ROWS 6 +#define MATRIX_COLS 13 + +/* key matrix pins */ +#define MATRIX_ROW_PINS { D3, B7, B3, B2, B1, B0 } +#define MATRIX_COL_PINS { F7, C7, C6, B6, B5, B4, D7, D6, D4, D5, D2, F1, F0 } +#define UNUSED_PINS { F4, F5, F6, D1, D0 } + + +/* COL2ROW, ROW2COL*/ +#define DIODE_DIRECTION COL2ROW + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +#define RGB_DI_PIN E6 +#define RGBLED_NUM 10 +#define RGBLIGHT_SLEEP + +#define RGBLIGHT_EFFECT_BREATHING +#define RGBLIGHT_EFFECT_RAINBOW_MOOD +#define RGBLIGHT_EFFECT_RAINBOW_SWIRL +#define RGBLIGHT_EFFECT_SNAKE +#define RGBLIGHT_EFFECT_KNIGHT +#define RGBLIGHT_EFFECT_CHRISTMAS +#define RGBLIGHT_EFFECT_STATIC_GRADIENT +#define RGBLIGHT_EFFECT_RGB_TEST +#define RGBLIGHT_EFFECT_ALTERNATING +#define RGBLIGHT_EFFECT_TWINKLE diff --git a/keyboards/minimon/index_tab/index_tab.c b/keyboards/minimon/index_tab/index_tab.c new file mode 100644 index 000000000000..a0d8377e9723 --- /dev/null +++ b/keyboards/minimon/index_tab/index_tab.c @@ -0,0 +1,14 @@ +/* +Copyright 2020 Kyrre Havik Eriksen +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 . +*/ +#include "index_tab.h" diff --git a/keyboards/minimon/index_tab/index_tab.h b/keyboards/minimon/index_tab/index_tab.h new file mode 100644 index 000000000000..cb9d3c5ae6b6 --- /dev/null +++ b/keyboards/minimon/index_tab/index_tab.h @@ -0,0 +1,36 @@ +/* Copyright 2020 Kyrre Havik Eriksen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + +#define LAYOUT( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0a, K0b, K0c, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1a, K1b, K1c, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2a, K2b, K2c, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3a, K3b, K3c, \ + K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4a, K4b, K4c, \ + K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5a, K5b, K5c \ +) \ + { \ + { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0a, K0b, K0c }, \ + { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1a, K1b, K1c }, \ + { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2a, K2b, K2c }, \ + { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3a, K3b, K3c }, \ + { K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4a, K4b, K4c }, \ + { K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5a, K5b, K5c } \ + } diff --git a/keyboards/minimon/index_tab/info.json b/keyboards/minimon/index_tab/info.json new file mode 100644 index 000000000000..21ff5a3cde12 --- /dev/null +++ b/keyboards/minimon/index_tab/info.json @@ -0,0 +1,17 @@ +{ + "keyboard_name": "Index Tab", + "maintainer": "kyrremann", + "url": "https://github.com/Kyrremann/index-tab", + "layouts": { + "LAYOUT_all": { + "layout": [ + {"label":"CAPS", "x":0, "y":0}, {"label":"F1", "x":1, "y":0}, {"label":"F2", "x":2, "y":0}, {"label":"F3", "x":3, "y":0}, {"label":"F4", "x":4, "y":0}, {"label":"F5", "x":5, "y":0}, {"label":"F6", "x":6, "y":0}, {"label":"F7", "x":7, "y":0}, {"label":"F8", "x":8, "y":0}, {"label":"F9", "x":9, "y":0}, {"label":"F10", "x":10, "y":0}, {"label":"F11", "x":11, "y":0}, {"label":"F12", "x":12, "y":0}, + {"label":"<", "x":0, "y":1}, {"label":"1", "x":1, "y":1}, {"label":"2", "x":2, "y":1}, {"label":"3", "x":3, "y":1}, {"label":"4", "x":4, "y":1}, {"label":"5", "x":5, "y":1}, {"label":"6", "x":6, "y":1}, {"label":"7", "x":7, "y":1}, {"label":"8", "x":8, "y":1}, {"label":"9", "x":9, "y":1}, {"label":"0", "x":10, "y":1}, {"label":"+", "x":11, "y":1}, {"label":"\u00b4", "x":12, "y":1}, + {"label":"TAB", "x":0, "y":2}, {"label":"q", "x":1, "y":2}, {"label":"w", "x":2, "y":2}, {"label":"e", "x":3, "y":2}, {"label":"r", "x":4, "y":2}, {"label":"t", "x":5, "y":2}, {"label":"y", "x":6, "y":2}, {"label":"u", "x":7, "y":2}, {"label":"i", "x":8, "y":2}, {"label":"o", "x":9, "y":2}, {"label":"p", "x":10, "y":2}, {"label":"\u00e5", "x":11, "y":2}, {"label":"BKSP", "x":12, "y":2}, + {"label":"CTRL", "x":0, "y":3}, {"label":"a", "x":1, "y":3}, {"label":"s", "x":2, "y":3}, {"label":"d", "x":3, "y":3}, {"label":"f", "x":4, "y":3}, {"label":"g", "x":5, "y":3}, {"label":"h", "x":6, "y":3}, {"label":"j", "x":7, "y":3}, {"label":"k", "x":8, "y":3}, {"label":"l", "x":9, "y":3}, {"label":"\u00f8", "x":10, "y":3}, {"label":"\u00e6", "x":11, "y":3}, {"label":"\u00a8", "x":12, "y":3}, + {"label":"SHIFT", "x":0, "y":4}, {"label":"z", "x":1, "y":4}, {"label":"x", "x":2, "y":4}, {"label":"c", "x":3, "y":4}, {"label":"v", "x":4, "y":4}, {"label":"b", "x":5, "y":4}, {"label":"n", "x":6, "y":4}, {"label":"m", "x":7, "y":4}, {"label":",", "x":8, "y":4}, {"label":".", "x":9, "y":4}, {"label":"-", "x":10, "y":4}, {"label":"\u2191", "x":11, "y":4}, {"label":"\u21b2", "x":12, "y":4}, + {"label":"ESC", "x":0, "y":5}, {"label":"\u00a7", "x":1, "y":5}, {"label":"WIN", "x":2, "y":5}, {"label":"LALT", "x":3, "y":5}, {"x":4, "y":5, "w":2}, {"x":6, "y":5, "w":2}, {"label":"FN", "x":8, "y":5}, {"label":"@", "x":9, "y":5}, {"label":"\u2190", "x":10, "y":5}, {"label":"\u2193", "x":11, "y":5}, {"label":"\u2192", "x":12, "y":5} + ] + } + } +} diff --git a/keyboards/minimon/index_tab/keymaps/default/keymap.c b/keyboards/minimon/index_tab/keymaps/default/keymap.c new file mode 100644 index 000000000000..9f2a3d1320ec --- /dev/null +++ b/keyboards/minimon/index_tab/keymaps/default/keymap.c @@ -0,0 +1,44 @@ +/* +Copyright 2020 Kyrre Havik Eriksen +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 . +*/ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[0] = LAYOUT( + KC_CAPS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + KC_NUBS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_BSPC, + KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_RBRC, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_UP, KC_ENT, + KC_ESC, KC_GRV, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_SPC, TG(1), KC_BSLS, KC_LEFT, KC_DOWN, KC_RGHT + ), + +[1] = LAYOUT( + KC_TRNS, RGB_TOG, RGB_MOD, RGB_RMOD,RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_P7, KC_P8, KC_P9, KC_PPLS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS, KC_TRNS, KC_P4, KC_P5, KC_P6, KC_PCMM, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MSTP, KC_VOLD, KC_MUTE, KC_VOLU, KC_MNXT, KC_P1, KC_P2, KC_P3, KC_PEQL, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MPLY, KC_MPLY, KC_MPLY, KC_TRNS, KC_P0, KC_P0, KC_PDOT, KC_PENT + ), + +[2] = LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; diff --git a/keyboards/minimon/index_tab/keymaps/default/readme.md b/keyboards/minimon/index_tab/keymaps/default/readme.md new file mode 100644 index 000000000000..3633ffcd08d4 --- /dev/null +++ b/keyboards/minimon/index_tab/keymaps/default/readme.md @@ -0,0 +1,6 @@ +Index Tab default keymap +======================== + +![Index Tab layout image](https://i.imgur.com/BSsNGL9.png) + +[Keyboard layout editor](http://www.keyboard-layout-editor.com/##@@_a:7%3B&=CAPS&=F1&=F2&=F3&=F4&=F5&=F6&=F7&=F8&=F9&=F10&=F11&=F12%3B&@=%3C&=1&=2&=3&=4&=5&=6&=7&=8&=9&=0&=+&=%C2%B4%3B&@=TAB&=q&=w&=e&=r&=t&=y&=u&=i&=o&=p&=%C3%A5&=BKSP%3B&@=CTRL&=a&=s&=d&=f&=g&=h&=j&=k&=l&=%C3%B8&=%C3%A6&=%C2%A8%3B&@=SHIFT&=z&=x&=c&=v&=b&=n&=m&=,&=.&=-&=%E2%86%91&=%E2%86%B2%3B&@=ESC&=%C2%A7&=WIN&=LALT&_w:2%3B&=&_w:2%3B&=&=FN&=%2F@&=%E2%86%90&=%E2%86%93&=%E2%86%92) diff --git a/keyboards/minimon/index_tab/keymaps/via/keymap.c b/keyboards/minimon/index_tab/keymaps/via/keymap.c new file mode 100644 index 000000000000..f6f0e0da1ef3 --- /dev/null +++ b/keyboards/minimon/index_tab/keymaps/via/keymap.c @@ -0,0 +1,53 @@ +/* +Copyright 2020 Kyrre Havik Eriksen +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 . +*/ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[0] = LAYOUT( + KC_CAPS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + KC_NUBS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_BSPC, + KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_RBRC, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_NUHS, KC_SFTENT, + KC_ESC, KC_GRV, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_SPC, TG(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT + ), + +[1] = LAYOUT( + KC_TRNS, RGB_TOG, RGB_MOD, RGB_RMOD,RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSLS, KC_PAST, KC_PMNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_P7, KC_P8, KC_P9, KC_PPLS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MRWD, KC_TRNS, KC_MSTP, KC_TRNS, KC_MFFD, KC_P4, KC_P5, KC_P6, KC_PCMM, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_VOLD, KC_MUTE, KC_VOLU, KC_MNXT, KC_P1, KC_P2, KC_P3, KC_PENT, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_TRNS, KC_TRNS, KC_MPLY, KC_TRNS, KC_P0, KC_P0, KC_PDOT, KC_PEQL + ), + +[2] = LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + +[3] = LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; diff --git a/keyboards/minimon/index_tab/keymaps/via/rules.mk b/keyboards/minimon/index_tab/keymaps/via/rules.mk new file mode 100644 index 000000000000..1e5b99807cb7 --- /dev/null +++ b/keyboards/minimon/index_tab/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/minimon/index_tab/readme.md b/keyboards/minimon/index_tab/readme.md new file mode 100644 index 000000000000..31ad51aa5529 --- /dev/null +++ b/keyboards/minimon/index_tab/readme.md @@ -0,0 +1,35 @@ +# Index Tab + +Not just another ortho-keyboard. but one catering to the northern marked with our extra letters. +This is a 13x6 ortho keyboard; giving you enough space for all the numbers, all the F-keys, and our precious extraordinary letters. + +![Picture of the keyboard in the wild](https://raw.githubusercontent.com/Kyrremann/index-tab/master/images/rev5-dsa-vilebloom.JPG) + +Keyboard Maintainer: [Kyrremann](https://github.com/Kyrremann) + +The keyboard files can be found here: https://github.com/Kyrremann/index-tab + + +## Instructions + +To create a hex file for the Index Tab, run: + + make minimon/index_tab:default + +Flash the keyboard with QMK Toolbox or run: + + make minimon/index_tab:default:flash + +How to enter bootloader (DFU): + +Press the reset button on the underside of the board, near the USB port. + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. +Brand new to QMK? Start with the [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + + +## Default layout + +![Index Tab layout image](https://raw.githubusercontent.com/Kyrremann/index-tab/master/images/index-tab.png) + +[Keyboard layout editor](http://www.keyboard-layout-editor.com/#/gists/2577189f7cf19d980fff8177d14dc3ec) diff --git a/keyboards/minimon/index_tab/rules.mk b/keyboards/minimon/index_tab/rules.mk new file mode 100644 index 000000000000..dcc5fd8be862 --- /dev/null +++ b/keyboards/minimon/index_tab/rules.mk @@ -0,0 +1,21 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output diff --git a/keyboards/minimon/info.json b/keyboards/minimon/info.json new file mode 100644 index 000000000000..6740fa750ff7 --- /dev/null +++ b/keyboards/minimon/info.json @@ -0,0 +1,4 @@ +{ + "maintainer": "Kyrremann", + "manufacturer": "Minimon" +} diff --git a/keyboards/minimon/readme.md b/keyboards/minimon/readme.md new file mode 100644 index 000000000000..cd020a11108d --- /dev/null +++ b/keyboards/minimon/readme.md @@ -0,0 +1,9 @@ +![Minimon logo](https://i.imgur.com/4SWEH5Kh.png) + +Having fun making keyboards for the northern marked, as we need an extra column for our extended alphabets. + +Maintained by [Kyrremann](https://github.com/Kyrremann). + +## Keyboards + +* [Index Tab](index_tab/) - 13x6 ortho keyboard From 312b1b95a88e1b4b6d0642e1f788bcbd3d8d589b Mon Sep 17 00:00:00 2001 From: JayceFayne <13365789+JayceFayne@users.noreply.github.com> Date: Wed, 27 Oct 2021 01:55:04 +0200 Subject: [PATCH 0039/1136] Document `MAGIC` feature (#14301) --- docs/config_options.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/config_options.md b/docs/config_options.md index dbf3d3da2eb0..cfbe39f0d32e 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -404,6 +404,8 @@ However, this will automatically disable the legacy TMK Macros and Functions fea Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU. +* `MAGIC_ENABLE` + * MAGIC actions (BOOTMAGIC without the boot) * `BOOTMAGIC_ENABLE` * Virtual DIP switch configuration * `MOUSEKEY_ENABLE` From c0c7c4692b83168cf016b7235133e121b0d1f6f0 Mon Sep 17 00:00:00 2001 From: Albert Y <76888457+filterpaper@users.noreply.github.com> Date: Wed, 27 Oct 2021 08:09:12 +0800 Subject: [PATCH 0040/1136] Add MAGIC_TOGGLE_GUI line to main keycode documentation (#14959) Co-authored-by: filterpaper --- docs/keycodes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/keycodes.md b/docs/keycodes.md index a134c5a1b289..9f61447dc5e0 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -344,6 +344,7 @@ See also: [Magic Keycodes](keycodes_magic.md) |`MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | |`MAGIC_NO_GUI` |`GUI_OFF`|Disable the GUI keys | |`MAGIC_UNNO_GUI` |`GUI_ON` |Enable the GUI keys | +|`MAGIC_TOGGLE_GUI` |`GUI_TOG`|Toggles the status of the GUI keys | |`MAGIC_SWAP_GRAVE_ESC` |`GE_SWAP`|Swap ` and Escape | |`MAGIC_UNSWAP_GRAVE_ESC` |`GE_NORM`|Unswap ` and Escape | |`MAGIC_SWAP_BACKSLASH_BACKSPACE` |`BS_SWAP`|Swap `\` and Backspace | From e5a729ccabf4c261a697dae22c5315fb1ae9990b Mon Sep 17 00:00:00 2001 From: projectcain <71684775+projectcain@users.noreply.github.com> Date: Tue, 26 Oct 2021 19:54:17 -0500 Subject: [PATCH 0041/1136] [Keyboard] add ProjectCain Vault35; update Vault45 (#13652) Co-authored-by: Drashna Jaelre Co-authored-by: ridingqwerty Co-authored-by: Ryan Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> --- keyboards/projectcain/vault35/config.h | 149 ++++++++++++++++++ keyboards/projectcain/vault35/info.json | 22 +++ .../vault35/keymaps/default/config.h | 24 +++ .../vault35/keymaps/default/keymap.c | 66 ++++++++ .../vault35/keymaps/default/readme.md | 1 + .../vault35/keymaps/default/rules.mk | 2 + keyboards/projectcain/vault35/readme.md | 21 +++ keyboards/projectcain/vault35/rules.mk | 21 +++ keyboards/projectcain/vault35/vault35.c | 29 ++++ keyboards/projectcain/vault35/vault35.h | 80 ++++++++++ keyboards/projectcain/vault45/info.json | 79 +++------- .../vault45/keymaps/default/keymap.c | 12 +- keyboards/projectcain/vault45/vault45.h | 54 ++++++- 13 files changed, 498 insertions(+), 62 deletions(-) create mode 100644 keyboards/projectcain/vault35/config.h create mode 100644 keyboards/projectcain/vault35/info.json create mode 100644 keyboards/projectcain/vault35/keymaps/default/config.h create mode 100644 keyboards/projectcain/vault35/keymaps/default/keymap.c create mode 100644 keyboards/projectcain/vault35/keymaps/default/readme.md create mode 100644 keyboards/projectcain/vault35/keymaps/default/rules.mk create mode 100644 keyboards/projectcain/vault35/readme.md create mode 100644 keyboards/projectcain/vault35/rules.mk create mode 100644 keyboards/projectcain/vault35/vault35.c create mode 100644 keyboards/projectcain/vault35/vault35.h diff --git a/keyboards/projectcain/vault35/config.h b/keyboards/projectcain/vault35/config.h new file mode 100644 index 000000000000..5eccd57172aa --- /dev/null +++ b/keyboards/projectcain/vault35/config.h @@ -0,0 +1,149 @@ +/* +Copyright 2021 projectcain +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6060 +#define DEVICE_VER 0x0001 +#define MANUFACTURER projectcain +#define PRODUCT vault35 + +/* key matrix size */ +#define MATRIX_ROWS 4 +#define MATRIX_COLS 11 + +/* + * Keyboard Matrix Assignments + * + * Change this to how you wired your keyboard + * COLS: AVR pins used for columns, left to right + * ROWS: AVR pins used for rows, top to bottom + * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) + * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) + * + */ +#define MATRIX_ROW_PINS { B4, D4, B0, C7 } +#define MATRIX_COL_PINS { B1, D3, F0, F1, F4, F5, F6, F7, C6, B6, B5 } +#define UNUSED_PINS + +/* COL2ROW, ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* + * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN. + */ +#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 + +//#define LED_NUM_LOCK_PIN B0 +//#define LED_CAPS_LOCK_PIN B1 +//#define LED_SCROLL_LOCK_PIN B2 +//#define LED_COMPOSE_PIN B3 +//#define LED_KANA_PIN B4 + +//#define BACKLIGHT_PIN B7 +//#define BACKLIGHT_LEVELS 3 +//#define BACKLIGHT_BREATHING + +//#define RGB_DI_PIN E2 +//#ifdef RGB_DI_PIN +//# define RGBLED_NUM 16 +//# define RGBLIGHT_HUE_STEP 8 +//# define RGBLIGHT_SAT_STEP 8 +//# define RGBLIGHT_VAL_STEP 8 +//# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */ +//# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */ +/*== all animations enable ==*/ +//# define RGBLIGHT_ANIMATIONS +/*== or choose animations ==*/ +//# define RGBLIGHT_EFFECT_BREATHING +//# define RGBLIGHT_EFFECT_RAINBOW_MOOD +//# define RGBLIGHT_EFFECT_RAINBOW_SWIRL +//# define RGBLIGHT_EFFECT_SNAKE +//# define RGBLIGHT_EFFECT_KNIGHT +//# define RGBLIGHT_EFFECT_CHRISTMAS +//# define RGBLIGHT_EFFECT_STATIC_GRADIENT +//# define RGBLIGHT_EFFECT_RGB_TEST +//# define RGBLIGHT_EFFECT_ALTERNATING +/*== customize breathing effect ==*/ +/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/ +//# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64 +/*==== use exp() and sin() ====*/ +//# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7 +//# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255 +//#endif + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is useful for the Windows task manager shortcut (ctrl+shift+esc). + */ +//#define GRAVE_ESC_CTRL_OVERRIDE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT + +/* disable these deprecated features by default */ +#define NO_ACTION_MACRO +#define NO_ACTION_FUNCTION + +/* Bootmagic Lite key configuration */ +//#define BOOTMAGIC_LITE_ROW 0 +//#define BOOTMAGIC_LITE_COLUMN 0 \ No newline at end of file diff --git a/keyboards/projectcain/vault35/info.json b/keyboards/projectcain/vault35/info.json new file mode 100644 index 000000000000..e842e35e41a5 --- /dev/null +++ b/keyboards/projectcain/vault35/info.json @@ -0,0 +1,22 @@ +{ + "keyboard_name": "Vault 35", + "url": "", + "maintainer": "projectcain", + "layouts": { + "LAYOUT_split_4space": { + "layout": [{"label":"Q", "x":0, "y":0}, {"label":"W", "x":1, "y":0}, {"label":"E", "x":2, "y":0}, {"label":"R", "x":3, "y":0}, {"label":"T", "x":4, "y":0}, {"label":"Y", "x":5, "y":0}, {"label":"U", "x":6, "y":0}, {"label":"I", "x":7, "y":0}, {"label":"O", "x":8, "y":0}, {"label":"P", "x":9, "y":0}, {"label":"BACK
SPACE", "x":10, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"S", "x":1.25, "y":1}, {"label":"D", "x":2.25, "y":1}, {"label":"F", "x":3.25, "y":1}, {"label":"G", "x":4.25, "y":1}, {"label":"H", "x":5.25, "y":1}, {"label":"J", "x":6.25, "y":1}, {"label":"K", "x":7.25, "y":1}, {"label":"L", "x":8.25, "y":1}, {"label":"ENTER", "x":9.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"X", "x":1.75, "y":2}, {"label":"C", "x":2.75, "y":2}, {"label":"V", "x":3.75, "y":2}, {"label":"B", "x":4.75, "y":2}, {"label":"N", "x":5.75, "y":2}, {"label":"M", "x":6.75, "y":2}, {"label":"<", "x":7.75, "y":2}, {"label":">", "x":8.75, "y":2}, {"label":"SHIFT", "x":9.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.5, "y":3}, {"label":"LOWER", "x":2.5, "y":3, "w":1.25}, {"x":3.75, "y":3, "w":1.75}, {"x":5.5, "y":3, "w":1.75}, {"label":"RAISE", "x":7.25, "y":3, "w":1.25}, {"label":"ALT", "x":8.5, "y":3}] + }, + + "LAYOUT_split_3space": { + "layout": [{"label":"Q", "x":0, "y":0}, {"label":"W", "x":1, "y":0}, {"label":"E", "x":2, "y":0}, {"label":"R", "x":3, "y":0}, {"label":"T", "x":4, "y":0}, {"label":"Y", "x":5, "y":0}, {"label":"U", "x":6, "y":0}, {"label":"I", "x":7, "y":0}, {"label":"O", "x":8, "y":0}, {"label":"P", "x":9, "y":0}, {"label":"BACK
SPACE", "x":10, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"S", "x":1.25, "y":1}, {"label":"D", "x":2.25, "y":1}, {"label":"F", "x":3.25, "y":1}, {"label":"G", "x":4.25, "y":1}, {"label":"H", "x":5.25, "y":1}, {"label":"J", "x":6.25, "y":1}, {"label":"K", "x":7.25, "y":1}, {"label":"L", "x":8.25, "y":1}, {"label":"ENTER", "x":9.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"X", "x":1.75, "y":2}, {"label":"C", "x":2.75, "y":2}, {"label":"V", "x":3.75, "y":2}, {"label":"B", "x":4.75, "y":2}, {"label":"N", "x":5.75, "y":2}, {"label":"M", "x":6.75, "y":2}, {"label":"<", "x":7.75, "y":2}, {"label":">", "x":8.75, "y":2}, {"label":"SHIFT", "x":9.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.5, "y":3}, {"x":2.5, "y":3, "w":2.25}, {"label":"FN", "x":4.75, "y":3}, {"x":5.75, "y":3, "w":2.75}, {"label":"ALT", "x":8.5, "y":3}] + }, + + "LAYOUT_split_2space": { + "layout": [{"label":"Q", "x":0, "y":0}, {"label":"W", "x":1, "y":0}, {"label":"E", "x":2, "y":0}, {"label":"R", "x":3, "y":0}, {"label":"T", "x":4, "y":0}, {"label":"Y", "x":5, "y":0}, {"label":"U", "x":6, "y":0}, {"label":"I", "x":7, "y":0}, {"label":"O", "x":8, "y":0}, {"label":"P", "x":9, "y":0}, {"label":"BACK
SPACE", "x":10, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"S", "x":1.25, "y":1}, {"label":"D", "x":2.25, "y":1}, {"label":"F", "x":3.25, "y":1}, {"label":"G", "x":4.25, "y":1}, {"label":"H", "x":5.25, "y":1}, {"label":"J", "x":6.25, "y":1}, {"label":"K", "x":7.25, "y":1}, {"label":"L", "x":8.25, "y":1}, {"label":"ENTER", "x":9.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"X", "x":1.75, "y":2}, {"label":"C", "x":2.75, "y":2}, {"label":"V", "x":3.75, "y":2}, {"label":"B", "x":4.75, "y":2}, {"label":"N", "x":5.75, "y":2}, {"label":"M", "x":6.75, "y":2}, {"label":"<", "x":7.75, "y":2}, {"label":">", "x":8.75, "y":2}, {"label":"SHIFT", "x":9.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.5, "y":3}, {"x":2.5, "y":3, "w":3}, {"x":5.5, "y":3, "w":3}, {"label":"ALT", "x":8.5, "y":3}] + }, + + "LAYOUT_full_space": { + "layout": [{"label":"Q", "x":0, "y":0}, {"label":"W", "x":1, "y":0}, {"label":"E", "x":2, "y":0}, {"label":"R", "x":3, "y":0}, {"label":"T", "x":4, "y":0}, {"label":"Y", "x":5, "y":0}, {"label":"U", "x":6, "y":0}, {"label":"I", "x":7, "y":0}, {"label":"O", "x":8, "y":0}, {"label":"P", "x":9, "y":0}, {"label":"BACK
SPACE", "x":10, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"S", "x":1.25, "y":1}, {"label":"D", "x":2.25, "y":1}, {"label":"F", "x":3.25, "y":1}, {"label":"G", "x":4.25, "y":1}, {"label":"H", "x":5.25, "y":1}, {"label":"J", "x":6.25, "y":1}, {"label":"K", "x":7.25, "y":1}, {"label":"L", "x":8.25, "y":1}, {"label":"ENTER", "x":9.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"X", "x":1.75, "y":2}, {"label":"C", "x":2.75, "y":2}, {"label":"V", "x":3.75, "y":2}, {"label":"B", "x":4.75, "y":2}, {"label":"N", "x":5.75, "y":2}, {"label":"M", "x":6.75, "y":2}, {"label":"<", "x":7.75, "y":2}, {"label":">", "x":8.75, "y":2}, {"label":"SHIFT", "x":9.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.5, "y":3}, {"x":2.5, "y":3, "w":6}, {"label":"ALT", "x":8.5, "y":3}] + } + } +} diff --git a/keyboards/projectcain/vault35/keymaps/default/config.h b/keyboards/projectcain/vault35/keymaps/default/config.h new file mode 100644 index 000000000000..6d8aa3d81a12 --- /dev/null +++ b/keyboards/projectcain/vault35/keymaps/default/config.h @@ -0,0 +1,24 @@ +/* Copyright 2021 projectcain + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define ENCODERS_PAD_A { D6 } +#define ENCODERS_PAD_B { D7 } +#define ENCODER_RESOLUTION 2 +#define COMBO_COUNT 2 +#define COMBO_TERM 50 +#define TAPPING_FORCE_HOLD diff --git a/keyboards/projectcain/vault35/keymaps/default/keymap.c b/keyboards/projectcain/vault35/keymaps/default/keymap.c new file mode 100644 index 000000000000..454e2a07ed50 --- /dev/null +++ b/keyboards/projectcain/vault35/keymaps/default/keymap.c @@ -0,0 +1,66 @@ + + /* Copyright 2021 projectcain + * + * 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 . + */ + +#include QMK_KEYBOARD_H +enum layers{ + BASE, + NUM, + SYM, + META +}; + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [BASE] = LAYOUT_split_4space( + + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_QUOTE, + KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, + LALT(KC_TAB), MO(1), SFT_T(KC_BSPC), KC_SPACE, MO(2), RESET + ), + + [NUM] = LAYOUT_split_4space( + + KC_PGUP, KC_HOME, KC_UP, KC_END, KC_WBAK, KC_PSLS, KC_7, KC_8, KC_9, KC_PMNS, KC_DEL, + KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_WFWD, KC_PAST, KC_4, KC_5, KC_6, KC_PPLS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_1, KC_2, KC_3, KC_PDOT, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RALT(KC_F4), RALT(KC_F4) + ), + + [SYM] = LAYOUT_split_4space( + + S(KC_GRV), KC_GRV, KC_BSLS, S(KC_BSLS), KC_TRNS, KC_TRNS, S(KC_MINS), KC_EQL, KC_TRNS, C(KC_W), C(KC_T), + S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), KC_SCLN, S(KC_SCLN), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NUMLOCK, KC_TRNS + ), + +}; + + +enum combos { + KL_SLSH, + JK_MINUS +}; + +const uint16_t PROGMEM kl_combo[] = {KC_K, KC_L, COMBO_END}; +const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [KL_SLSH] = COMBO(kl_combo, S(KC_SLSH)), + [JK_MINUS] = COMBO(jk_combo, KC_MINUS) +}; diff --git a/keyboards/projectcain/vault35/keymaps/default/readme.md b/keyboards/projectcain/vault35/keymaps/default/readme.md new file mode 100644 index 000000000000..608072276767 --- /dev/null +++ b/keyboards/projectcain/vault35/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for vault35 diff --git a/keyboards/projectcain/vault35/keymaps/default/rules.mk b/keyboards/projectcain/vault35/keymaps/default/rules.mk new file mode 100644 index 000000000000..dca6713d4fa6 --- /dev/null +++ b/keyboards/projectcain/vault35/keymaps/default/rules.mk @@ -0,0 +1,2 @@ +ENCODER_ENABLE = yes +COMBO_ENABLE = yes \ No newline at end of file diff --git a/keyboards/projectcain/vault35/readme.md b/keyboards/projectcain/vault35/readme.md new file mode 100644 index 000000000000..88d3ebc73ebf --- /dev/null +++ b/keyboards/projectcain/vault35/readme.md @@ -0,0 +1,21 @@ +# vault35 + +![vault35](https://i.imgur.com/yw3Fvjxh.jpg) + +This is a 30% HHKB-style variant of the vault45 with several bottom row options and rotary encoder support. + +* Keyboard Maintainer: [projectcain](https://github.com/projectcain) +* Hardware Supported: Vault 35 PCB +* Hardware Availability: mechvault.net + +To reset the keyboard into bootloader mode, short the two pads labeled "Reset" on the left side of the pcb + +Make example for this keyboard (after setting up your build environment): + + make projectcain/vault35:default + +Flashing example for this keyboard: + + make projectcain/vault35:default:flash + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/projectcain/vault35/rules.mk b/keyboards/projectcain/vault35/rules.mk new file mode 100644 index 000000000000..9906266f4822 --- /dev/null +++ b/keyboards/projectcain/vault35/rules.mk @@ -0,0 +1,21 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output diff --git a/keyboards/projectcain/vault35/vault35.c b/keyboards/projectcain/vault35/vault35.c new file mode 100644 index 000000000000..9a83d47ad119 --- /dev/null +++ b/keyboards/projectcain/vault35/vault35.c @@ -0,0 +1,29 @@ +/* Copyright 2021 projectcain + * + * 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 . + */ + +#include "vault35.h" + +bool encoder_update_kb(uint8_t index, bool clockwise) { + if (!encoder_update_user(index, clockwise)) { return false; } + if (index == 0) { /* First encoder */ + if (clockwise) { + tap_code(KC_PGDN); + } else { + tap_code(KC_PGUP); + } + } + return true; +} \ No newline at end of file diff --git a/keyboards/projectcain/vault35/vault35.h b/keyboards/projectcain/vault35/vault35.h new file mode 100644 index 000000000000..af5577f3142e --- /dev/null +++ b/keyboards/projectcain/vault35/vault35.h @@ -0,0 +1,80 @@ +/* Copyright 2021 projectcain + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + +/* This is a shortcut to help you visually see your layout. + * + * The first section contains all of the arguments representing the physical + * layout of the board and position of the keys. + * + * The second converts the arguments into a two-dimensional array which + * represents the switch matrix. + */ + +#define LAYOUT_split_4space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, \ + K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, \ + K301, K302, K303, K305, K306, K307 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, KC_NO }, \ + { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, KC_NO }, \ + { KC_NO, K301, K302, K303, KC_NO, K305, K306, K307, KC_NO, KC_NO, KC_NO } \ +} + +#define LAYOUT_split_3space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, \ + K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, \ + K301, K303, K304, K305, K307 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, KC_NO }, \ + { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, KC_NO }, \ + { KC_NO, K301, KC_NO, K303, K304, K305, KC_NO, K307, KC_NO, KC_NO, KC_NO } \ +} + +#define LAYOUT_split_2space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, \ + K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, \ + K301, K303, K305, K307 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, KC_NO }, \ + { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, KC_NO }, \ + { KC_NO, K301, KC_NO, K303, KC_NO, K305, KC_NO, K307, KC_NO, KC_NO, KC_NO } \ +} + +#define LAYOUT_full_space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, \ + K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, \ + K301, K304, K307 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, KC_NO }, \ + { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, KC_NO }, \ + { KC_NO, K301, KC_NO, KC_NO, K304, KC_NO, KC_NO, K307, KC_NO, KC_NO, KC_NO } \ +} diff --git a/keyboards/projectcain/vault45/info.json b/keyboards/projectcain/vault45/info.json index c70600019204..de2f299b64d2 100644 --- a/keyboards/projectcain/vault45/info.json +++ b/keyboards/projectcain/vault45/info.json @@ -1,58 +1,29 @@ { - "keyboard_name": "vault 45", - "url": "", - "maintainer": "projectcain", - "layouts": { - "LAYOUT": { - "layout": [ - { "label": "Tab", "x": 0, "y": 0 }, - { "label": "Q", "x": 1, "y": 0 }, - { "label": "W", "x": 2, "y": 0 }, - { "label": "E", "x": 3, "y": 0 }, - { "label": "R", "x": 4, "y": 0 }, - { "label": "T", "x": 5, "y": 0 }, - { "label": "Y", "x": 6, "y": 0 }, - { "label": "U", "x": 7, "y": 0 }, - { "label": "I", "x": 8, "y": 0 }, - { "label": "O", "x": 9, "y": 0 }, - { "label": "P", "x": 10, "y": 0 }, - { "label": "Back
Space", "x": 11, "y": 0 }, - { "x": 12, "y": 0 }, - { "label": "Caps", "x": 0, "y": 1, "w": 1.25 }, - { "label": "A", "x": 1.25, "y": 1 }, - { "label": "S", "x": 2.25, "y": 1 }, - { "label": "D", "x": 3.25, "y": 1 }, - { "label": "F", "x": 4.25, "y": 1 }, - { "label": "G", "x": 5.25, "y": 1 }, - { "label": "H", "x": 6.25, "y": 1 }, - { "label": "J", "x": 7.25, "y": 1 }, - { "label": "K", "x": 8.25, "y": 1 }, - { "label": "L", "x": 9.25, "y": 1 }, - { "label": ":", "x": 10.25, "y": 1 }, - { "label": "Enter", "x": 11.25, "y": 1, "w": 1.75 }, - { "label": "Shift", "x": 0, "y": 2, "w": 1.75 }, - { "label": "Z", "x": 1.75, "y": 2 }, - { "label": "X", "x": 2.75, "y": 2 }, - { "label": "C", "x": 3.75, "y": 2 }, - { "label": "V", "x": 4.75, "y": 2 }, - { "label": "B", "x": 5.75, "y": 2 }, - { "label": "N", "x": 6.75, "y": 2 }, - { "label": "M", "x": 7.75, "y": 2 }, - { "label": "<", "x": 8.75, "y": 2 }, - { "label": ">", "x": 9.75, "y": 2 }, - { "label": "?", "x": 10.75, "y": 2 }, - { "label": "Shift", "x": 11.75, "y": 2, "w": 1.25 }, - { "label": "Hyper", "x": 0, "y": 3, "w": 1.25 }, - { "label": "Super", "x": 1.25, "y": 3 }, - { "label": "Meta", "x": 2.25, "y": 3, "w": 1.25 }, - { "label": "Alt", "x": 3.5, "y": 3, "w": 1.25 }, - { "x": 4.75, "y": 3, "w": 1.75 }, - { "x": 6.5, "y": 3, "w": 1.75 }, - { "label": "Meta", "x": 8.25, "y": 3, "w": 1.25 }, - { "label": "Super", "x": 9.5, "y": 3, "w": 1.25 }, - { "label": "Fn2", "x": 10.75, "y": 3 }, - { "label": "Ctrl", "x": 11.75, "y": 3, "w": 1.25 } - ] + "keyboard_name": "Vault 45", + "url": "", + "maintainer": "projectcain", + "layout_aliases": { + "LAYOUT": "LAYOUT_all" + }, + "layouts": { + "LAYOUT_all": { + "layout": [{"label":"ESC", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"DEL", "x":11, "y":0}, {"label":"BACK
SPACE", "x":12, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"ENTER", "x":11.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"label":"SHIFT", "x":11.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.25, "y":3}, {"label":"ALT", "x":2.25, "y":3, "w":1.25}, {"label":"SYS", "x":3.5, "y":3, "w":1.25}, {"x":4.75, "y":3, "w":1.25}, {"x":6, "y":3}, {"x":7, "y":3, "w":1.25}, {"label":"FN", "x":8.25, "y":3, "w":1.25}, {"label":"ALT", "x":9.5, "y":3, "w":1.25}, {"label":"CTRL", "x":10.75, "y":3}] + }, + + "LAYOUT_split_4space": { + "layout": [{"label":"ESC", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"DEL", "x":11, "y":0}, {"label":"BACK
SPACE", "x":12, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"ENTER", "x":11.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"label":"SHIFT", "x":11.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.25, "y":3}, {"label":"ALT", "x":2.25, "y":3, "w":1.25}, {"label":"SYS", "x":3.5, "y":3, "w":1.25}, {"x":4.75, "y":3, "w":1.75}, {"x":6.5, "y":3, "w":1.75}, {"label":"FN", "x":8.25, "y":3, "w":1.25}, {"label":"ALT", "x":9.5, "y":3, "w":1.25}, {"label":"CTRL", "x":10.75, "y":3}] + }, + + "LAYOUT_split_3space": { + "layout": [{"label":"ESC", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"DEL", "x":11, "y":0}, {"label":"BACK
SPACE", "x":12, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"ENTER", "x":11.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"label":"SHIFT", "x":11.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.25, "y":3}, {"label":"ALT", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":2.25}, {"x":5.75, "y":3}, {"x":6.75, "y":3, "w":2.75}, {"label":"ALT", "x":9.5, "y":3, "w":1.25}, {"label":"CTRL", "x":10.75, "y":3}] + }, + + "LAYOUT_split_2space": { + "layout": [{"label":"ESC", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"DEL", "x":11, "y":0}, {"label":"BACK
SPACE", "x":12, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"ENTER", "x":11.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"label":"SHIFT", "x":11.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.25, "y":3}, {"label":"ALT", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":3}, {"x":6.5, "y":3, "w":3}, {"label":"ALT", "x":9.5, "y":3, "w":1.25}, {"label":"CTRL", "x":10.75, "y":3}] + }, + + "LAYOUT_full_space": { + "layout": [{"label":"ESC", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"DEL", "x":11, "y":0}, {"label":"BACK
SPACE", "x":12, "y":0}, {"label":"TAB", "x":0, "y":1, "w":1.25}, {"label":"A", "x":1.25, "y":1}, {"label":"S", "x":2.25, "y":1}, {"label":"D", "x":3.25, "y":1}, {"label":"F", "x":4.25, "y":1}, {"label":"G", "x":5.25, "y":1}, {"label":"H", "x":6.25, "y":1}, {"label":"J", "x":7.25, "y":1}, {"label":"K", "x":8.25, "y":1}, {"label":"L", "x":9.25, "y":1}, {"label":":", "x":10.25, "y":1}, {"label":"ENTER", "x":11.25, "y":1, "w":1.75}, {"label":"SHIFT", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"label":"SHIFT", "x":11.75, "y":2, "w":1.25}, {"label":"CTRL", "x":1.25, "y":3}, {"label":"ALT", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":6}, {"label":"ALT", "x":9.5, "y":3, "w":1.25}, {"label":"CTRL", "x":10.75, "y":3}] } } } diff --git a/keyboards/projectcain/vault45/keymaps/default/keymap.c b/keyboards/projectcain/vault45/keymaps/default/keymap.c index 9307370200a8..6955320e7783 100644 --- a/keyboards/projectcain/vault45/keymaps/default/keymap.c +++ b/keyboards/projectcain/vault45/keymaps/default/keymap.c @@ -21,25 +21,25 @@ enum layers{ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [BASE] = LAYOUT( + [BASE] = LAYOUT_split_4space( KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, KC_F5, KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_QUOTE, LT(SYM, KC_ENT), RCTL_T(S(KC_9)), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, S(KC_0), - LALT(KC_TAB), LALT(KC_TAB), MO(1), SFT_T(KC_BSPC), KC_SPACE, KC_SPACE, MO(2), KC_LGUI, G(KC_TAB) + LALT(KC_TAB), LALT(KC_TAB), MO(1), SFT_T(KC_BSPC), KC_SPACE, MO(2), KC_LGUI, G(KC_TAB) ), - [NUM] = LAYOUT( + [NUM] = LAYOUT_split_4space( KC_TRNS, KC_PGUP, KC_HOME, KC_UP, KC_END, KC_WBAK, KC_PSLS, KC_7, KC_8, KC_9, KC_PMNS, KC_DEL, RESET, KC_TRNS, KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_WFWD, KC_PAST, KC_4, KC_5, KC_6, KC_PPLS, KC_TRNS, KC_LBRC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_1, KC_2, KC_3, KC_PDOT, KC_RBRC, - KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, S(KC_RCTRL), RALT(KC_F4), RALT(KC_F4) + KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, S(KC_RCTRL), RALT(KC_F4), RALT(KC_F4) ), - [SYM] = LAYOUT( + [SYM] = LAYOUT_split_4space( RGB_TOG, S(KC_GRV), KC_GRV, KC_BSLS, S(KC_BSLS), KC_TRNS, KC_TRNS, S(KC_MINS), KC_EQL, KC_TRNS, C(KC_W), C(KC_T), KC_TRNS, KC_TRNS, S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), KC_SCLN, S(KC_SCLN), KC_TRNS, S(KC_LBRC), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, S(KC_RBRC), - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPSLOCK, KC_NUMLOCK, KC_TRNS + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPSLOCK, KC_NUMLOCK, KC_TRNS ), }; diff --git a/keyboards/projectcain/vault45/vault45.h b/keyboards/projectcain/vault45/vault45.h index 031de0003a41..b1217d6d06a8 100644 --- a/keyboards/projectcain/vault45/vault45.h +++ b/keyboards/projectcain/vault45/vault45.h @@ -26,7 +26,8 @@ * The second converts the arguments into a two-dimensional array which * represents the switch matrix. */ -#define LAYOUT( \ + +#define LAYOUT_all( \ K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, \ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K112, \ K200, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, \ @@ -36,5 +37,54 @@ { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012 }, \ { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, KC_NO, K112 }, \ { K200, KC_NO, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212 }, \ - { KC_NO, K301, K302, KC_NO, K304, K305, K306, K307, K308, KC_NO, K310, K311, KC_NO }, \ + { KC_NO, K301, K302, KC_NO, K304, K305, K306, K307, K308, KC_NO, K310, K311, KC_NO } \ +} + +#define LAYOUT_split_4space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K112, \ + K200, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, \ + K301, K302, K304, K305, K307, K308, K310, K311 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, KC_NO, K112 }, \ + { K200, KC_NO, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212 }, \ + { KC_NO, K301, K302, KC_NO, K304, K305, KC_NO, K307, K308, KC_NO, K310, K311, KC_NO } \ +} +#define LAYOUT_split_3space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K112, \ + K200, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, \ + K301, K302, K305, K306, K307, K310, K311 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, KC_NO, K112 }, \ + { K200, KC_NO, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212 }, \ + { KC_NO, K301, K302, KC_NO, KC_NO, K305, K306, K307, KC_NO, KC_NO, K310, K311, KC_NO } \ +} +#define LAYOUT_split_2space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K112, \ + K200, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, \ + K301, K302, K305, K307, K310, K311 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, KC_NO, K112 }, \ + { K200, KC_NO, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212 }, \ + { KC_NO, K301, K302, KC_NO, KC_NO, K305, KC_NO, K307, KC_NO, KC_NO, K310, K311, KC_NO } \ +} +#define LAYOUT_full_space( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K112, \ + K200, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, \ + K301, K302, K306, K310, K311 \ +) \ +{ \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, KC_NO, K112 }, \ + { K200, KC_NO, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212 }, \ + { KC_NO, K301, K302, KC_NO, KC_NO, KC_NO, K306, KC_NO, KC_NO, KC_NO, K310, K311, KC_NO } \ } From b29f0059360ae760d2c7215b72327a9b8050b0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= <40222273+pjanx@users.noreply.github.com> Date: Wed, 27 Oct 2021 02:56:38 +0200 Subject: [PATCH 0042/1136] [Keymap] Add planck/pjanx and keebio/nyquist/pjanx keymaps (#13115) --- .../keebio/nyquist/keymaps/pjanx/config.h | 31 ++ .../keebio/nyquist/keymaps/pjanx/keymap.c | 113 ++++++ .../keebio/nyquist/keymaps/pjanx/rules.mk | 2 + keyboards/planck/keymaps/pjanx/config.h | 49 +++ keyboards/planck/keymaps/pjanx/keymap.c | 354 ++++++++++++++++++ keyboards/planck/keymaps/pjanx/readme.md | 2 + keyboards/planck/keymaps/pjanx/rules.mk | 2 + 7 files changed, 553 insertions(+) create mode 100644 keyboards/keebio/nyquist/keymaps/pjanx/config.h create mode 100644 keyboards/keebio/nyquist/keymaps/pjanx/keymap.c create mode 100644 keyboards/keebio/nyquist/keymaps/pjanx/rules.mk create mode 100644 keyboards/planck/keymaps/pjanx/config.h create mode 100644 keyboards/planck/keymaps/pjanx/keymap.c create mode 100644 keyboards/planck/keymaps/pjanx/readme.md create mode 100644 keyboards/planck/keymaps/pjanx/rules.mk diff --git a/keyboards/keebio/nyquist/keymaps/pjanx/config.h b/keyboards/keebio/nyquist/keymaps/pjanx/config.h new file mode 100644 index 000000000000..ef1c4a51ab9b --- /dev/null +++ b/keyboards/keebio/nyquist/keymaps/pjanx/config.h @@ -0,0 +1,31 @@ +/* +Copyright 2017 Danny Nguyen + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +// #define USE_I2C + +/* Select hand configuration */ +// #define MASTER_RIGHT +// #define EE_HANDS + +#undef RGBLED_NUM +#define RGBLIGHT_ANIMATIONS +#define RGBLED_NUM 12 +#define RGBLIGHT_HUE_STEP 8 +#define RGBLIGHT_SAT_STEP 8 +#define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/keebio/nyquist/keymaps/pjanx/keymap.c b/keyboards/keebio/nyquist/keymaps/pjanx/keymap.c new file mode 100644 index 000000000000..44a30063b86b --- /dev/null +++ b/keyboards/keebio/nyquist/keymaps/pjanx/keymap.c @@ -0,0 +1,113 @@ +/* Copyright 2015-2017 Jack Humbert + * Copyright 2021 Přemysl Eric Janouch + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +enum planck_layers { + _QWERTY, + _LOWER, + _RAISE, + _ADJUST +}; + +enum planck_keycodes { + UNUSED = SAFE_RANGE +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |LCtrl | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |LShift| Z | X | C | V | B | N | M | , | . | / |RShift| + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | Caps | LGUI | LAlt |Lower | Space |Raise | RAlt | Down | Up |Enter | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = LAYOUT_ortho_4x12( + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_ESC, KC_CAPS, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_SPC, RAISE, KC_RALT, KC_DOWN, KC_UP, KC_ENT +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Ins | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |RCtrl | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | RGUI | | | | | | Left | Vol- | Vol+ | Right| + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = LAYOUT_ortho_4x12( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_INS, + KC_RCTL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_HOME, KC_END, _______, + _______, KC_RGUI, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_VOLD, KC_VOLU, KC_RGHT +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |RCtrl | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | PgDn | PgUp | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | App | | | | | | Left | Vol- | Vol+ | Right| + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = LAYOUT_ortho_4x12( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, + KC_RCTL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGDN, KC_PGUP, _______, + _______, KC_APP, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_VOLD, KC_VOLU, KC_RGHT +), + +/* Adjust (Lower + Raise) + * v------------------------RGB CONTROL--------------------v + * ,-----------------------------------------------------------------------------------. + * | | Reset|Debug | RGB |RGBMOD| HUE+ | HUE- | SAT+ | SAT- |BRGTH+|BRGTH-| Del | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | |MUSmod|Aud on|Audoff|AGnorm|AGswap| | | | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|TermOn|TermOf| | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | M1 | M2 | M3 | | | | | <- | vv | ^^ | -> | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = LAYOUT_ortho_4x12( + _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , + _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, _______, _______, _______, _______, _______, + _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______, + KC_MS_BTN1, KC_MS_BTN2, KC_MS_BTN3, _______, _______, _______, _______, _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_UP, KC_MS_RIGHT +) + +}; + +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} diff --git a/keyboards/keebio/nyquist/keymaps/pjanx/rules.mk b/keyboards/keebio/nyquist/keymaps/pjanx/rules.mk new file mode 100644 index 000000000000..31710b1014b7 --- /dev/null +++ b/keyboards/keebio/nyquist/keymaps/pjanx/rules.mk @@ -0,0 +1,2 @@ +RGBLIGHT_ENABLE = yes +MOUSEKEY_ENABLE = yes diff --git a/keyboards/planck/keymaps/pjanx/config.h b/keyboards/planck/keymaps/pjanx/config.h new file mode 100644 index 000000000000..b38db026e06c --- /dev/null +++ b/keyboards/planck/keymaps/pjanx/config.h @@ -0,0 +1,49 @@ +/* Copyright 2015-2018 Jack Humbert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#ifdef AUDIO_ENABLE + #define STARTUP_SONG SONG(PLANCK_SOUND) + // #define STARTUP_SONG SONG(NO_SOUND) + + #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ + SONG(COLEMAK_SOUND), \ + SONG(DVORAK_SOUND) \ + } +#endif + +/* + * MIDI options + */ + +/* enable basic MIDI features: + - MIDI notes can be sent when in Music mode is on +*/ + +#define MIDI_BASIC + +/* enable advanced MIDI features: + - MIDI notes can be added to the keymap + - Octave shift and transpose + - Virtual sustain, portamento, and modulation wheel + - etc. +*/ +//#define MIDI_ADVANCED + +// Most tactile encoders have detents every 4 stages +#define ENCODER_RESOLUTION 4 + diff --git a/keyboards/planck/keymaps/pjanx/keymap.c b/keyboards/planck/keymaps/pjanx/keymap.c new file mode 100644 index 000000000000..cf2e52623d26 --- /dev/null +++ b/keyboards/planck/keymaps/pjanx/keymap.c @@ -0,0 +1,354 @@ +/* Copyright 2015-2017 Jack Humbert + * Copyright 2021 Přemysl Eric Janouch + * + * 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 . + */ + +#include QMK_KEYBOARD_H +#include "muse.h" + + +enum planck_layers { + _QWERTY, + _COLEMAK, + _DVORAK, + _LOWER, + _RAISE, + _PLOVER, + _ADJUST +}; + +enum planck_keycodes { + QWERTY = SAFE_RANGE, + COLEMAK, + DVORAK, + PLOVER, + BACKLIT, + EXT_PLV +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* Qwerty + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |LCtrl | A | S | D | F | G | H | J | K | L | ; | " | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |LShift| Z | X | C | V | B | N | M | , | . | / |RShift| + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | Caps | LGUI | LAlt |Lower | Space |Raise | RAlt | Down | Up |Enter | + * `-----------------------------------------------------------------------------------' + */ +[_QWERTY] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_ESC, KC_CAPS, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_SPC, RAISE, KC_RALT, KC_DOWN, KC_UP, KC_ENT +), + +/* Colemak + * ,-----------------------------------------------------------------------------------. + * | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | A | R | S | T | D | H | N | E | I | O | " | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Shift| Z | X | C | V | B | K | M | , | . | / |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_COLEMAK] = LAYOUT_planck_grid( + KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, + KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Dvorak + * ,-----------------------------------------------------------------------------------. + * | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Esc | A | O | E | U | I | D | H | T | N | S | / | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right | + * `-----------------------------------------------------------------------------------' + */ +[_DVORAK] = LAYOUT_planck_grid( + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, + KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , + BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT +), + +/* Lower + * ,-----------------------------------------------------------------------------------. + * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Ins | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |RCtrl | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | Home | End | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | RGUI | | | | | | Left | Vol- | Vol+ | Right| + * `-----------------------------------------------------------------------------------' + */ +[_LOWER] = LAYOUT_planck_grid( + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_INS, + KC_RCTL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_HOME, KC_END, _______, + _______, KC_RGUI, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_VOLD, KC_VOLU, KC_RGHT +), + +/* Raise + * ,-----------------------------------------------------------------------------------. + * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * |RCtrl | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | PgDn | PgUp | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | App | | | | | | Left | Vol- | Vol+ | Right| + * `-----------------------------------------------------------------------------------' + */ +[_RAISE] = LAYOUT_planck_grid( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, + KC_RCTL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGDN, KC_PGUP, _______, + _______, KC_APP, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_VOLD, KC_VOLU, KC_RGHT +), + +/* Plover layer (http://opensteno.org) + * ,-----------------------------------------------------------------------------------. + * | # | # | # | # | # | # | # | # | # | # | # | # | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | S | T | P | H | * | * | F | P | L | T | D | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | S | K | W | R | * | * | R | B | G | S | Z | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | Exit | | | A | O | | E | U | | | | + * `-----------------------------------------------------------------------------------' + */ +[_PLOVER] = LAYOUT_planck_grid( + KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 , + XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, + XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX +), + +/* Adjust (Lower + Raise) + * v------------------------RGB CONTROL--------------------v + * ,-----------------------------------------------------------------------------------. + * | | Reset|Debug | RGB |RGBMOD| HUE+ | HUE- | SAT+ | SAT- |BRGTH+|BRGTH-| Del | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | | |MUSmod|Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|TermOn|TermOf| | | | + * |------+------+------+------+------+------+------+------+------+------+------+------| + * | M1 | M2 | M3 | | | | | <- | vv | ^^ | -> | + * `-----------------------------------------------------------------------------------' + */ +[_ADJUST] = LAYOUT_planck_grid( + _______, RESET, DEBUG, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_DEL , + _______, _______, MU_MOD, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______, + _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, TERM_ON, TERM_OFF, _______, _______, _______, + KC_MS_BTN1, KC_MS_BTN2, KC_MS_BTN3, _______, _______, _______, _______, _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_UP, KC_MS_RIGHT +) + +}; + +#ifdef AUDIO_ENABLE + float plover_song[][2] = SONG(PLOVER_SOUND); + float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND); +#endif + +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case QWERTY: + if (record->event.pressed) { + print("mode just switched to qwerty and this is a huge string\n"); + set_single_persistent_default_layer(_QWERTY); + } + return false; + break; + case COLEMAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_COLEMAK); + } + return false; + break; + case DVORAK: + if (record->event.pressed) { + set_single_persistent_default_layer(_DVORAK); + } + return false; + break; + case BACKLIT: + if (record->event.pressed) { + register_code(KC_RSFT); + #ifdef BACKLIGHT_ENABLE + backlight_step(); + #endif + #ifdef KEYBOARD_planck_rev5 + writePinLow(E6); + #endif + } else { + unregister_code(KC_RSFT); + #ifdef KEYBOARD_planck_rev5 + writePinHigh(E6); + #endif + } + return false; + break; + case PLOVER: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + stop_all_notes(); + PLAY_SONG(plover_song); + #endif + layer_off(_RAISE); + layer_off(_LOWER); + layer_off(_ADJUST); + layer_on(_PLOVER); + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + keymap_config.raw = eeconfig_read_keymap(); + keymap_config.nkro = 1; + eeconfig_update_keymap(keymap_config.raw); + } + return false; + break; + case EXT_PLV: + if (record->event.pressed) { + #ifdef AUDIO_ENABLE + PLAY_SONG(plover_gb_song); + #endif + layer_off(_PLOVER); + } + return false; + break; + } + return true; +} + +bool muse_mode = false; +uint8_t last_muse_note = 0; +uint16_t muse_counter = 0; +uint8_t muse_offset = 70; +uint16_t muse_tempo = 50; + +bool encoder_update(bool clockwise) { + if (muse_mode) { + if (IS_LAYER_ON(_RAISE)) { + if (clockwise) { + muse_offset++; + } else { + muse_offset--; + } + } else { + if (clockwise) { + muse_tempo+=1; + } else { + muse_tempo-=1; + } + } + } else { + if (clockwise) { + #ifdef MOUSEKEY_ENABLE + tap_code(KC_MS_WH_DOWN); + #else + tap_code(KC_PGDN); + #endif + } else { + #ifdef MOUSEKEY_ENABLE + tap_code(KC_MS_WH_UP); + #else + tap_code(KC_PGUP); + #endif + } + } + return true; +} + +bool dip_switch_update_user(uint8_t index, bool active) { + switch (index) { + case 0: { +#ifdef AUDIO_ENABLE + static bool play_sound = false; +#endif + if (active) { +#ifdef AUDIO_ENABLE + if (play_sound) { PLAY_SONG(plover_song); } +#endif + layer_on(_ADJUST); + } else { +#ifdef AUDIO_ENABLE + if (play_sound) { PLAY_SONG(plover_gb_song); } +#endif + layer_off(_ADJUST); + } +#ifdef AUDIO_ENABLE + play_sound = true; +#endif + break; + } + case 1: + if (active) { + muse_mode = true; + } else { + muse_mode = false; + } + } + return true; +} + +void matrix_scan_user(void) { +#ifdef AUDIO_ENABLE + if (muse_mode) { + if (muse_counter == 0) { + uint8_t muse_note = muse_offset + SCALE[muse_clock_pulse()]; + if (muse_note != last_muse_note) { + stop_note(compute_freq_for_midi_note(last_muse_note)); + play_note(compute_freq_for_midi_note(muse_note), 0xF); + last_muse_note = muse_note; + } + } + muse_counter = (muse_counter + 1) % muse_tempo; + } else { + if (muse_counter) { + stop_all_notes(); + muse_counter = 0; + } + } +#endif +} + +bool music_mask_user(uint16_t keycode) { + switch (keycode) { + case RAISE: + case LOWER: + return false; + default: + return true; + } +} diff --git a/keyboards/planck/keymaps/pjanx/readme.md b/keyboards/planck/keymaps/pjanx/readme.md new file mode 100644 index 000000000000..e53397847d6a --- /dev/null +++ b/keyboards/planck/keymaps/pjanx/readme.md @@ -0,0 +1,2 @@ +# Modified Default Planck Layout + diff --git a/keyboards/planck/keymaps/pjanx/rules.mk b/keyboards/planck/keymaps/pjanx/rules.mk new file mode 100644 index 000000000000..3a551bd429bc --- /dev/null +++ b/keyboards/planck/keymaps/pjanx/rules.mk @@ -0,0 +1,2 @@ +SRC += muse.c +MOUSEKEY_ENABLE = yes From ee23aae87fac7b5dca24c1f150465bae1c66cb6c Mon Sep 17 00:00:00 2001 From: Chad Austin Date: Tue, 26 Oct 2021 20:01:57 -0700 Subject: [PATCH 0043/1136] Optimize matrix scanning by removing variable shifts (#14947) --- docs/custom_quantum_functions.md | 2 +- quantum/matrix.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md index 463366ff7632..798c346e67a1 100644 --- a/docs/custom_quantum_functions.md +++ b/docs/custom_quantum_functions.md @@ -149,7 +149,7 @@ This is useful for setting up stuff that you may need elsewhere, but isn't hardw * GPIO pin initialisation: `void matrix_init_pins(void)` * This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override. * `COL2ROW`-based row reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` -* `ROW2COL`-based column reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)` +* `ROW2COL`-based column reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter)` * `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` * These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override. diff --git a/quantum/matrix.c b/quantum/matrix.c index 4fbcc2419cc6..483d518eccf9 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -69,7 +69,7 @@ uint8_t thisHand, thatHand; // user-defined overridable functions __attribute__((weak)) void matrix_init_pins(void); __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); +__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter); #ifdef SPLIT_KEYBOARD __attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); } __attribute__((weak)) void matrix_slave_scan_user(void) {} @@ -113,10 +113,11 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[] // Start with a clear matrix row matrix_row_t current_row_value = 0; - for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { + matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; + for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) { pin_t pin = direct_pins[current_row][col_index]; if (pin != NO_PIN) { - current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index); + current_row_value |= readPin(pin) ? 0 : row_shifter; } } @@ -169,11 +170,12 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[] matrix_output_select_delay(); // For each col... - for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { + matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; + for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) { uint8_t pin_state = readMatrixPin(col_pins[col_index]); // Populate the matrix row with the state of the col pin - current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); + current_row_value |= pin_state ? 0 : row_shifter; } // Unselect row @@ -217,7 +219,7 @@ __attribute__((weak)) void matrix_init_pins(void) { } } -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { +__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter) { bool key_pressed = false; // Select col @@ -231,11 +233,11 @@ __attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[] // Check row pin state if (readMatrixPin(row_pins[row_index]) == 0) { // Pin LO, set col bit - current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); + current_matrix[row_index] |= row_shifter; key_pressed = true; } else { // Pin HI, clear col bit - current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); + current_matrix[row_index] &= ~row_shifter; } } @@ -347,8 +349,9 @@ uint8_t matrix_scan(void) { } #elif (DIODE_DIRECTION == ROW2COL) // Set col, read rows - for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { - matrix_read_rows_on_col(curr_matrix, current_col); + matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; + for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++, row_shifter <<= 1) { + matrix_read_rows_on_col(curr_matrix, current_col, row_shifter); } #endif From 2ac9b31ed1ee45e82ce0ac87680b82e510d481fa Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Wed, 27 Oct 2021 07:47:42 -0700 Subject: [PATCH 0044/1136] Fix white spacing issues in kb files (#14963) --- .../checkerboards/phoenix45_ortho/info.json | 30 ++-- .../vault35/keymaps/default/config.h | 48 +++---- .../vault35/keymaps/default/keymap.c | 132 +++++++++--------- keyboards/projectcain/vault35/vault35.c | 56 ++++---- 4 files changed, 133 insertions(+), 133 deletions(-) diff --git a/keyboards/checkerboards/phoenix45_ortho/info.json b/keyboards/checkerboards/phoenix45_ortho/info.json index f5c02caeff90..e64e67abbf63 100644 --- a/keyboards/checkerboards/phoenix45_ortho/info.json +++ b/keyboards/checkerboards/phoenix45_ortho/info.json @@ -1,16 +1,16 @@ -{ - "keyboard_name": "Phoenix45_Ortho", - "url": "www.checkerboards.xyz", - "maintainer": "nasp", - "layouts": { - "LAYOUT_ortho_2x225u": { - "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.5}, {"x":3.75, "y":3, "w":2.25}, {"label":"Fn", "x":6, "y":3}, {"x":7, "y":3, "w":2.25}, {"label":"Meta", "x":9.25, "y":3, "w":1.5}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] - }, - "LAYOUT_ortho_2x3u": { - "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":3}, {"x":6.5, "y":3, "w":3}, {"label":"Meta", "x":9.5, "y":3, "w":1.25}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] - }, -"LAYOUT_ortho_6u": { - "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.25}, {"label":"", "x":3.5, "y":3, "w":6}, {"label":"Meta", "x":9.5, "y":3, "w":1.25}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] - } - } +{ + "keyboard_name": "Phoenix45_Ortho", + "url": "www.checkerboards.xyz", + "maintainer": "nasp", + "layouts": { + "LAYOUT_ortho_2x225u": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.5}, {"x":3.75, "y":3, "w":2.25}, {"label":"Fn", "x":6, "y":3}, {"x":7, "y":3, "w":2.25}, {"label":"Meta", "x":9.25, "y":3, "w":1.5}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] + }, + "LAYOUT_ortho_2x3u": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.25}, {"x":3.5, "y":3, "w":3}, {"x":6.5, "y":3, "w":3}, {"label":"Meta", "x":9.5, "y":3, "w":1.25}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] + }, +"LAYOUT_ortho_6u": { + "layout": [{"label":"Tab", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"x":11, "y":0}, {"label":"Back Space", "x":12, "y":0}, {"label":"Esc", "x":0, "y":1}, {"label":"A", "x":1, "y":1}, {"label":"S", "x":2, "y":1}, {"label":"D", "x":3, "y":1}, {"label":"F", "x":4, "y":1}, {"label":"G", "x":5, "y":1}, {"label":"H", "x":6, "y":1}, {"label":"J", "x":7, "y":1}, {"label":"K", "x":8, "y":1}, {"label":"L", "x":9, "y":1}, {"label":";", "x":10, "y":1}, {"x":11, "y":1}, {"label":"'", "x":12, "y":1}, {"label":"Shift", "x":0, "y":2}, {"label":"Z", "x":1, "y":2}, {"label":"X", "x":2, "y":2}, {"label":"C", "x":3, "y":2}, {"label":"V", "x":4, "y":2}, {"label":"B", "x":5, "y":2}, {"label":"N", "x":6, "y":2}, {"label":"M", "x":7, "y":2}, {"label":",", "x":8, "y":2}, {"label":".", "x":9, "y":2}, {"label":"/", "x":10, "y":2}, {"x":11, "y":2}, {"label":"Return", "x":12, "y":2}, {"label":"Hyper", "x":0, "y":3, "w":1.25}, {"label":"Super", "x":1.25, "y":3}, {"label":"Meta", "x":2.25, "y":3, "w":1.25}, {"label":"", "x":3.5, "y":3, "w":6}, {"label":"Meta", "x":9.5, "y":3, "w":1.25}, {"label":"Super", "x":10.75, "y":3}, {"label":"Hyper", "x":11.75, "y":3, "w":1.25}] + } + } } \ No newline at end of file diff --git a/keyboards/projectcain/vault35/keymaps/default/config.h b/keyboards/projectcain/vault35/keymaps/default/config.h index 6d8aa3d81a12..35f670c86b42 100644 --- a/keyboards/projectcain/vault35/keymaps/default/config.h +++ b/keyboards/projectcain/vault35/keymaps/default/config.h @@ -1,24 +1,24 @@ -/* Copyright 2021 projectcain - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#define ENCODERS_PAD_A { D6 } -#define ENCODERS_PAD_B { D7 } -#define ENCODER_RESOLUTION 2 -#define COMBO_COUNT 2 -#define COMBO_TERM 50 -#define TAPPING_FORCE_HOLD +/* Copyright 2021 projectcain + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#define ENCODERS_PAD_A { D6 } +#define ENCODERS_PAD_B { D7 } +#define ENCODER_RESOLUTION 2 +#define COMBO_COUNT 2 +#define COMBO_TERM 50 +#define TAPPING_FORCE_HOLD diff --git a/keyboards/projectcain/vault35/keymaps/default/keymap.c b/keyboards/projectcain/vault35/keymaps/default/keymap.c index 454e2a07ed50..05fb05b76082 100644 --- a/keyboards/projectcain/vault35/keymaps/default/keymap.c +++ b/keyboards/projectcain/vault35/keymaps/default/keymap.c @@ -1,66 +1,66 @@ - - /* Copyright 2021 projectcain - * - * 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 . - */ - -#include QMK_KEYBOARD_H -enum layers{ - BASE, - NUM, - SYM, - META -}; - - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [BASE] = LAYOUT_split_4space( - - KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, - KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_QUOTE, - KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, - LALT(KC_TAB), MO(1), SFT_T(KC_BSPC), KC_SPACE, MO(2), RESET - ), - - [NUM] = LAYOUT_split_4space( - - KC_PGUP, KC_HOME, KC_UP, KC_END, KC_WBAK, KC_PSLS, KC_7, KC_8, KC_9, KC_PMNS, KC_DEL, - KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_WFWD, KC_PAST, KC_4, KC_5, KC_6, KC_PPLS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_1, KC_2, KC_3, KC_PDOT, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RALT(KC_F4), RALT(KC_F4) - ), - - [SYM] = LAYOUT_split_4space( - - S(KC_GRV), KC_GRV, KC_BSLS, S(KC_BSLS), KC_TRNS, KC_TRNS, S(KC_MINS), KC_EQL, KC_TRNS, C(KC_W), C(KC_T), - S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), KC_SCLN, S(KC_SCLN), - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NUMLOCK, KC_TRNS - ), - -}; - - -enum combos { - KL_SLSH, - JK_MINUS -}; - -const uint16_t PROGMEM kl_combo[] = {KC_K, KC_L, COMBO_END}; -const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; - -combo_t key_combos[COMBO_COUNT] = { - [KL_SLSH] = COMBO(kl_combo, S(KC_SLSH)), - [JK_MINUS] = COMBO(jk_combo, KC_MINUS) -}; + + /* Copyright 2021 projectcain + * + * 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 . + */ + +#include QMK_KEYBOARD_H +enum layers{ + BASE, + NUM, + SYM, + META +}; + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [BASE] = LAYOUT_split_4space( + + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_QUOTE, + KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, + LALT(KC_TAB), MO(1), SFT_T(KC_BSPC), KC_SPACE, MO(2), RESET + ), + + [NUM] = LAYOUT_split_4space( + + KC_PGUP, KC_HOME, KC_UP, KC_END, KC_WBAK, KC_PSLS, KC_7, KC_8, KC_9, KC_PMNS, KC_DEL, + KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, KC_WFWD, KC_PAST, KC_4, KC_5, KC_6, KC_PPLS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_1, KC_2, KC_3, KC_PDOT, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RALT(KC_F4), RALT(KC_F4) + ), + + [SYM] = LAYOUT_split_4space( + + S(KC_GRV), KC_GRV, KC_BSLS, S(KC_BSLS), KC_TRNS, KC_TRNS, S(KC_MINS), KC_EQL, KC_TRNS, C(KC_W), C(KC_T), + S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), S(KC_6), S(KC_7), S(KC_8), KC_SCLN, S(KC_SCLN), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NUMLOCK, KC_TRNS + ), + +}; + + +enum combos { + KL_SLSH, + JK_MINUS +}; + +const uint16_t PROGMEM kl_combo[] = {KC_K, KC_L, COMBO_END}; +const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; + +combo_t key_combos[COMBO_COUNT] = { + [KL_SLSH] = COMBO(kl_combo, S(KC_SLSH)), + [JK_MINUS] = COMBO(jk_combo, KC_MINUS) +}; diff --git a/keyboards/projectcain/vault35/vault35.c b/keyboards/projectcain/vault35/vault35.c index 9a83d47ad119..2bb1675a1f84 100644 --- a/keyboards/projectcain/vault35/vault35.c +++ b/keyboards/projectcain/vault35/vault35.c @@ -1,29 +1,29 @@ -/* Copyright 2021 projectcain - * - * 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 . - */ - -#include "vault35.h" - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!encoder_update_user(index, clockwise)) { return false; } - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_PGDN); - } else { - tap_code(KC_PGUP); - } - } - return true; +/* Copyright 2021 projectcain + * + * 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 . + */ + +#include "vault35.h" + +bool encoder_update_kb(uint8_t index, bool clockwise) { + if (!encoder_update_user(index, clockwise)) { return false; } + if (index == 0) { /* First encoder */ + if (clockwise) { + tap_code(KC_PGDN); + } else { + tap_code(KC_PGUP); + } + } + return true; } \ No newline at end of file From 0b0edf3d81ec0d5494691987f1b1e695fdc35ca5 Mon Sep 17 00:00:00 2001 From: jfescobar18 <81986725+jfescobar18@users.noreply.github.com> Date: Wed, 27 Oct 2021 09:59:58 -0500 Subject: [PATCH 0045/1136] [Keyboard] Docs/folder organization and info json fixed (#14239) Co-authored-by: Ryan --- .../{ => mechanickeys}/undead60m/config.h | 30 +++++++++---------- keyboards/mechanickeys/undead60m/info.json | 16 ++++++++++ .../undead60m/keymaps/default/keymap.c | 2 +- .../undead60m/keymaps/via/keymap.c | 2 +- .../undead60m/keymaps/via/rules.mk | 0 .../{ => mechanickeys}/undead60m/readme.md | 0 .../{ => mechanickeys}/undead60m/rules.mk | 0 .../{ => mechanickeys}/undead60m/undead60m.c | 4 +-- .../{ => mechanickeys}/undead60m/undead60m.h | 2 +- keyboards/undead60m/info.json | 16 ---------- 10 files changed, 36 insertions(+), 36 deletions(-) rename keyboards/{ => mechanickeys}/undead60m/config.h (70%) create mode 100644 keyboards/mechanickeys/undead60m/info.json rename keyboards/{ => mechanickeys}/undead60m/keymaps/default/keymap.c (99%) rename keyboards/{ => mechanickeys}/undead60m/keymaps/via/keymap.c (99%) rename keyboards/{ => mechanickeys}/undead60m/keymaps/via/rules.mk (100%) rename keyboards/{ => mechanickeys}/undead60m/readme.md (100%) rename keyboards/{ => mechanickeys}/undead60m/rules.mk (100%) rename keyboards/{ => mechanickeys}/undead60m/undead60m.c (97%) rename keyboards/{ => mechanickeys}/undead60m/undead60m.h (97%) delete mode 100644 keyboards/undead60m/info.json diff --git a/keyboards/undead60m/config.h b/keyboards/mechanickeys/undead60m/config.h similarity index 70% rename from keyboards/undead60m/config.h rename to keyboards/mechanickeys/undead60m/config.h index a307b5db66f4..e819cf99713e 100644 --- a/keyboards/undead60m/config.h +++ b/keyboards/mechanickeys/undead60m/config.h @@ -1,18 +1,18 @@ -/* -Copyright 2021 Franciso Escobar -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 . -*/ +/* Copyright 2021 jfescobar18 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ #pragma once diff --git a/keyboards/mechanickeys/undead60m/info.json b/keyboards/mechanickeys/undead60m/info.json new file mode 100644 index 000000000000..e1fd210aab7a --- /dev/null +++ b/keyboards/mechanickeys/undead60m/info.json @@ -0,0 +1,16 @@ +{ + "keyboard_name": "Undead-60M", + "url": "", + "maintainer": "qmk", + "layouts": { + "LAYOUT": { + "layout": [ + {"label": "F1", "x": 0, "y": 0}, {"label": "F2", "x": 1, "y": 0}, {"label": "Esc", "x": 2.5, "y": 0}, {"label": "1", "x": 3.5, "y": 0}, {"label": "2", "x": 4.5, "y": 0}, {"label": "3", "x": 5.5, "y": 0}, {"label": "4", "x": 6.5, "y": 0}, {"label": "5", "x": 7.5, "y": 0}, {"label": "6", "x": 8.5, "y": 0}, {"label": "7", "x": 9.5, "y": 0}, {"label": "8", "x": 10.5, "y": 0}, {"label": "9", "x": 11.5, "y": 0}, {"label": "0", "x": 12.5, "y": 0}, {"label": "-", "x": 13.5, "y": 0}, {"label": "=", "x": 14.5, "y": 0}, {"label": "Backspace", "x": 15.5, "y": 0, "w": 2}, + {"label": "F2", "x": 0, "y": 1}, {"label": "F3", "x": 1, "y": 1}, {"label": "Tab", "x": 2.5, "y": 1, "w": 1.5} , {"label": "Q", "x": 4, "y": 1}, {"label": "W", "x": 5, "y": 1}, {"label": "E", "x": 6, "y": 1}, {"label": "R", "x": 7, "y": 1}, {"label": "T", "x": 8, "y": 1}, {"label": "Y", "x": 9, "y": 1}, {"label": "U", "x": 10, "y": 1}, {"label": "I", "x": 11, "y": 1}, {"label": "O", "x": 12, "y": 1}, {"label": "P", "x": 13, "y": 1}, {"label": "[", "x": 14, "y": 1}, {"label": "]", "x": 15, "y": 1}, {"label": "|", "x": 16, "y": 1, "w": 1.5}, + {"label": "F4", "x": 0, "y": 2}, {"label": "F5", "x": 1, "y": 2}, {"label": "Caps", "x": 2.5, "y": 2, "w": 1.75}, {"label": "A", "x": 4.25, "y": 2}, {"label": "S", "x": 5.25, "y": 2}, {"label": "D", "x": 6.25, "y": 2}, {"label": "F", "x": 7.25, "y": 2}, {"label": "G", "x": 8.25, "y": 2}, {"label": "H", "x": 9.25, "y": 2}, {"label": "J", "x": 10.25, "y": 2}, {"label": "K", "x": 11.25, "y": 2}, {"label": "L", "x": 12.25, "y": 2}, {"label": ";", "x": 13.25, "y": 2}, {"label": "'", "x": 14.25, "y": 2}, {"label": "Enter", "x": 15.25, "y": 2, "w": 2.25}, + {"label": "F6", "x": 0, "y": 3}, {"label": "F7", "x": 1, "y": 3}, {"label": "Shift", "x": 2.5, "y": 3, "w": 2.25}, {"label": "Z", "x": 4.5, "y": 3}, {"label": "X", "x": 5.5, "y": 3}, {"label": "C", "x": 6.5, "y": 3}, {"label": "V", "x": 7.5, "y": 3}, {"label": "B", "x": 8.5, "y": 3}, {"label": "N", "x": 9.5, "y": 3}, {"label": "M", "x": 10.5, "y": 3}, {"label": ",", "x": 11.5, "y": 3}, {"label": ".", "x": 12.5, "y": 3}, {"label": "/", "x": 13.5, "y": 3}, {"label": "Shift", "x": 14.5, "y": 3, "w": 2.75}, + {"label": "F1", "x": 0, "y": 4}, {"label": "F2", "x": 1, "y": 4}, {"label": "Ctrl", "x": 2.5, "y": 4, "w": 1.25}, {"label": "OS", "x": 3.75, "y": 4, "w": 1.25}, {"label": "Alt", "x": 5, "y": 4, "w": 1.25}, {"label": "Space", "x": 6.25, "y": 4}, {"label": "Alt", "x": 12.5, "y": 4, "w": 1.25}, {"label": "OS", "x": 13.75, "y": 4, "w": 1.25}, {"label": "Ctrl", "x": 15, "y": 4, "w": 1.25}, {"label": "Fn", "x": 16.25, "y": 4, "w": 1.25} + ] + } + } +} diff --git a/keyboards/undead60m/keymaps/default/keymap.c b/keyboards/mechanickeys/undead60m/keymaps/default/keymap.c similarity index 99% rename from keyboards/undead60m/keymaps/default/keymap.c rename to keyboards/mechanickeys/undead60m/keymaps/default/keymap.c index 7760a671eeef..084049f09bd3 100644 --- a/keyboards/undead60m/keymaps/default/keymap.c +++ b/keyboards/mechanickeys/undead60m/keymaps/default/keymap.c @@ -1,4 +1,4 @@ -/* Copyright 2021 Francisco Escobar +/* Copyright 2021 jfescobar18 * * 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 diff --git a/keyboards/undead60m/keymaps/via/keymap.c b/keyboards/mechanickeys/undead60m/keymaps/via/keymap.c similarity index 99% rename from keyboards/undead60m/keymaps/via/keymap.c rename to keyboards/mechanickeys/undead60m/keymaps/via/keymap.c index 9ab159ab1c80..1bd56eadbf3d 100644 --- a/keyboards/undead60m/keymaps/via/keymap.c +++ b/keyboards/mechanickeys/undead60m/keymaps/via/keymap.c @@ -1,4 +1,4 @@ -/* Copyright 2021 Francisco Escobar +/* Copyright 2021 jfescobar18 * * 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 diff --git a/keyboards/undead60m/keymaps/via/rules.mk b/keyboards/mechanickeys/undead60m/keymaps/via/rules.mk similarity index 100% rename from keyboards/undead60m/keymaps/via/rules.mk rename to keyboards/mechanickeys/undead60m/keymaps/via/rules.mk diff --git a/keyboards/undead60m/readme.md b/keyboards/mechanickeys/undead60m/readme.md similarity index 100% rename from keyboards/undead60m/readme.md rename to keyboards/mechanickeys/undead60m/readme.md diff --git a/keyboards/undead60m/rules.mk b/keyboards/mechanickeys/undead60m/rules.mk similarity index 100% rename from keyboards/undead60m/rules.mk rename to keyboards/mechanickeys/undead60m/rules.mk diff --git a/keyboards/undead60m/undead60m.c b/keyboards/mechanickeys/undead60m/undead60m.c similarity index 97% rename from keyboards/undead60m/undead60m.c rename to keyboards/mechanickeys/undead60m/undead60m.c index 5cedd10e8d24..1bda4b1bd83c 100644 --- a/keyboards/undead60m/undead60m.c +++ b/keyboards/mechanickeys/undead60m/undead60m.c @@ -1,4 +1,4 @@ - /* Copyright 2021 Francisco Escobar +/* Copyright 2021 jfescobar18 * * 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 @@ -12,7 +12,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ +*/ #include "undead60m.h" bool encoder_update_kb(uint8_t index, bool clockwise) { diff --git a/keyboards/undead60m/undead60m.h b/keyboards/mechanickeys/undead60m/undead60m.h similarity index 97% rename from keyboards/undead60m/undead60m.h rename to keyboards/mechanickeys/undead60m/undead60m.h index 2d71e9640f9d..4bc665ffd87e 100644 --- a/keyboards/undead60m/undead60m.h +++ b/keyboards/mechanickeys/undead60m/undead60m.h @@ -1,4 +1,4 @@ -/* Copyright 2021 Francisco Escobar +/* Copyright 2021 jfescobar18 * * 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 diff --git a/keyboards/undead60m/info.json b/keyboards/undead60m/info.json deleted file mode 100644 index 81f5a220afe2..000000000000 --- a/keyboards/undead60m/info.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "keyboard_name": "Undead-60M", - "url": "", - "maintainer": "qmk", - "layouts": { - "LAYOUT": { - "layout": [ - {"label": "F1", "x": 0, "y": 0}, {"label": "F2", "x": 1, "y": 0}, {"label": "Esc", "x": 3.5, "y": 0}, {"label": "1", "x": 4.5, "y": 0}, {"label": "2", "x": 5.5, "y": 0}, {"label": "3", "x": 6.5, "y": 0}, {"label": "4", "x": 7.5, "y": 0}, {"label": "5", "x": 8.5, "y": 0}, {"label": "6", "x": 9.5, "y": 0}, {"label": "7", "x": 10.5, "y": 0}, {"label": "8", "x": 11.5, "y": 0}, {"label": "9", "x": 12.5, "y": 0}, {"label": "0", "x": 13.5, "y": 0}, {"label": "-", "x": 14.5, "y": 0}, {"label": "=", "x": 15.5, "y": 0}, {"label": "Backspace", "x": 16.5, "y": 0}, - {"label": "F2", "x": 0, "y": 1}, {"label": "F3", "x": 1, "y": 1}, {"label": "Tab", "x": 3.5, "y": 1}, {"label": "Q", "x": 5, "y": 1}, {"label": "W", "x": 6, "y": 1}, {"label": "E", "x": 7, "y": 1}, {"label": "R", "x": 8, "y": 1}, {"label": "T", "x": 9, "y": 1}, {"label": "Y", "x": 10, "y": 1}, {"label": "U", "x": 11, "y": 1}, {"label": "I", "x": 12, "y": 1}, {"label": "O", "x": 13, "y": 1}, {"label": "P", "x": 14, "y": 1}, {"label": "[", "x": 15, "y": 1}, {"label": "]", "x": 16, "y": 1}, {"label": "|", "x": 17, "y": 1}, - {"label": "F4", "x": 0, "y": 2}, {"label": "F5", "x": 1, "y": 2}, {"label": "Caps", "x": 3.5, "y": 2}, {"label": "A", "x": 5.25, "y": 2}, {"label": "S", "x": 6.25, "y": 2}, {"label": "D", "x": 7.25, "y": 2}, {"label": "F", "x": 8.25, "y": 2}, {"label": "G", "x": 9.25, "y": 2}, {"label": "H", "x": 10.25, "y": 2}, {"label": "J", "x": 11.25, "y": 2}, {"label": "K", "x": 12.25, "y": 2}, {"label": "L", "x": 13.25, "y": 2}, {"label": ";", "x": 14.25, "y": 2}, {"label": "'", "x": 15.25, "y": 2}, {"label": "Enter", "x": 16.25, "y": 2}, - {"label": "F6", "x": 0, "y": 3}, {"label": "F7", "x": 1, "y": 3}, {"label": "Shift", "x": 3.5, "y": 3}, {"label": "Z", "x": 5.5, "y": 3}, {"label": "X", "x": 6.5, "y": 3}, {"label": "C", "x": 7.5, "y": 3}, {"label": "V", "x": 8.5, "y": 3}, {"label": "B", "x": 9.5, "y": 3}, {"label": "N", "x": 10.5, "y": 3}, {"label": "M", "x": 11.5, "y": 3}, {"label": ",", "x": 12.5, "y": 3}, {"label": ".", "x": 13.5, "y": 3}, {"label": "/", "x": 14.5, "y": 3}, {"label": "Shift", "x": 15.5, "y": 3}, - {"label": "F1", "x": 0, "y": 4}, {"label": "F2", "x": 1, "y": 4}, {"label": "Ctrl", "x": 3.5, "y": 4}, {"label": "OS", "x": 4.75, "y": 4}, {"label": "Alt", "x": 6, "y": 4}, {"label": "Space", "x": 7.25, "y": 4}, {"label": "Alt", "x": 13.5, "y": 4}, {"label": "OS", "x": 14.75, "y": 4}, {"label": "Ctrl", "x": 16, "y": 4}, {"label": "Fn", "x": 17.25, "y": 4} - ] - } - } -} From 77877990ff2728af34508bf98e3f9121346292c6 Mon Sep 17 00:00:00 2001 From: Marc Nause Date: Wed, 27 Oct 2021 17:00:35 +0200 Subject: [PATCH 0046/1136] [Keymap] Add VLC keymap (#14956) Co-authored-by: Drashna Jaelre --- .../anavi/macropad8/keymaps/vlc/keymap.c | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 keyboards/anavi/macropad8/keymaps/vlc/keymap.c diff --git a/keyboards/anavi/macropad8/keymaps/vlc/keymap.c b/keyboards/anavi/macropad8/keymaps/vlc/keymap.c new file mode 100644 index 000000000000..3e15a81861de --- /dev/null +++ b/keyboards/anavi/macropad8/keymaps/vlc/keymap.c @@ -0,0 +1,138 @@ + /* Copyright 2021 Marc Nause + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +enum custom_layers { + _PLAY, + _FRAME, + _DVD, + _FN +}; + +#define KC_X0 LT(_FN, KC_ESC) + +#ifdef RGBLIGHT_ENABLE +// How long (in ms) to wait between animation steps for the rainbow mode +const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {60, 30, 15}; +// How long (in milliseconds) to wait between animation steps for each of the "Swirling rainbow" animations +const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {20, 10, 4}; +#endif + +/* + * The keymap contains 3 layers for vlc hotkeys and a 4th layer + * for controlling the backlighting and the underlighting. + * + * See https://wiki.videolan.org/QtHotkeys/ for VLC hotkeys + * + * - Layer for VLC media play hotkeys: + * Space - Play/pause + * P - Previous track + * S - Stop + * N - Next track + * + - Slower + * - - Faster + * = - Normal rate + * + * - Layer for VLC frame control hotkeys: + * Shift + right arrow - Jump 5 seconds forward + * Alt + right arrow - Jump 10 seconds forward + * Control + right arrow - Jump 1 minute forward + * E - Next frame + * Shift + left arrow - Jump 5 seconds back + * Alt + left arrow - Jump 10 seconds back + * Control + left arrow - Jump 1 minute back + * + * - Layer for VLC DVD hotkeys: + * Shift + M - Disc menu + * Arrow up - Navigate menu (up) + * Enter - Select menu entry + * Shift + V - Toggle subtitles + * Arrow left - Navigate menu (left) + * Arrow down - Navigate menu (down) + * Arrow right - Navigate menu (right) + */ + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [_PLAY] = LAYOUT_ortho_2x4( + KC_SPC, KC_P, KC_S, KC_N, + KC_KP_PLUS, KC_KP_MINUS, KC_KP_EQUAL, TO(_FRAME) + ), + + [_FRAME] = LAYOUT_ortho_2x4( + LSFT(KC_RIGHT), LALT(KC_RIGHT), LCTL(KC_RIGHT), KC_E, + LSFT(KC_LEFT), LALT(KC_LEFT), LCTL(KC_LEFT), TO(_DVD) + ), + + [_DVD] = LAYOUT_ortho_2x4( + LSFT(KC_M), KC_UP, KC_ENTER, LSFT(KC_V), + KC_LEFT, KC_DOWN, KC_RIGHT, TO(_FN) + ), + + [_FN] = LAYOUT_ortho_2x4( + RGB_TOG, RGB_MOD, RGB_M_R, RGB_M_SN, + BL_TOGG, BL_STEP, BL_BRTG, TO(_PLAY) + ) +}; + +#ifdef OLED_ENABLE +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + return OLED_ROTATION_180; // flips the display 180 degrees if offhand +} + +void oled_task_user(void) { + // Host Keyboard Layer Status + oled_write_ln_P(PSTR("ANAVI Macro Pad 8"), false); + oled_write_P(PSTR("Layer: "), false); + + switch (get_highest_layer(layer_state)) { + case _PLAY: + oled_write_ln_P(PSTR("VLC Play"), false); + break; + case _FRAME: + oled_write_ln_P(PSTR("VLC Frame"), false); + break; + case _DVD: + oled_write_ln_P(PSTR("VLC DVD"), false); + break; + case _FN: + oled_write_ln_P(PSTR("FN "), false); + break; + default: + // Or use the write_ln shortcut over adding '\n' to the end of your string + oled_write_ln_P(PSTR("N/A"), false); + } + + // Host Keyboard LED Status + led_t led_state = host_keyboard_led_state(); + oled_write_P(PSTR("Num Lock: "), false); + oled_write_ln_P(led_state.num_lock ? PSTR("On") : PSTR("Off"), false); + oled_write_P(PSTR("Caps Lock: "), false); + oled_write_ln_P(led_state.caps_lock ? PSTR("On") : PSTR("Off"), false); + oled_write_P(PSTR("Scroll Lock: "), false); + oled_write_ln_P(led_state.scroll_lock ? PSTR("On") : PSTR("Off"), false); + oled_write_P(PSTR("Backlit: "), false); + oled_write_ln_P(is_backlight_enabled() ? PSTR("On") : PSTR("Off"), false); +#ifdef RGBLIGHT_ENABLE + static char rgbStatusLine1[26] = {0}; + snprintf(rgbStatusLine1, sizeof(rgbStatusLine1), "RGB Mode: %d", rgblight_get_mode()); + oled_write_ln(rgbStatusLine1, false); + static char rgbStatusLine2[26] = {0}; + snprintf(rgbStatusLine2, sizeof(rgbStatusLine2), "h:%d s:%d v:%d", rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val()); + oled_write_ln(rgbStatusLine2, false); +#endif +} +#endif From db634c21a721e48966d028524a9129afd598ceff Mon Sep 17 00:00:00 2001 From: Jeremy Levy Date: Wed, 27 Oct 2021 08:01:54 -0700 Subject: [PATCH 0047/1136] [Keyboard] update(readme): with PCB reset instructions (#14961) --- keyboards/wuque/ikki68_aurora/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keyboards/wuque/ikki68_aurora/readme.md b/keyboards/wuque/ikki68_aurora/readme.md index 298d7e00ed95..98674d0d728f 100644 --- a/keyboards/wuque/ikki68_aurora/readme.md +++ b/keyboards/wuque/ikki68_aurora/readme.md @@ -19,7 +19,7 @@ Flashing example for this keyboard: To reset the board into bootloader mode, do one of the following: -* Tap the Reset switch mounted on the PCB +* Under the **space1** key short the pins on the PCB as shown [here]( https://media.discordapp.net/attachments/768892137205923850/862663262180999218/image0.jpg?width=2520&height=910) * In the case of the default keymap, use the key combination Fn + PageUp * Hold the Esc key while connecting the USB cable (also erases persistent settings) From 546e6a15dcad55e2b370dddf417d83ae88e87217 Mon Sep 17 00:00:00 2001 From: Albert Y <76888457+filterpaper@users.noreply.github.com> Date: Wed, 27 Oct 2021 23:02:21 +0800 Subject: [PATCH 0048/1136] [Keyboard] Cradio keyboard (#14946) Co-authored-by: Ryan Co-authored-by: filterpaper --- keyboards/cradio/config.h | 83 +++++++++++++++++++++++ keyboards/cradio/cradio.c | 20 ++++++ keyboards/cradio/cradio.h | 50 ++++++++++++++ keyboards/cradio/info.json | 52 ++++++++++++++ keyboards/cradio/keymaps/default/keymap.c | 51 ++++++++++++++ keyboards/cradio/readme.md | 33 +++++++++ keyboards/cradio/rules.mk | 23 +++++++ 7 files changed, 312 insertions(+) create mode 100644 keyboards/cradio/config.h create mode 100644 keyboards/cradio/cradio.c create mode 100644 keyboards/cradio/cradio.h create mode 100644 keyboards/cradio/info.json create mode 100644 keyboards/cradio/keymaps/default/keymap.c create mode 100644 keyboards/cradio/readme.md create mode 100644 keyboards/cradio/rules.mk diff --git a/keyboards/cradio/config.h b/keyboards/cradio/config.h new file mode 100644 index 000000000000..2d76de6a8e3c --- /dev/null +++ b/keyboards/cradio/config.h @@ -0,0 +1,83 @@ +/* Copyright 2018-2021 + * ENDO Katsuhiro + * David Philip Barr <@davidphilipbarr> + * Pierre Chevalier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xC88B +#define PRODUCT_ID 0x3988 +#define DEVICE_VER 0x0001 +#define MANUFACTURER DPB +#define PRODUCT Cradio + +/* key matrix size */ +#define MATRIX_ROWS 8 +#define MATRIX_COLS 5 + +/* + * Keyboard Matrix Assignments + * + * Change this to how you wired your keyboard + * COLS: AVR pins used for columns, left to right + * ROWS: AVR pins used for rows, top to bottom + * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) + * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) + * NO_DIODE = switches are directly connected to AVR pins + * +*/ +#define DIRECT_PINS { \ + { E6, F7, F6, F5, F4 }, \ + { B1, B3, B2, B6, D3 }, \ + { D1, D0, D4, C6, D7 }, \ + { B4, B5, NO_PIN, NO_PIN, NO_PIN } \ +} + +#define DIRECT_PINS_RIGHT { \ + { F4, F5, F6, F7, E6 }, \ + { D3, B6, B2, B3, B1 }, \ + { D7, C6, D4, D0, D1 }, \ + { B5, B4, NO_PIN, NO_PIN, NO_PIN } \ +} + +#define UNUSED_PINS + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* Serial settings */ +#define USE_SERIAL +/* serial.c configuration for split keyboard */ +#define SOFT_SERIAL_PIN D2 + +/* Split handedness */ +#define EE_HANDS + +/* Top left key on left half */ +#define BOOTMAGIC_LITE_ROW 0 +#define BOOTMAGIC_LITE_COLUMN 0 +/* Top right key on right half */ +#define BOOTMAGIC_LITE_ROW_RIGHT 4 +#define BOOTMAGIC_LITE_COLUMN_RIGHT 4 diff --git a/keyboards/cradio/cradio.c b/keyboards/cradio/cradio.c new file mode 100644 index 000000000000..6ef938122355 --- /dev/null +++ b/keyboards/cradio/cradio.c @@ -0,0 +1,20 @@ +/* Copyright 2018-2021 + * ENDO Katsuhiro + * David Philip Barr <@davidphilipbarr> + * Pierre Chevalier + * + * 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 . + */ + +#include "cradio.h" diff --git a/keyboards/cradio/cradio.h b/keyboards/cradio/cradio.h new file mode 100644 index 000000000000..29e81ef9b8da --- /dev/null +++ b/keyboards/cradio/cradio.h @@ -0,0 +1,50 @@ +/* Copyright 2018-2021 + * ENDO Katsuhiro + * David Philip Barr <@davidphilipbarr> + * Pierre Chevalier + * + * 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 . + */ + +#include "quantum.h" + +/* This a shortcut to help you visually see your layout. + * + * The first section contains all of the arguments representing the physical + * layout of the board and position of the keys. + * + * The second converts the arguments into a two-dimensional array which + * represents the switch matrix. + */ + +// readability +#define ___ KC_NO + +#define LAYOUT( \ + L01, L02, L03, L04, L05, R01, R02, R03, R04, R05, \ + L06, L07, L08, L09, L10, R06, R07, R08, R09, R10, \ + L11, L12, L13, L14, L15, R11, R12, R13, R14, R15, \ + L16, L17, R16, R17 \ + ) \ + { \ + { L01, L02, L03, L04, L05 }, \ + { L06, L07, L08, L09, L10 }, \ + { L11, L12, L13, L14, L15 }, \ + { L16, L17, ___, ___, ___ }, \ + { R01, R02, R03, R04, R05 }, \ + { R06, R07, R08, R09, R10 }, \ + { R11, R12, R13, R14, R15 }, \ + { R16, R17, ___, ___, ___ } \ + } + diff --git a/keyboards/cradio/info.json b/keyboards/cradio/info.json new file mode 100644 index 000000000000..77b611f32566 --- /dev/null +++ b/keyboards/cradio/info.json @@ -0,0 +1,52 @@ +{ + "keyboard_name": "Cradio", + "url": "https://github.com/davidphilipbarr/Sweep", + "maintainer": "@davidphilipbarr", + "layouts": { + "LAYOUT": { + "layout": [ + {"x": 0, "y": 0.93}, + {"x": 1, "y": 0.31}, + {"x": 2, "y": 0}, + {"x": 3, "y": 0.28}, + {"x": 4, "y": 0.42}, + + {"x": 7, "y": 0.42}, + {"x": 8, "y": 0.28}, + {"x": 9, "y": 0}, + {"x": 10, "y": 0.31}, + {"x": 11, "y": 0.93}, + + {"x": 0, "y": 1.93}, + {"x": 1, "y": 1.31}, + {"x": 2, "y": 1}, + {"x": 3, "y": 1.28}, + {"x": 4, "y": 1.42}, + + {"x": 7, "y": 1.42}, + {"x": 8, "y": 1.28}, + {"x": 9, "y": 1}, + {"x": 10, "y": 1.31}, + {"x": 11, "y": 1.93}, + + {"x": 0, "y": 2.93}, + {"x": 1, "y": 2.31}, + {"x": 2, "y": 2}, + {"x": 3, "y": 2.28}, + {"x": 4, "y": 2.42}, + + {"x": 7, "y": 2.42}, + {"x": 8, "y": 2.28}, + {"x": 9, "y": 2}, + {"x": 10, "y": 2.31}, + {"x": 11, "y": 2.93}, + + {"x": 3.5, "y": 3.75}, + {"x": 4.5, "y": 4}, + + {"x": 6.5, "y": 4}, + {"x": 7.5, "y": 3.75} + ] + } + } +} diff --git a/keyboards/cradio/keymaps/default/keymap.c b/keyboards/cradio/keymaps/default/keymap.c new file mode 100644 index 000000000000..bb7e2d35e68f --- /dev/null +++ b/keyboards/cradio/keymaps/default/keymap.c @@ -0,0 +1,51 @@ +/* Copyright 2018-2021 + * ENDO Katsuhiro + * David Philip Barr <@davidphilipbarr> + * Pierre Chevalier + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +/* Base layer 0 layout uses home row mods. See the following guide for details: + * https://precondition.github.io/home-row-mods + */ + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + SFT_T(KC_A),ALT_T(KC_S),CTL_T(KC_D),GUI_T(KC_F), KC_G, KC_H, GUI_T(KC_J),CTL_T(KC_K),ALT_T(KC_L),SFT_T(KC_SCLN), + KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, + LT(2,KC_TAB), KC_ENT, KC_SPC, LT(1,KC_BSPC) + ), + [1] = LAYOUT( + _______, KC_1, KC_2, KC_3, KC_VOLU, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DQUO, + _______, KC_4, KC_5, KC_6, KC_VOLD, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_QUOT, + KC_CAPS, KC_7, KC_8, KC_9, KC_0, _______, _______, _______, _______, _______, + MO(3), KC_GESC, _______, _______ + ), + [2] = LAYOUT( + _______, KC_LBRC, KC_LCBR, KC_RCBR, _______, KC_CIRC, KC_LPRN, KC_RPRN, KC_RBRC, KC_TILD, + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_AMPR, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, + _______, _______, _______, _______, _______, KC_ASTR, KC_UNDS, KC_PLUS, KC_PIPE, _______, + _______, _______, KC_DEL, MO(3) + ), + [3] = LAYOUT( + _______, KC_F1, KC_F2, KC_F3, KC_F10, _______, KC_WH_U, KC_WH_D, _______, RESET, + _______, KC_F4, KC_F5, KC_F6, KC_F11, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_INS, + _______, KC_F7, KC_F8, KC_F9, KC_F12, _______, KC_BTN1, KC_BTN2, _______, _______, + _______, _______, _______, _______ + ) +}; diff --git a/keyboards/cradio/readme.md b/keyboards/cradio/readme.md new file mode 100644 index 000000000000..b8520a366bea --- /dev/null +++ b/keyboards/cradio/readme.md @@ -0,0 +1,33 @@ +# Cradio keyboards + +![Cradio](https://github.com/davidphilipbarr/hypergolic/raw/main/hypergarlic/ht.png) + +Cradio are low-profile 34-key split-keyboards designed by [@davidphilipbarr](https://github.com/davidphilipbarr), with no diodes and direct micro-controller pin wiring. + +## Keyboard Info + +* Keyboard Maintainer: [davidphilipbarr](https://github.com/davidphilipbarr) +* Hardware Supported: + * [Sweep](https://github.com/davidphilipbarr/Sweep) + * [Hypergarlic](https://github.com/davidphilipbarr/hypergolic/tree/main/hypergarlic) + * Variants of the same 34-key direct pin PCB +* Hardware Availability: PCBs can be printed with gerber files from the repository + +Make examples for this keyboard (after setting up your build environment): + + make cradio:default + +Firmware uses `EE_HANDS` split handedness by default. Each halve should be flashed once with the following: + + make cradio:default:dfu-split-left + make cradio:default:dfu-split-right + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +## Bootloader + +Enter the bootloader in 3 ways: + +* **Bootmagic reset**: Hold down the top left key on the left half (or the top right right key on the right half) and plug in the controller on that side. +* **Physical reset button**: Briefly press the reset button soldered on the PCB. +* **Keycode in layout**: Press the key mapped to `RESET` if it is configured. diff --git a/keyboards/cradio/rules.mk b/keyboards/cradio/rules.mk new file mode 100644 index 000000000000..437ca573d74b --- /dev/null +++ b/keyboards/cradio/rules.mk @@ -0,0 +1,23 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +UNICODE_ENABLE = yes # Unicode +AUDIO_ENABLE = no # Audio output +SPLIT_KEYBOARD = yes # Use shared split_common code From 9b912416b4334a55d49e84f38d73625f9fa728b1 Mon Sep 17 00:00:00 2001 From: Albert Y <76888457+filterpaper@users.noreply.github.com> Date: Wed, 27 Oct 2021 23:03:00 +0800 Subject: [PATCH 0049/1136] [Docs] Add instructions to create keymap before proceeding (#14945) Co-authored-by: filterpaper --- docs/newbs_getting_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/newbs_getting_started.md b/docs/newbs_getting_started.md index b434a04bbef3..5dbaa56169f4 100644 --- a/docs/newbs_getting_started.md +++ b/docs/newbs_getting_started.md @@ -194,7 +194,7 @@ You can also set your default keymap name. Most people use their GitHub username qmk config user.keymap= -After this you can leave those arguments off and compile your keyboard like this: +The keyboard can now be compiled without arguments using the following command after creating your keymap in the next section: qmk compile From 2e3514f21c718e0f99e12433a96d6916f1a2fb73 Mon Sep 17 00:00:00 2001 From: TW59420 <40019210+TW59420@users.noreply.github.com> Date: Wed, 27 Oct 2021 23:03:51 +0800 Subject: [PATCH 0050/1136] [Keyboard] Add MW65 Series PCB (#14939) --- keyboards/mwstudio/mw65_rgb/config.h | 61 +++++++++ keyboards/mwstudio/mw65_rgb/info.json | 84 ++++++++++++ .../mw65_rgb/keymaps/default/keymap.c | 51 +++++++ .../mwstudio/mw65_rgb/keymaps/via/keymap.c | 128 ++++++++++++++++++ .../mwstudio/mw65_rgb/keymaps/via/rules.mk | 2 + keyboards/mwstudio/mw65_rgb/mw65_rgb.c | 45 ++++++ keyboards/mwstudio/mw65_rgb/mw65_rgb.h | 33 +++++ keyboards/mwstudio/mw65_rgb/readme.md | 22 +++ keyboards/mwstudio/mw65_rgb/rules.mk | 24 ++++ keyboards/mwstudio/readme.md | 2 + 10 files changed, 452 insertions(+) create mode 100644 keyboards/mwstudio/mw65_rgb/config.h create mode 100644 keyboards/mwstudio/mw65_rgb/info.json create mode 100644 keyboards/mwstudio/mw65_rgb/keymaps/default/keymap.c create mode 100644 keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c create mode 100644 keyboards/mwstudio/mw65_rgb/keymaps/via/rules.mk create mode 100644 keyboards/mwstudio/mw65_rgb/mw65_rgb.c create mode 100644 keyboards/mwstudio/mw65_rgb/mw65_rgb.h create mode 100644 keyboards/mwstudio/mw65_rgb/readme.md create mode 100644 keyboards/mwstudio/mw65_rgb/rules.mk diff --git a/keyboards/mwstudio/mw65_rgb/config.h b/keyboards/mwstudio/mw65_rgb/config.h new file mode 100644 index 000000000000..8a320664a9a7 --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/config.h @@ -0,0 +1,61 @@ +/* Copyright 2021 TW59420 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x7BA1 +#define PRODUCT_ID 0x6502 +#define DEVICE_VER 0x0001 +#define MANUFACTURER MWStudio +#define PRODUCT MW65 + +/* key matrix size */ +#define MATRIX_ROWS 6 +#define MATRIX_COLS 15 + +/* key matrix pins */ +#define MATRIX_ROW_PINS { D0, D1, D2, D3, B7, B0 } +#define MATRIX_COL_PINS { C6, B6, B5, B4, D7, D6, D4, C7, F7, F6, F5, F4, F1, F0, E6 } + +#define BOOTMAGIC_LITE_ROW 0 +#define BOOTMAGIC_LITE_COLUMN 0 + +/* COL2ROW or ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +#define RGB_DI_PIN B3 +#ifdef RGB_DI_PIN + #define RGBLIGHT_SLEEP + + #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 + #define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS + #define DRIVER_LED_TOTAL 83 + #define RGBLED_NUM 83 + #define RGB_MATRIX_KEYPRESSES + + #define RGBLIGHT_HUE_STEP 8 + #define RGBLIGHT_SAT_STEP 8 + #define RGBLIGHT_VAL_STEP 8 +#endif + +#define ENCODERS_PAD_A { B1 } +#define ENCODERS_PAD_B { B2 } diff --git a/keyboards/mwstudio/mw65_rgb/info.json b/keyboards/mwstudio/mw65_rgb/info.json new file mode 100644 index 000000000000..affcdadbc0f6 --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/info.json @@ -0,0 +1,84 @@ +{ + "keyboard_name": "MW65_RGB", + "url": "", + "maintainer": "qmk", + "layouts": { + "LAYOUT": { + "layout": [ + {"label":"ESC", "x":0, "y":0}, + {"label":"1", "x":1, "y":0}, + {"label":"2", "x":2, "y":0}, + {"label":"3", "x":3, "y":0}, + {"label":"4", "x":4, "y":0}, + {"label":"5", "x":5, "y":0}, + {"label":"6", "x":6, "y":0}, + {"label":"7", "x":7, "y":0}, + {"label":"8", "x":8, "y":0}, + {"label":"9", "x":9, "y":0}, + {"label":"0", "x":10, "y":0}, + {"label":"-", "x":11, "y":0}, + {"label":"=", "x":12, "y":0}, + {"label":"Backspace", "x":13, "y":0, "w":2}, + {"label":"Delete", "x":15, "y":0}, + + {"label":"Tab", "x":0, "y":1, "w":1.5}, + {"label":"Q", "x":1.5, "y":1}, + {"label":"W", "x":2.5, "y":1}, + {"label":"E", "x":3.5, "y":1}, + {"label":"R", "x":4.5, "y":1}, + {"label":"T", "x":5.5, "y":1}, + {"label":"Y", "x":6.5, "y":1}, + {"label":"U", "x":7.5, "y":1}, + {"label":"I", "x":8.5, "y":1}, + {"label":"O", "x":9.5, "y":1}, + {"label":"P", "x":10.5, "y":1}, + {"label":"[", "x":11.5, "y":1}, + {"label":"]", "x":12.5, "y":1}, + {"label":"\\", "x":13.5, "y":1, "w":1.5}, + {"label":"PgUp", "x":15, "y":1}, + + {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, + {"label":"A", "x":1.75, "y":2}, + {"label":"S", "x":2.75, "y":2}, + {"label":"D", "x":3.75, "y":2}, + {"label":"F", "x":4.75, "y":2}, + {"label":"G", "x":5.75, "y":2}, + {"label":"H", "x":6.75, "y":2}, + {"label":"J", "x":7.75, "y":2}, + {"label":"K", "x":8.75, "y":2}, + {"label":"L", "x":9.75, "y":2}, + {"label":";", "x":10.75, "y":2}, + {"label":"'", "x":11.75, "y":2}, + {"label":"Enter", "x":12.75, "y":2, "w":2.25}, + {"label":"PgDn", "x":15, "y":2}, + + {"label":"Shift", "x":0, "y":3, "w":2.25}, + {"label":"Z", "x":2.25, "y":3}, + {"label":"X", "x":3.25, "y":3}, + {"label":"C", "x":4.25, "y":3}, + {"label":"V", "x":5.25, "y":3}, + {"label":"B", "x":6.25, "y":3}, + {"label":"N", "x":7.25, "y":3}, + {"label":"M", "x":8.25, "y":3}, + {"label":",", "x":9.25, "y":3}, + {"label":".", "x":10.25, "y":3}, + {"label":"/", "x":11.25, "y":3}, + {"label":"Shift", "x":12.25, "y":3, "w":1.75}, + {"label":"\u2191", "x":14, "y":3}, + {"label":"End", "x":15, "y":3}, + + {"label":"Ctrl", "x":0, "y":4, "w":1.25}, + {"label":"Win", "x":1.25, "y":4, "w":1.25}, + {"label":"Alt", "x":2.5, "y":4, "w":1.25}, + {"label":"Vol-", "x":3.75, "y":4 }, + {"label":"Vol+", "x":4.75, "y":4 }, + {"x":5.75, "y":4, "w":4.25}, + {"label":"Alt", "x":10, "y":4, "w":1.25}, + {"label":"Fn", "x":11.25, "y":4, "w":1.25}, + {"label":"\u2190", "x":13, "y":4}, + {"label":"\u2193", "x":14, "y":4}, + {"label":"\u2192", "x":15, "y":4} + ] + } + } +} diff --git a/keyboards/mwstudio/mw65_rgb/keymaps/default/keymap.c b/keyboards/mwstudio/mw65_rgb/keymaps/default/keymap.c new file mode 100644 index 000000000000..9466b0f28367 --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/keymaps/default/keymap.c @@ -0,0 +1,51 @@ +/* Copyright 2021 TW59420 + * + * 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 . + */ + +#include QMK_KEYBOARD_H +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, RGB_TOG, + KC_LCTL, KC_LGUI, KC_LALT, KC_VOLU, KC_VOLD, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT + ), + + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, RGB_HUI, + RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUD, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_VAI, RGB_SAD, + _______, _______, _______, _______, _______, _______, RGB_MOD, _______, RGB_SPD, RGB_VAD, RGB_SPI + ), + + [2] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + + [3] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; diff --git a/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c b/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c new file mode 100644 index 000000000000..6506433998e3 --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/keymaps/via/keymap.c @@ -0,0 +1,128 @@ +/* Copyright 2021 TW59420 + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +typedef union { + uint32_t raw; + struct { + bool top_rgb_change :1; + bool bottom_rgb_change :1; + }; +} user_config_t; + +user_config_t user_config; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [0] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, RGB_TOG, + KC_LCTL, KC_LGUI, KC_LALT, KC_VOLU, KC_VOLD, KC_SPACE, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT + ), + + [1] = LAYOUT( + KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, RGB_HUI, + RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_HUD, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, USER00, RGB_SAI, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, USER01, RGB_VAI, RGB_SAD, + _______, _______, _______, _______, _______, _______, RGB_MOD, _______, RGB_SPD, RGB_VAD, RGB_SPI + ), + + [2] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + + [3] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), +}; + +void keyboard_post_init_user(void) { + // Read the user config from EEPROM + user_config.raw = eeconfig_read_user(); +} + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case USER00: + if (record->event.pressed) { + // Do something when pressed + user_config.top_rgb_change ^= 1; // Toggles the status + eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM + } else { + // Do something else when release + } + return false; // Skip all further processing of this key + case USER01: + if (record->event.pressed) { + // Do something when pressed + user_config.bottom_rgb_change ^= 1; // Toggles the status + eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM + } else { + // Do something else when release + } + return false; // Skip all further processing of this key + default: + return true; // Process all other keycodes normally + } +} + +#ifdef ENCODER_ENABLE +bool encoder_update_user(uint8_t index, bool clockwise) { + if (index == 0) { + if (clockwise) { + tap_code(dynamic_keymap_get_keycode(biton32(layer_state), 4, 3)); + } else { + tap_code(dynamic_keymap_get_keycode(biton32(layer_state), 4, 4)); + } + } + return true; +} +#endif + +void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { + + if (user_config.top_rgb_change) + { + for (size_t i = 16; i < 83; i++) + { + RGB_MATRIX_INDICATOR_SET_COLOR(i, 0, 0, 0); + } + } + + if (host_keyboard_led_state().caps_lock) { + RGB_MATRIX_INDICATOR_SET_COLOR(52, 0, 255, 255); // assuming caps lock is at led #5 + } + + if (user_config.bottom_rgb_change) + { + for (size_t i = 0; i < 16; i++) + { + RGB_MATRIX_INDICATOR_SET_COLOR(i, 0, 0, 0); + } + } +} diff --git a/keyboards/mwstudio/mw65_rgb/keymaps/via/rules.mk b/keyboards/mwstudio/mw65_rgb/keymaps/via/rules.mk new file mode 100644 index 000000000000..36b7ba9cbc98 --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/keymaps/via/rules.mk @@ -0,0 +1,2 @@ +VIA_ENABLE = yes +LTO_ENABLE = yes diff --git a/keyboards/mwstudio/mw65_rgb/mw65_rgb.c b/keyboards/mwstudio/mw65_rgb/mw65_rgb.c new file mode 100644 index 000000000000..e49944f1ce2e --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/mw65_rgb.c @@ -0,0 +1,45 @@ +/* Copyright 2021 TW59420 + * + * 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 . + */ + +#include "mw65_rgb.h" + +#ifdef RGB_MATRIX_ENABLE +led_config_t g_led_config = { { + { 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68 }, + { 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67 }, + { 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, NO_LED, 40, 39 }, + { 25, NO_LED, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38 }, + { 24, 23, 22, NO_LED, NO_LED, NO_LED, 21, NO_LED, NO_LED, 15, 20, 19, 18, 17, 16 }, + + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } +}, { + { 175, 45 },{ 130, 45 },{ 85, 45 }, { 50, 45 }, { 15, 45 }, { 15, 35 }, { 15, 25 }, { 15, 10 }, + { 50, 10 }, { 85, 10 }, { 130, 10 }, { 175, 10 }, { 210, 10 }, { 210, 25 }, { 210, 35 }, { 210, 45 }, + { 217, 54 }, { 203, 54 }, { 189, 54 }, { 166, 54 }, { 150, 54 }, { 95, 54 }, { 40, 54 }, { 24, 54 }, { 8, 54 }, + { 17, 42 }, { 39, 42 }, { 53, 42 }, { 67, 42 }, { 81, 42 }, { 95, 42 }, { 109, 42 }, { 123, 42 }, { 137, 42 }, { 151, 42 }, { 165, 42 }, { 184, 42 }, { 203, 42 }, { 217, 42 }, + { 217, 30 }, { 195, 30 }, { 172, 30 }, { 158, 30 }, { 144, 30 }, { 130, 30 }, { 116, 30 }, { 102, 30 }, { 88, 30 }, { 74, 30 }, { 60, 30 }, { 46, 30 }, { 32, 30 },{ 13, 30 }, + { 9, 18 }, { 25, 18 }, { 39, 18 }, { 53, 18 }, { 67, 18 }, { 81, 18 }, { 95, 18 }, { 109, 18 }, { 123, 18 }, { 137, 18 }, { 151, 18 }, { 165, 18 }, { 181, 18 }, { 199, 18 }, { 217, 18 }, + { 217, 6 }, { 196, 6 }, { 175, 6 }, { 161, 6 }, { 147, 6 }, { 133, 6 }, { 119, 6 }, { 105, 6 }, { 91, 6 }, { 77, 6 }, { 63, 6 }, { 49, 6 }, { 35, 6 }, { 21, 6 }, { 7, 6 }, +}, { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +} }; +#endif + diff --git a/keyboards/mwstudio/mw65_rgb/mw65_rgb.h b/keyboards/mwstudio/mw65_rgb/mw65_rgb.h new file mode 100644 index 000000000000..b491e324e28a --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/mw65_rgb.h @@ -0,0 +1,33 @@ +/* Copyright 2021 TW59420 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include "quantum.h" + +#define LAYOUT( \ + K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014, \ + K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, \ + K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K213, K214, \ + K300, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K313, K314, \ + K400, K401, K402, K403, K404, K406, K410, K411, K412, K413, K414 \ +) { \ + { K000, K001, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 }, \ + { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 }, \ + { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, KC_NO, K213, K214 }, \ + { K300, KC_NO, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K312, K313, K314 }, \ + { K400, K401, K402, K403, K404, KC_NO, K406, KC_NO, KC_NO, KC_NO, K410, K411, K412, K413, K414 }, \ + { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO } \ +} diff --git a/keyboards/mwstudio/mw65_rgb/readme.md b/keyboards/mwstudio/mw65_rgb/readme.md new file mode 100644 index 000000000000..e15b5f9de9b2 --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/readme.md @@ -0,0 +1,22 @@ +# MW65_RGB + +![MW65_RGB](https://i.imgur.com/MPb8Lba.jpg?2) + +Support Atmega32u4 keyboard. + +* Keyboard Maintainer: [TW59420](https://github.com/TW59420) +* Hardware Supported: Atmega32u4 + +Make example for this keyboard (after setting up your build environment): + + make mwstudio/mw65_rgb:default + +Flashing example for this keyboard: + + make mwstudio/mw65_rgb:default:flash + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +## Bootloader +* **Physical reset button**: Short press the button on the back of the PCB to enter the Bootloader and flash the firmware +* **Keycode in layout**: Press the key mapped to RESET if it is available diff --git a/keyboards/mwstudio/mw65_rgb/rules.mk b/keyboards/mwstudio/mw65_rgb/rules.mk new file mode 100644 index 000000000000..58d8da3e898b --- /dev/null +++ b/keyboards/mwstudio/mw65_rgb/rules.mk @@ -0,0 +1,24 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +RGB_MATRIX_ENABLE = yes +RGB_MATRIX_DRIVER = WS2812 +ENCODER_ENABLE = yes diff --git a/keyboards/mwstudio/readme.md b/keyboards/mwstudio/readme.md index d4433a8c9613..1962a97d8215 100644 --- a/keyboards/mwstudio/readme.md +++ b/keyboards/mwstudio/readme.md @@ -2,4 +2,6 @@ This is a series of PCB * MW75 The chip is ATmega32U4 +* MW65_RGB The chip is ATmega32U4 + From 59738955293c85abcc5d9bd6998e3ed90ced4733 Mon Sep 17 00:00:00 2001 From: binepad <69730862+binepad@users.noreply.github.com> Date: Wed, 27 Oct 2021 20:37:58 +0530 Subject: [PATCH 0051/1136] [Keyboard] binepad bn009 (#14881) Co-authored-by: Drashna Jaelre Co-authored-by: Ryan --- keyboards/binepad/bn009/bn009.c | 16 ++++ keyboards/binepad/bn009/bn009.h | 28 +++++++ keyboards/binepad/bn009/config.h | 78 +++++++++++++++++++ keyboards/binepad/bn009/info.json | 10 +++ .../binepad/bn009/keymaps/default/keymap.c | 42 ++++++++++ .../binepad/bn009/keymaps/default/readme.md | 1 + keyboards/binepad/bn009/keymaps/via/keymap.c | 44 +++++++++++ keyboards/binepad/bn009/keymaps/via/rules.mk | 1 + keyboards/binepad/bn009/readme.md | 17 ++++ keyboards/binepad/bn009/rules.mk | 21 +++++ 10 files changed, 258 insertions(+) create mode 100644 keyboards/binepad/bn009/bn009.c create mode 100644 keyboards/binepad/bn009/bn009.h create mode 100644 keyboards/binepad/bn009/config.h create mode 100644 keyboards/binepad/bn009/info.json create mode 100644 keyboards/binepad/bn009/keymaps/default/keymap.c create mode 100644 keyboards/binepad/bn009/keymaps/default/readme.md create mode 100644 keyboards/binepad/bn009/keymaps/via/keymap.c create mode 100644 keyboards/binepad/bn009/keymaps/via/rules.mk create mode 100644 keyboards/binepad/bn009/readme.md create mode 100644 keyboards/binepad/bn009/rules.mk diff --git a/keyboards/binepad/bn009/bn009.c b/keyboards/binepad/bn009/bn009.c new file mode 100644 index 000000000000..48bfb44dae56 --- /dev/null +++ b/keyboards/binepad/bn009/bn009.c @@ -0,0 +1,16 @@ +/* Copyright 2020 BINEPAD + * + * 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 . + */ +#include "bn009.h" diff --git a/keyboards/binepad/bn009/bn009.h b/keyboards/binepad/bn009/bn009.h new file mode 100644 index 000000000000..9a3a23fbcb4b --- /dev/null +++ b/keyboards/binepad/bn009/bn009.h @@ -0,0 +1,28 @@ +/* Copyright 2020 BINEPAD + * + * 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 . + */ +#include "quantum.h" + +#define LAYOUT( \ + k00, k01, k02, \ + k10, k11, k12, \ + k20, k21, k22 \ +) \ +{ \ + { k00, k01, k02 }, \ + { k10, k11, k12 }, \ + { k20, k21, k22 } \ +} + diff --git a/keyboards/binepad/bn009/config.h b/keyboards/binepad/bn009/config.h new file mode 100644 index 000000000000..0b12f54c75f3 --- /dev/null +++ b/keyboards/binepad/bn009/config.h @@ -0,0 +1,78 @@ +/* Copyright 2020 BINEPAD + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x4249 // Binepad +#define PRODUCT_ID 0x4295 +#define DEVICE_VER 0x0001 +#define MANUFACTURER Binepad +#define PRODUCT BN009 + +/* Key matrix size */ +#define MATRIX_ROWS 3 +#define MATRIX_COLS 3 + +#define MATRIX_ROW_PINS { D2, D1, D0 } +#define MATRIX_COL_PINS { B6, B5, B4 } +#define UNUSED_PINS + +/* COL2ROW, ROW2COL*/ +#define DIODE_DIRECTION COL2ROW + + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is userful for the Windows task manager shortcut (ctrl+shift+esc). + */ +// #define GRAVE_ESC_CTRL_OVERRIDE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + + */ +//#define FORCE_NKRO + diff --git a/keyboards/binepad/bn009/info.json b/keyboards/binepad/bn009/info.json new file mode 100644 index 000000000000..2d439c825737 --- /dev/null +++ b/keyboards/binepad/bn009/info.json @@ -0,0 +1,10 @@ +{ + "keyboard_name": "BN009", + "url": "https://binepad.com", + "maintainer": "binepad", + "layouts": { + "LAYOUT": { + "layout": [{"label":"k00", "x":0, "y":0}, {"label":"k01", "x":1, "y":0}, {"label":"k02", "x":2, "y":0}, {"label":"k10", "x":0, "y":1}, {"label":"k11", "x":1, "y":1}, {"label":"k12", "x":2, "y":1}, {"label":"k20", "x":0, "y":2}, {"label":"k21", "x":1, "y":2}, {"label":"k22", "x":2, "y":2}] + } + } +} \ No newline at end of file diff --git a/keyboards/binepad/bn009/keymaps/default/keymap.c b/keyboards/binepad/bn009/keymaps/default/keymap.c new file mode 100644 index 000000000000..573a25d01dcb --- /dev/null +++ b/keyboards/binepad/bn009/keymaps/default/keymap.c @@ -0,0 +1,42 @@ +/* Copyright 2021 BINEPAD + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + +[0] = LAYOUT( + KC_7, KC_8, KC_9, + KC_4, KC_5, KC_6, + KC_1, KC_2, KC_3 +), + + +[1] = LAYOUT( + KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO +), + + +[2] = LAYOUT( + KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO, + KC_NO, KC_NO, KC_NO +) + +}; diff --git a/keyboards/binepad/bn009/keymaps/default/readme.md b/keyboards/binepad/bn009/keymaps/default/readme.md new file mode 100644 index 000000000000..b3c7ba28dc50 --- /dev/null +++ b/keyboards/binepad/bn009/keymaps/default/readme.md @@ -0,0 +1 @@ +# bn009 - Default layout diff --git a/keyboards/binepad/bn009/keymaps/via/keymap.c b/keyboards/binepad/bn009/keymaps/via/keymap.c new file mode 100644 index 000000000000..4ce3d1ae786d --- /dev/null +++ b/keyboards/binepad/bn009/keymaps/via/keymap.c @@ -0,0 +1,44 @@ +/* Copyright 2021 BINEPAD + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = + LAYOUT( + KC_7 , KC_8 , KC_9, + KC_4 , KC_5 , KC_6, + KC_1 , KC_2 , KC_3 + ), + [1] = + LAYOUT( + KC_NO , KC_NO, KC_NO, + KC_NO , KC_NO, KC_NO, + KC_NO , KC_NO, KC_NO + ), + [2] = + LAYOUT( + KC_NO , KC_NO, KC_NO, + KC_NO , KC_NO, KC_NO, + KC_NO , KC_NO, KC_NO + ), + [3] = + LAYOUT( + KC_NO , KC_NO, KC_NO, + KC_NO , KC_NO, KC_NO, + KC_NO , KC_NO, KC_NO + ), +}; diff --git a/keyboards/binepad/bn009/keymaps/via/rules.mk b/keyboards/binepad/bn009/keymaps/via/rules.mk new file mode 100644 index 000000000000..1e5b99807cb7 --- /dev/null +++ b/keyboards/binepad/bn009/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/binepad/bn009/readme.md b/keyboards/binepad/bn009/readme.md new file mode 100644 index 000000000000..dc0442fa8269 --- /dev/null +++ b/keyboards/binepad/bn009/readme.md @@ -0,0 +1,17 @@ +# BINEPAD BN009 + +![BINEPAD BN009](https://imgur.com/fu0iXD0h.jpg) + +A 9% macropad. + +* Keyboard Maintainer: [BINEPAD] +* Hardware Supported: BN009 PCB (ATmega32U4) +* Hardware Availability: [Interest Check](https://www.binepad.com/bn009) + +**Physical reset button**: There's a small hole at the bottom of macropad. Use the reset pin provided in box and push it hard through the hole, so that it press the reset button on pcb. + +Make example for this keyboard (after setting up your build environment): + + make binepad/bn009:default + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/binepad/bn009/rules.mk b/keyboards/binepad/bn009/rules.mk new file mode 100644 index 000000000000..10e9616d6fdf --- /dev/null +++ b/keyboards/binepad/bn009/rules.mk @@ -0,0 +1,21 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output From e4ae4c8b1ceef6617aa3928901c78eaa1e8fd5b5 Mon Sep 17 00:00:00 2001 From: pttbx <57902726+pttbx@users.noreply.github.com> Date: Wed, 27 Oct 2021 23:09:19 +0800 Subject: [PATCH 0052/1136] [Keymap] Add personal lily58 keymap (#14834) Co-authored-by: Ryan Co-authored-by: polplop Co-authored-by: paultan <47445257+polplop@users.noreply.github.com> --- keyboards/lily58/keymaps/pttbx/config.h | 46 +++++++ keyboards/lily58/keymaps/pttbx/keymap.c | 164 ++++++++++++++++++++++++ keyboards/lily58/keymaps/pttbx/rules.mk | 5 + 3 files changed, 215 insertions(+) create mode 100644 keyboards/lily58/keymaps/pttbx/config.h create mode 100644 keyboards/lily58/keymaps/pttbx/keymap.c create mode 100644 keyboards/lily58/keymaps/pttbx/rules.mk diff --git a/keyboards/lily58/keymaps/pttbx/config.h b/keyboards/lily58/keymaps/pttbx/config.h new file mode 100644 index 000000000000..d843f5b1c4f4 --- /dev/null +++ b/keyboards/lily58/keymaps/pttbx/config.h @@ -0,0 +1,46 @@ +/* +This is the c configuration file for the keymap + +Copyright 2012 Jun Wako +Copyright 2015 Jack Humbert + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +/* Select hand configuration */ + +#define MASTER_LEFT +// #define MASTER_RIGHT +// #define EE_HANDS + +#define TAPPING_FORCE_HOLD +#define TAPPING_TERM 100 + +#undef RGBLED_NUM +#define RGBLIGHT_ANIMATIONS +#define RGBLED_NUM 27 +#define RGBLIGHT_LIMIT_VAL 120 +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 +#define RGBLIGHT_VAL_STEP 17 + +// Underglow +/* +#undef RGBLED_NUM +#define RGBLED_NUM 14 // Number of LEDs +#define RGBLIGHT_ANIMATIONS +#define RGBLIGHT_SLEEP +*/ diff --git a/keyboards/lily58/keymaps/pttbx/keymap.c b/keyboards/lily58/keymaps/pttbx/keymap.c new file mode 100644 index 000000000000..944794141a8a --- /dev/null +++ b/keyboards/lily58/keymaps/pttbx/keymap.c @@ -0,0 +1,164 @@ +/* Copyright 2021 Paul Tan + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +enum layer_number { + _QWERTY = 0, + _LOWER, + _RAISE, + _ADJUST, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* QWERTY + * ,-----------------------------------------. ,-----------------------------------------. + * | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | ` | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | Tab | Q | W | E | R | T | | Y | U | I | O | P | - | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * |LCTRL | A | S | D | F | G |-------. ,-------| H | J | K | L | ; | ' | + * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------| + * |LShift| Z | X | C | V | B |-------| |-------| N | M | , | . | / |RShift| + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LOWER| LGUI |LAlt | /Space / \Enter \ |BackSP| RGUI |RAISE | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ + + [_QWERTY] = LAYOUT( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_GRV, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS, + KC_LCTRL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + MO(_LOWER), KC_LGUI, KC_LALT, KC_SPC, KC_ENT, KC_BSPC, KC_RGUI, MO(_RAISE) +), +/* LOWER + * ,-----------------------------------------. ,-----------------------------------------. + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | ` | ! | @ | # | $ | % |-------. ,-------| ^ | & | * | ( | ) | - | + * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------| + * | | | | | | |-------| |-------| | _ | + | { | } | | | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ +[_LOWER] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______,_______, _______, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, + KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_TILD, + _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, + _______, _______, _______, _______, _______, _______, _______, _______ +), +/* RAISE + * ,-----------------------------------------. ,-----------------------------------------. + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | F1 | F2 | F3 | F4 | F5 | F6 |-------. ,-------| | Left | Down | Up |Right | | + * |------+------+------+------+------+------| [ | | ] |------+------+------+------+------+------| + * | F7 | F8 | F9 | F10 | F11 | F12 |-------| |-------| + | - | = | [ | ] | \ | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ + +[_RAISE] = LAYOUT( + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX, + KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, KC_PLUS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, + _______, _______, _______, _______, _______, _______, _______, _______ +), +/* ADJUST + * ,-----------------------------------------. ,-----------------------------------------. + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | | | | | | |-------. ,-------| | |RGB ON| HUE+ | SAT+ | VAL+ | + * |------+------+------+------+------+------| | | |------+------+------+------+------+------| + * | | | | | | |-------| |-------| | | MODE | HUE- | SAT- | VAL- | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ + [_ADJUST] = LAYOUT( + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + _______, _______, _______, _______, _______, _______, _______, _______ + ) +}; + +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} + +//SSD1306 OLED update loop, make sure to enable OLED_ENABLE=yes in rules.mk +#ifdef OLED_ENABLE + +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + if (!is_keyboard_master()) + return OLED_ROTATION_180; // flips the display 180 degrees if offhand + return rotation; +} + +// When you add source files to SRC in rules.mk, you can use functions. +const char *read_layer_state(void); +const char *read_logo(void); +void set_keylog(uint16_t keycode, keyrecord_t *record); +const char *read_keylog(void); +const char *read_keylogs(void); + +// const char *read_mode_icon(bool swap); +// const char *read_host_led_state(void); +// void set_timelog(void); +// const char *read_timelog(void); + +void oled_task_user(void) { + if (is_keyboard_master()) { + // If you want to change the display of OLED, you need to change here + oled_write_ln(read_layer_state(), false); + oled_write_ln(read_keylog(), false); + oled_write_ln(read_keylogs(), false); + //oled_write_ln(read_mode_icon(keymap_config.swap_lalt_lgui), false); + //oled_write_ln(read_host_led_state(), false); + //oled_write_ln(read_timelog(), false); + } else { + oled_write(read_logo(), false); + } +} +#endif // OLED_ENABLE + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + if (record->event.pressed) { +#ifdef OLED_ENABLE + set_keylog(keycode, record); +#endif + // set_timelog(); + } + return true; +} diff --git a/keyboards/lily58/keymaps/pttbx/rules.mk b/keyboards/lily58/keymaps/pttbx/rules.mk new file mode 100644 index 000000000000..e2c8a6f7467b --- /dev/null +++ b/keyboards/lily58/keymaps/pttbx/rules.mk @@ -0,0 +1,5 @@ +# If you want to change the display of OLED, you need to change here +SRC += ./lib/rgb_state_reader.c \ + ./lib/layer_state_reader.c \ + ./lib/logo_reader.c \ + ./lib/keylogger.c From 128b4eb005c2d8dcedb715e0168bde3beb591bac Mon Sep 17 00:00:00 2001 From: peepeetee <43021794+peepeetee@users.noreply.github.com> Date: Wed, 27 Oct 2021 23:09:52 +0800 Subject: [PATCH 0053/1136] [Keyboard] Add support for bm65rgb, a revival of #13361 (#14800) Co-authored-by: Drashna Jaelre Co-authored-by: Ryan Co-authored-by: bytesapart --- .../bm65rgb/keymaps/default/keymap.c | 34 +++++ .../bm65rgb/keymaps/default/readme.md | 1 + keyboards/kprepublic/bm65rgb/readme.md | 24 ++++ keyboards/kprepublic/bm65rgb/rev1/config.h | 122 ++++++++++++++++++ keyboards/kprepublic/bm65rgb/rev1/info.json | 78 +++++++++++ keyboards/kprepublic/bm65rgb/rev1/readme.md | 24 ++++ keyboards/kprepublic/bm65rgb/rev1/rev1.c | 44 +++++++ keyboards/kprepublic/bm65rgb/rev1/rev1.h | 41 ++++++ keyboards/kprepublic/bm65rgb/rev1/rules.mk | 26 ++++ 9 files changed, 394 insertions(+) create mode 100644 keyboards/kprepublic/bm65rgb/keymaps/default/keymap.c create mode 100644 keyboards/kprepublic/bm65rgb/keymaps/default/readme.md create mode 100644 keyboards/kprepublic/bm65rgb/readme.md create mode 100644 keyboards/kprepublic/bm65rgb/rev1/config.h create mode 100644 keyboards/kprepublic/bm65rgb/rev1/info.json create mode 100644 keyboards/kprepublic/bm65rgb/rev1/readme.md create mode 100644 keyboards/kprepublic/bm65rgb/rev1/rev1.c create mode 100644 keyboards/kprepublic/bm65rgb/rev1/rev1.h create mode 100644 keyboards/kprepublic/bm65rgb/rev1/rules.mk diff --git a/keyboards/kprepublic/bm65rgb/keymaps/default/keymap.c b/keyboards/kprepublic/bm65rgb/keymaps/default/keymap.c new file mode 100644 index 000000000000..dadeb9c149aa --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/keymaps/default/keymap.c @@ -0,0 +1,34 @@ +/* Copyright 2021 bytesapart + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi_blocker( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_LEFT, KC_DOWN, KC_RGHT + ), + [1] = LAYOUT_65_ansi_blocker( + KC_GRAVE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, + _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + +}; diff --git a/keyboards/kprepublic/bm65rgb/keymaps/default/readme.md b/keyboards/kprepublic/bm65rgb/keymaps/default/readme.md new file mode 100644 index 000000000000..72171ee89a68 --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/keymaps/default/readme.md @@ -0,0 +1 @@ +# The default keymap for bm65rgb diff --git a/keyboards/kprepublic/bm65rgb/readme.md b/keyboards/kprepublic/bm65rgb/readme.md new file mode 100644 index 000000000000..3a87afabf142 --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/readme.md @@ -0,0 +1,24 @@ +# bm65rgb + +![bm65rgb](https://i.imgur.com/DskSCve.jpeg) + +A 65% hotswap in switch RGB keyboard from KPRepublic. + +* Keyboard Maintainer: [bytesapart](https://github.com/bytesapart) +* Hardware Supported: BM65 RGB +* Hardware Availability: [KP Republic](https://kprepublic.com/products/bm65rgb-bm65-rgb-65-hot-swappable-custom-mechanical-keyboard-pcb-programmed-qmk-via-firmware-full-rgb-switch-underglow-type-c?_pos=1&_sid=5b9a6a5d0&_ss=r) + +Make example for this keyboard (after setting up your build environment): + + make kprepublic/bm65rgb:default + +Flashing example for this keyboard: + + make kprepublic/bm65rgb:default:flash + +To reset the board into bootloader mode, do one of the following: + +* Short the two-pad footprint to the left of the spacebar switch while the board is plugged in +* Hold the Esc key while connecting the USB cable (also erases persistent settings) + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/kprepublic/bm65rgb/rev1/config.h b/keyboards/kprepublic/bm65rgb/rev1/config.h new file mode 100644 index 000000000000..21624b9f1664 --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/rev1/config.h @@ -0,0 +1,122 @@ +/* +Copyright 2021 bytesapart + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x4B50 //KP +#define PRODUCT_ID 0xEF6E +#define DEVICE_VER 0x0001 +#define MANUFACTURER KPRepublic +#define PRODUCT BM65 RGB + +/* key matrix size */ +#define MATRIX_ROWS 5 +#define MATRIX_COLS 15 + +/* + * Keyboard Matrix Assignments + * + * Change this to how you wired your keyboard + * COLS: AVR pins used for columns, left to right + * ROWS: AVR pins used for rows, top to bottom + * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) + * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) + * + */ +#define MATRIX_ROW_PINS { B0, \ + B1, \ + B2, \ + B3, \ + E6 } +#define MATRIX_COL_PINS { D0, D1, D2, D3, D5, D4, D6, D7, B4, B5, B6, C6, C7, F7, F6 } +#define UNUSED_PINS + +/* COL2ROW, ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +// The pin connected to the data pin of the LEDs +#define RGB_DI_PIN E2 +// The number of LEDs connected +#define DRIVER_LED_TOTAL 73 +#ifdef RGB_DI_PIN + #define RGBLED_NUM 73 + #define RGB_MATRIX_KEYPRESSES // reacts to keypresses +#endif + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is useful for the Windows task manager shortcut (ctrl+shift+esc). + */ +//#define GRAVE_ESC_CTRL_OVERRIDE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT + +/* disable these deprecated features by default */ +#define NO_ACTION_MACRO +#define NO_ACTION_FUNCTION + +/* Bootmagic Lite key configuration */ +//#define BOOTMAGIC_LITE_ROW 0 +//#define BOOTMAGIC_LITE_COLUMN 0 diff --git a/keyboards/kprepublic/bm65rgb/rev1/info.json b/keyboards/kprepublic/bm65rgb/rev1/info.json new file mode 100644 index 000000000000..444d8cee8516 --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/rev1/info.json @@ -0,0 +1,78 @@ +{ + "keyboard_name": "bm65rgb", + "url": "", + "maintainer": "bytesapart", + "layouts": { + "LAYOUT_65_ansi": { + "layout": [ + {"label":"K00 (B0,D0)", "x":0, "y":0}, + {"label":"K01 (B0,D1)", "x":1, "y":0}, + {"label":"K02 (B0,D2)", "x":2, "y":0}, + {"label":"K03 (B0,D3)", "x":3, "y":0}, + {"label":"K04 (B0,D5)", "x":4, "y":0}, + {"label":"K05 (B0,D4)", "x":5, "y":0}, + {"label":"K06 (B0,D6)", "x":6, "y":0}, + {"label":"K07 (B0,D7)", "x":7, "y":0}, + {"label":"K08 (B0,B4)", "x":8, "y":0}, + {"label":"K09 (B0,B5)", "x":9, "y":0}, + {"label":"K0A (B0,B6)", "x":10, "y":0}, + {"label":"K0B (B0,C6)", "x":11, "y":0}, + {"label":"K0C (B0,C7)", "x":12, "y":0}, + {"label":"K0D (B0,F7)", "x":13, "y":0, "w":2}, + {"label":"K0E (B0,F6)", "x":15, "y":0}, + {"label":"K10 (B1,D0)", "x":0, "y":1, "w":1.5}, + {"label":"K11 (B1,D1)", "x":1.5, "y":1}, + {"label":"K12 (B1,D2)", "x":2.5, "y":1}, + {"label":"K13 (B1,D3)", "x":3.5, "y":1}, + {"label":"K14 (B1,D5)", "x":4.5, "y":1}, + {"label":"K15 (B1,D4)", "x":5.5, "y":1}, + {"label":"K16 (B1,D6)", "x":6.5, "y":1}, + {"label":"K17 (B1,D7)", "x":7.5, "y":1}, + {"label":"K18 (B1,B4)", "x":8.5, "y":1}, + {"label":"K19 (B1,B5)", "x":9.5, "y":1}, + {"label":"K1A (B1,B6)", "x":10.5, "y":1}, + {"label":"K1B (B1,C6)", "x":11.5, "y":1}, + {"label":"K1C (B1,C7)", "x":12.5, "y":1}, + {"label":"K1D (B1,F7)", "x":13.5, "y":1, "w":1.5}, + {"label":"K1E (B1,F6)", "x":15, "y":1}, + {"label":"K20 (B2,D0)", "x":0, "y":2, "w":1.75}, + {"label":"K22 (B2,D2)", "x":1.75, "y":2}, + {"label":"K23 (B2,D3)", "x":2.75, "y":2}, + {"label":"K24 (B2,D5)", "x":3.75, "y":2}, + {"label":"K25 (B2,D4)", "x":4.75, "y":2}, + {"label":"K26 (B2,D6)", "x":5.75, "y":2}, + {"label":"K27 (B2,D7)", "x":6.75, "y":2}, + {"label":"K28 (B2,B4)", "x":7.75, "y":2}, + {"label":"K29 (B2,B5)", "x":8.75, "y":2}, + {"label":"K2A (B2,B6)", "x":9.75, "y":2}, + {"label":"K2B (B2,C6)", "x":10.75, "y":2}, + {"label":"K2C (B2,C7)", "x":11.75, "y":2}, + {"label":"K2D (B2,F7)", "x":12.75, "y":2, "w":2.25}, + {"label":"K2E (B2,F6)", "x":15, "y":2}, + {"label":"K31 (B3,D1)", "x":0, "y":3, "w":2.25}, + {"label":"K32 (B3,D2)", "x":2.25, "y":3}, + {"label":"K33 (B3,D3)", "x":3.25, "y":3}, + {"label":"K34 (B3,D5)", "x":4.25, "y":3}, + {"label":"K35 (B3,D4)", "x":5.25, "y":3}, + {"label":"K36 (B3,D6)", "x":6.25, "y":3}, + {"label":"K37 (B3,D7)", "x":7.25, "y":3}, + {"label":"K38 (B3,B4)", "x":8.25, "y":3}, + {"label":"K39 (B3,B5)", "x":9.25, "y":3}, + {"label":"K3A (B3,B6)", "x":10.25, "y":3}, + {"label":"K3B (B3,C6)", "x":11.25, "y":3}, + {"label":"K3C (B3,C7)", "x":12.25, "y":3, "w":1.75}, + {"label":"K3D (B3,F7)", "x":14, "y":3}, + {"label":"K3E (B3,F6)", "x":15, "y":3}, + {"label":"K40 (E6,D0)", "x":0, "y":4, "w":1.25}, + {"label":"K41 (E6,D1)", "x":1.25, "y":4, "w":1.25}, + {"label":"K42 (E6,D2)", "x":2.5, "y":4, "w":1.25}, + {"label":"K46 (E6,D6)", "x":3.75, "y":4, "w":6.25}, + {"label":"K49 (E6,B5)", "x":10, "y":4}, + {"label":"K4A (E6,B6)", "x":11, "y":4}, + {"label":"K49 (E6,B5)", "x":10, "y":4, "w":1.25}, + {"label":"K4A (E6,B6)", "x":11.25, "y":4, "w":1.25}, + {"label":"K4E (E6,F6)", "x":15, "y":4} + ] + } + } +} diff --git a/keyboards/kprepublic/bm65rgb/rev1/readme.md b/keyboards/kprepublic/bm65rgb/rev1/readme.md new file mode 100644 index 000000000000..119d05d20e6c --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/rev1/readme.md @@ -0,0 +1,24 @@ +# bm65rgb + +![bm65rgb](https://i.imgur.com/DskSCve.jpeg) + +A 65% hotswap in switch RGB keyboard from KPRepublic. + +* Keyboard Maintainer: [bytesapart](https://github.com/bytesapart) +* Hardware Supported: BM65 RGB +* Hardware Availability: [KP Republic](https://kprepublic.com/products/bm65rgb-bm65-rgb-65-hot-swappable-custom-mechanical-keyboard-pcb-programmed-qmk-via-firmware-full-rgb-switch-underglow-type-c?_pos=1&_sid=5b9a6a5d0&_ss=r) + +Make example for this keyboard (after setting up your build environment): + + make kprepublic/bm65rgb/rev1:default + +Flashing example for this keyboard: + + make kprepublic/bm65rgb/rev1:default:flash + +To reset the board into bootloader mode, do one of the following: + +* Short the two-pad footprint to the left of the spacebar switch while the board is plugged in +* Hold the Esc key while connecting the USB cable (also erases persistent settings) + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). diff --git a/keyboards/kprepublic/bm65rgb/rev1/rev1.c b/keyboards/kprepublic/bm65rgb/rev1/rev1.c new file mode 100644 index 000000000000..6f85f256e1f4 --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/rev1/rev1.c @@ -0,0 +1,44 @@ +/* Copyright 2021 bytesapart + * + * 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 . + */ + +#include "rev1.h" + +#ifdef RGB_MATRIX_ENABLE +led_config_t g_led_config = { { + // Key Matrix to LED Index + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, + { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }, + { 30, NO_LED, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 }, + { NO_LED, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 }, + { 58, 59, 60, NO_LED, NO_LED, NO_LED, 61, NO_LED, NO_LED, 62, 63, NO_LED, 64, 65, 66 } +}, { + // LED Index to Physical Position + { 0, 0}, { 15, 0}, { 30, 0}, { 45, 0}, { 60, 0}, { 75, 0}, { 90, 0}, {105, 0}, {120, 0}, {135, 0}, {150, 0}, {165, 0}, {180, 0}, {202, 0}, {225, 0}, // Esc, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, Backspace, Delete + { 4, 16}, { 22, 16}, { 37, 16}, { 52, 16}, { 67, 16}, { 82, 16}, { 97, 16}, {112, 16}, {127, 16}, {142, 16}, {157, 16}, {172, 16}, {187, 16}, {206, 16}, {225, 16}, // Tab, Q, W, E, R, T, Y, U, I, O, P, [, ], backslash , Home + { 6, 32}, { 26, 32}, { 41, 32}, { 56, 32}, { 71, 32}, { 86, 32}, {101, 32}, {116, 32}, {131, 32}, {146, 32}, {161, 32}, {176, 32}, {201, 32}, {225, 32}, // Capslock, A, S, D, F, G, H, J, K, L, ;, ', Enter, Page up + { 9, 48}, { 34, 48}, { 49, 48}, { 64, 48}, { 79, 48}, { 94, 48}, {109, 48}, {124, 48}, {139, 48}, {154, 48}, {169, 48}, {189, 48}, {208, 48}, {225, 48}, // LShift, Z, X, C, V, B, N, M, ,, ., /, Shift, Up, Page Down + { 2, 64}, { 21, 64}, { 39, 64}, { 94, 64}, {148, 64}, {163, 64}, {193, 64}, {208, 64}, {225, 64}, // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right + {185, 45}, {160, 45}, {125, 45}, { 95, 45}, { 60, 45}, { 25, 45} // UNDERGLOW +}, { + // LED Index to Flag + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, // Esc, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, Backspace, Delete + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, // Tab, Q, W, E, R, T, Y, U, I, O, P, [, ], backslash , Home + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, // Capslock, A, S, D, F, G, H, J, K, L, ;, ', Enter, Page up + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, // LShift, Z, X, C, V, B, N, M, ,, ., /, Shift, Up, Page Down + 1, 1, 1, 4, 1, 1, 1, 1, 1, // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right + 2, 2, 2, 2, 2, 2 // UNDERGLOW +} }; +#endif diff --git a/keyboards/kprepublic/bm65rgb/rev1/rev1.h b/keyboards/kprepublic/bm65rgb/rev1/rev1.h new file mode 100644 index 000000000000..4bafcf1943dd --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/rev1/rev1.h @@ -0,0 +1,41 @@ +/* Copyright 2021 bytesapart + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + +/* This is a shortcut to help you visually see your layout. + * + * The first section contains all of the arguments representing the physical + * layout of the board and position of the keys. + * + * The second converts the arguments into a two-dimensional array which + * represents the switch matrix. + */ +#define LAYOUT_65_ansi_blocker( \ + k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E,\ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E,\ + k20, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E,\ + k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E,\ + k40, k41, k42, k46, k49, k4A, k4C, k4D, k4E\ +) { \ + { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E }, \ + { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E }, \ + { k20, KC_NO, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E }, \ + { KC_NO, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E }, \ + { k40, k41, k42, KC_NO, KC_NO, KC_NO, k46, KC_NO, KC_NO, k49, k4A, KC_NO, k4C, k4D, k4E }, \ +} diff --git a/keyboards/kprepublic/bm65rgb/rev1/rules.mk b/keyboards/kprepublic/bm65rgb/rev1/rules.mk new file mode 100644 index 000000000000..a0e70197150d --- /dev/null +++ b/keyboards/kprepublic/bm65rgb/rev1/rules.mk @@ -0,0 +1,26 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = yes # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +RGB_MATRIX_ENABLE = yes +RGB_MATRIX_DRIVER = WS2812 +LTO_ENABLE = yes + +LAYOUTS = 65_ansi_blocker From 6c507afcf212165dd5f3c3f6c026b517295c5090 Mon Sep 17 00:00:00 2001 From: SmollChungus <38044391+SmollChungus@users.noreply.github.com> Date: Wed, 27 Oct 2021 17:14:44 +0200 Subject: [PATCH 0054/1136] [Keyboard] add Lefty keyboard (#14898) Co-authored-by: Drashna Jaelre Co-authored-by: Ryan --- keyboards/lefty/config.h | 44 ++++++++++++++++ keyboards/lefty/info.json | 43 ++++++++++++++++ keyboards/lefty/keymaps/default/keymap.c | 65 ++++++++++++++++++++++++ keyboards/lefty/keymaps/via/keymap.c | 65 ++++++++++++++++++++++++ keyboards/lefty/keymaps/via/rules.mk | 1 + keyboards/lefty/lefty.c | 43 ++++++++++++++++ keyboards/lefty/lefty.h | 37 ++++++++++++++ keyboards/lefty/readme.md | 27 ++++++++++ keyboards/lefty/rev1/config.h | 22 ++++++++ keyboards/lefty/rev1/rev1.c | 17 +++++++ keyboards/lefty/rev2/config.h | 21 ++++++++ keyboards/lefty/rev2/rev2.c | 17 +++++++ keyboards/lefty/rules.mk | 27 ++++++++++ 13 files changed, 429 insertions(+) create mode 100644 keyboards/lefty/config.h create mode 100644 keyboards/lefty/info.json create mode 100644 keyboards/lefty/keymaps/default/keymap.c create mode 100644 keyboards/lefty/keymaps/via/keymap.c create mode 100644 keyboards/lefty/keymaps/via/rules.mk create mode 100644 keyboards/lefty/lefty.c create mode 100644 keyboards/lefty/lefty.h create mode 100644 keyboards/lefty/readme.md create mode 100644 keyboards/lefty/rev1/config.h create mode 100644 keyboards/lefty/rev1/rev1.c create mode 100644 keyboards/lefty/rev2/config.h create mode 100644 keyboards/lefty/rev2/rev2.c create mode 100644 keyboards/lefty/rules.mk diff --git a/keyboards/lefty/config.h b/keyboards/lefty/config.h new file mode 100644 index 000000000000..85620ca15bf1 --- /dev/null +++ b/keyboards/lefty/config.h @@ -0,0 +1,44 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x5363 // Sc for Smollchungus +#define PRODUCT_ID 0x0001 +#define DEVICE_VER 0x0001 +#define MANUFACTURER SmollChungus +#define PRODUCT Lefty + +/* key matrix size */ +#define MATRIX_ROWS 5 +#define MATRIX_COLS 8 + +/* key matrix pins are in subfolders v1/v2 */ + +/* Diode direction */ +#define DIODE_DIRECTION COL2ROW + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE + +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE diff --git a/keyboards/lefty/info.json b/keyboards/lefty/info.json new file mode 100644 index 000000000000..bd5d2f7c4e4a --- /dev/null +++ b/keyboards/lefty/info.json @@ -0,0 +1,43 @@ +{ + "keyboard_name": "lefty", + "url": "https://github.com/smollchungus", + "maintainer": "smollchungus", + "layouts": { + "LAYOUT_all": { + "layout": [ + {"label":"F1", "x":0.5, "y":0}, + {"label":"Escape", "x":2, "y":0}, + {"label":"1", "x":3, "y":0}, + {"label":"2", "x":4, "y":0}, + {"label":"3", "x":5, "y":0}, + {"label":"4", "x":6, "y":0}, + {"label":"5", "x":7, "y":0}, + {"label":"6", "x":8, "y":0}, + {"label":"F2", "x":0.25, "y":1}, + {"label":"Tab", "x":1.75, "y":1, "w":1.5}, + {"label":"Q", "x":3.25, "y":1}, + {"label":"W", "x":4.25, "y":1}, + {"label":"E", "x":5.25, "y":1}, + {"label":"R", "x":6.25, "y":1}, + {"label":"T", "x":7.25, "y":1}, + {"label":"F3", "x":0, "y":2}, + {"label":"Caps Lock", "x":1.5, "y":2, "w":1.75}, + {"label":"A", "x":3.25, "y":2}, + {"label":"S", "x":4.25, "y":2}, + {"label":"D", "x":5.25, "y":2}, + {"label":"F", "x":6.25, "y":2}, + {"label":"G", "x":7.25, "y":2}, + {"label":"Shift", "x":1.25, "y":3, "w":2.25}, + {"label":"Z", "x":3.5, "y":3}, + {"label":"X", "x":4.5, "y":3}, + {"label":"C", "x":5.5, "y":3}, + {"label":"V", "x":6.5, "y":3}, + {"label":"B", "x":7.5, "y":3}, + {"label":"Control", "x":1.25, "y":4, "w":1.25}, + {"label":"Alt", "x":4.5, "y":4, "w":1.25}, + {"label":"Layer2", "x":5.75, "y":4, "w":2}, + {"label":"Layer3", "x":7.75, "y":4, "w":1.25} + ] + } + } +} diff --git a/keyboards/lefty/keymaps/default/keymap.c b/keyboards/lefty/keymaps/default/keymap.c new file mode 100644 index 000000000000..0e1f56c03676 --- /dev/null +++ b/keyboards/lefty/keymaps/default/keymap.c @@ -0,0 +1,65 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* 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 . +*/ + +#include QMK_KEYBOARD_H + +enum layers { + _QWERTY, + _LOWER, + _RAISE, + _SPECIAL, +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) +#define SPECIAL MO(_SPECIAL) + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[_QWERTY] = LAYOUT_all( + KC_UP, KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, + KC_DOWN, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, + KC_RGHT, LOWER, KC_A, KC_S, KC_D, KC_F, KC_G, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, + KC_LCTL, KC_LALT, RAISE, SPECIAL +), + +[_LOWER] = LAYOUT_all( + ____, ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____ +), + +[_RAISE] = LAYOUT_all( + ____, ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____ +), + +[_SPECIAL] = LAYOUT_all( + ____, ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____ +) +}; + diff --git a/keyboards/lefty/keymaps/via/keymap.c b/keyboards/lefty/keymaps/via/keymap.c new file mode 100644 index 000000000000..764aa80c826e --- /dev/null +++ b/keyboards/lefty/keymaps/via/keymap.c @@ -0,0 +1,65 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* 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 . +*/ + +#include QMK_KEYBOARD_H + + +enum layers { + _QWERTY, + _LOWER, + _RAISE, + _SPECIAL, +}; + +#define LOWER MO(_LOWER) +#define RAISE MO(_RAISE) +#define SPECIAL MO(_SPECIAL) + + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +[_QWERTY] = LAYOUT_all( + KC_UP, KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, + KC_DOWN, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, + KC_RGHT, LOWER, KC_A, KC_S, KC_D, KC_F, KC_G, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, + KC_LCTL, KC_LALT, RAISE, SPECIAL +), + +[_LOWER] = LAYOUT_all( + ____, ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____ +), + +[_RAISE] = LAYOUT_all( + ____, ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____ +), + +[_SPECIAL] = LAYOUT_all( + ____, ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____, ____, ____, + ____, ____, ____, ____ +) +}; diff --git a/keyboards/lefty/keymaps/via/rules.mk b/keyboards/lefty/keymaps/via/rules.mk new file mode 100644 index 000000000000..1e5b99807cb7 --- /dev/null +++ b/keyboards/lefty/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/lefty/lefty.c b/keyboards/lefty/lefty.c new file mode 100644 index 000000000000..ba4ac34383c0 --- /dev/null +++ b/keyboards/lefty/lefty.c @@ -0,0 +1,43 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* 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 . +*/ + +#include "lefty.h" + +#ifdef OLED_ENABLE +__attribute__((weak)) void oled_task_user(void) { + // Host Keyboard Layer Status + oled_write_P(PSTR("Layer: "), false); + + switch (get_highest_layer(layer_state)) { + case 0: + oled_write_P(PSTR("Default\n"), false); + break; + case 1: + oled_write_P(PSTR("LOWER\n"), false); + break; + case 2: + oled_write_P(PSTR("RAISE\n"), false); + break; + case 3: + oled_write_P(PSTR("SPECIAL\n"), false); + break; + default: + // Or use the write_ln shortcut over adding '\n' to the end of your string + oled_write_ln_P(PSTR("Undefined"), false); + } + +} +#endif diff --git a/keyboards/lefty/lefty.h b/keyboards/lefty/lefty.h new file mode 100644 index 000000000000..2466552353fa --- /dev/null +++ b/keyboards/lefty/lefty.h @@ -0,0 +1,37 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#pragma once + +#include "quantum.h" + +// keymap +#define LAYOUT_all( \ + K00, K01, K02, K03, K04, K05, K06, K07, \ + K10, K11, K12, K13, K14, K15, K16, \ + K20, K21, K22, K23, K24, K25, K26, \ + K31, K32, K33, K34, K35, K36, \ + K41, K43, K44, K46 \ +) \ +{ \ + { K00, K01, K02, K03, K04, K05, K06, K07 }, \ + { K10, K11, K12, K13, K14, K15, K16, KC_NO }, \ + { K20, K21, K22, K23, K24, K25, K26, KC_NO }, \ + { KC_NO, K31, K32, K33, K34, K35, K36, KC_NO }, \ + { KC_NO, K41, KC_NO, K43, K44, KC_NO, K46, KC_NO } \ +} + +#define LAYOUT LAYOUT diff --git a/keyboards/lefty/readme.md b/keyboards/lefty/readme.md new file mode 100644 index 000000000000..f8cc2ec2037d --- /dev/null +++ b/keyboards/lefty/readme.md @@ -0,0 +1,27 @@ +# lefty + +![lefty](https://i.imgur.com/nMmJCJMh.jpeg) + +Half an alice used as a macropad. + +* Keyboard Maintainer: [SmollChungus](https://github.com/smollchungus/) + +* Hardware Supported: Lefty PCB rev1 and rev2 + +Make example for this keyboard (after setting up your build environment): + + make lefty:default + +Flashing example for this keyboard: + + make lefty:default:flash + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. +Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +# Bootloader +Enter the bootloader in 3 ways: + +Bootmagic reset: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard +Physical reset button: Briefly press the button on the back of the PCB - some may have pads you must short instead +Keycode in layout: Press the key mapped to RESET if it is available diff --git a/keyboards/lefty/rev1/config.h b/keyboards/lefty/rev1/config.h new file mode 100644 index 000000000000..fa70eeb3595b --- /dev/null +++ b/keyboards/lefty/rev1/config.h @@ -0,0 +1,22 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#pragma once + +/* key matrix pins */ + +#define MATRIX_ROW_PINS { F0, F1, C7, D5, B7 } +#define MATRIX_COL_PINS { D4, B5, F5, F6, F7, B1, B3, F4 } diff --git a/keyboards/lefty/rev1/rev1.c b/keyboards/lefty/rev1/rev1.c new file mode 100644 index 000000000000..81734fd7fc39 --- /dev/null +++ b/keyboards/lefty/rev1/rev1.c @@ -0,0 +1,17 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* 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 . +*/ + +#include "lefty.h" diff --git a/keyboards/lefty/rev2/config.h b/keyboards/lefty/rev2/config.h new file mode 100644 index 000000000000..82894187287e --- /dev/null +++ b/keyboards/lefty/rev2/config.h @@ -0,0 +1,21 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +#pragma once + +/* key matrix pins */ +#define MATRIX_ROW_PINS { B2, B6, D7, E6, B4 } +#define MATRIX_COL_PINS { D4, B5, F5, F6, F7, B1, B3, F4 } diff --git a/keyboards/lefty/rev2/rev2.c b/keyboards/lefty/rev2/rev2.c new file mode 100644 index 000000000000..81734fd7fc39 --- /dev/null +++ b/keyboards/lefty/rev2/rev2.c @@ -0,0 +1,17 @@ +/* Copyright 2021 Smoll Chungus (@smollchungus) +* +* 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 . +*/ + +#include "lefty.h" diff --git a/keyboards/lefty/rules.mk b/keyboards/lefty/rules.mk new file mode 100644 index 000000000000..119ec3128a41 --- /dev/null +++ b/keyboards/lefty/rules.mk @@ -0,0 +1,27 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = atmel-dfu + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = no # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output +LTO_ENABLE = yes + +OLED_ENABLE = yes +OLED_DRIVER = SSD1306 + +DEFAULT_FOLDER = lefty/rev2 From b780c797beb726839e99e3f4054f9b4c33331cdc Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 28 Oct 2021 01:07:53 +0100 Subject: [PATCH 0055/1136] Migrate makefile utilities to sub-directory (#14917) --- Makefile | 3 ++- build_keyboard.mk | 13 +++++++------ build_test.mk | 5 +++-- bootloader.mk => builddefs/bootloader.mk | 0 .../disable_features.mk | 0 .../generic_features.mk | 0 {quantum => builddefs}/mcu_selection.mk | 0 message.mk => builddefs/message.mk | 0 show_options.mk => builddefs/show_options.mk | 0 common.mk => paths.mk | 5 +++-- 10 files changed, 15 insertions(+), 11 deletions(-) rename bootloader.mk => builddefs/bootloader.mk (100%) rename disable_features.mk => builddefs/disable_features.mk (100%) rename generic_features.mk => builddefs/generic_features.mk (100%) rename {quantum => builddefs}/mcu_selection.mk (100%) rename message.mk => builddefs/message.mk (100%) rename show_options.mk => builddefs/show_options.mk (100%) rename common.mk => paths.mk (91%) diff --git a/Makefile b/Makefile index a1741dd961f8..c221cb89e021 100644 --- a/Makefile +++ b/Makefile @@ -425,7 +425,8 @@ define SET_SILENT_MODE endif endef -include $(ROOT_DIR)/message.mk +include paths.mk +include $(BUILDDEFS_PATH)/message.mk ifeq ($(strip $(BREAK_ON_ERRORS)), yes) HANDLE_ERROR = exit 1 diff --git a/build_keyboard.mk b/build_keyboard.mk index c1f4f93381e4..36c628c7cebf 100644 --- a/build_keyboard.mk +++ b/build_keyboard.mk @@ -10,7 +10,8 @@ endif .DEFAULT_GOAL := all -include common.mk +include paths.mk +include $(BUILDDEFS_PATH)/message.mk # Set the qmk cli to use QMK_BIN ?= qmk @@ -164,7 +165,7 @@ ifeq ($(strip $(CONVERT_TO_PROTON_C)), yes) include platforms/chibios/boards/QMK_PROTON_C/convert_to_proton_c.mk endif -include quantum/mcu_selection.mk +include $(BUILDDEFS_PATH)/mcu_selection.mk # Find all the C source files to be compiled in subfolders. KEYBOARD_SRC := @@ -342,7 +343,7 @@ ifneq ("$(wildcard $(USER_PATH)/post_config.h)","") endif # Disable features that a keyboard doesn't support --include disable_features.mk +-include $(BUILDDEFS_PATH)/disable_features.mk # Pull in post_rules.mk files from all our subfolders ifneq ("$(wildcard $(KEYBOARD_PATH_1)/post_rules.mk)","") @@ -385,10 +386,10 @@ VPATH += $(KEYBOARD_PATHS) VPATH += $(COMMON_VPATH) include common_features.mk -include generic_features.mk +include $(BUILDDEFS_PATH)/generic_features.mk include $(TMK_PATH)/protocol.mk include $(TMK_PATH)/common.mk -include bootloader.mk +include $(BUILDDEFS_PATH)/bootloader.mk SRC += $(patsubst %.c,%.clib,$(LIB_SRC)) SRC += $(patsubst %.c,%.clib,$(QUANTUM_LIB_SRC)) @@ -445,7 +446,7 @@ check-size: build check-md5: build objs-size: build -include show_options.mk +include $(BUILDDEFS_PATH)/show_options.mk include $(TMK_PATH)/rules.mk # Ensure we have generated files available for each of the objects diff --git a/build_test.mk b/build_test.mk index dd66a008ee67..8f1ff1e849b3 100644 --- a/build_test.mk +++ b/build_test.mk @@ -4,7 +4,8 @@ endif .DEFAULT_GOAL := all -include common.mk +include paths.mk +include $(BUILDDEFS_PATH)/message.mk TARGET=test/$(TEST) @@ -52,7 +53,7 @@ include tests/$(TEST)/rules.mk endif include common_features.mk -include generic_features.mk +include $(BUILDDEFS_PATH)/generic_features.mk include $(TMK_PATH)/common.mk include $(QUANTUM_PATH)/debounce/tests/rules.mk include $(QUANTUM_PATH)/sequencer/tests/rules.mk diff --git a/bootloader.mk b/builddefs/bootloader.mk similarity index 100% rename from bootloader.mk rename to builddefs/bootloader.mk diff --git a/disable_features.mk b/builddefs/disable_features.mk similarity index 100% rename from disable_features.mk rename to builddefs/disable_features.mk diff --git a/generic_features.mk b/builddefs/generic_features.mk similarity index 100% rename from generic_features.mk rename to builddefs/generic_features.mk diff --git a/quantum/mcu_selection.mk b/builddefs/mcu_selection.mk similarity index 100% rename from quantum/mcu_selection.mk rename to builddefs/mcu_selection.mk diff --git a/message.mk b/builddefs/message.mk similarity index 100% rename from message.mk rename to builddefs/message.mk diff --git a/show_options.mk b/builddefs/show_options.mk similarity index 100% rename from show_options.mk rename to builddefs/show_options.mk diff --git a/common.mk b/paths.mk similarity index 91% rename from common.mk rename to paths.mk index 8acea39376e6..78eaf3996768 100644 --- a/common.mk +++ b/paths.mk @@ -1,5 +1,3 @@ -include message.mk - # Directory common source files exist TOP_DIR = . TMK_DIR = tmk_core @@ -15,6 +13,9 @@ DRIVER_PATH = $(DRIVER_DIR) PLATFORM_DIR = platforms PLATFORM_PATH = $(PLATFORM_DIR) +BUILDDEFS_DIR = builddefs +BUILDDEFS_PATH = $(BUILDDEFS_DIR) + BUILD_DIR := .build COMMON_VPATH := $(TOP_DIR) From 780e763c13052138e4d9ad379c4138c3b2c344a7 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 28 Oct 2021 02:43:51 +0100 Subject: [PATCH 0056/1136] Remove SERIAL_MOUSE (#14969) --- quantum/keyboard.c | 10 -- tmk_core/protocol.mk | 20 --- tmk_core/protocol/serial_mouse.h | 29 ----- tmk_core/protocol/serial_mouse_microsoft.c | 113 ----------------- tmk_core/protocol/serial_mouse_mousesystems.c | 119 ------------------ 5 files changed, 291 deletions(-) delete mode 100644 tmk_core/protocol/serial_mouse.h delete mode 100644 tmk_core/protocol/serial_mouse_microsoft.c delete mode 100644 tmk_core/protocol/serial_mouse_mousesystems.c diff --git a/quantum/keyboard.c b/quantum/keyboard.c index f8e36994d298..030fec2d3e99 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -40,9 +40,6 @@ along with this program. If not, see . #ifdef PS2_MOUSE_ENABLE # include "ps2_mouse.h" #endif -#ifdef SERIAL_MOUSE_ENABLE -# include "serial_mouse.h" -#endif #ifdef RGBLIGHT_ENABLE # include "rgblight.h" #endif @@ -310,9 +307,6 @@ void keyboard_init(void) { #ifdef PS2_MOUSE_ENABLE ps2_mouse_init(); #endif -#ifdef SERIAL_MOUSE_ENABLE - serial_mouse_init(); -#endif #ifdef BACKLIGHT_ENABLE backlight_init(); #endif @@ -490,10 +484,6 @@ void keyboard_task(void) { ps2_mouse_task(); #endif -#ifdef SERIAL_MOUSE_ENABLE - serial_mouse_task(); -#endif - #ifdef POINTING_DEVICE_ENABLE pointing_device_task(); #endif diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index 8aa063c9116c..d4ad50db6a75 100644 --- a/tmk_core/protocol.mk +++ b/tmk_core/protocol.mk @@ -1,25 +1,5 @@ PROTOCOL_DIR = protocol -ifeq ($(strip $(SERIAL_MOUSE_MICROSOFT_ENABLE)), yes) - SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c - OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \ - -DMOUSE_ENABLE -endif - -ifeq ($(strip $(SERIAL_MOUSE_MOUSESYSTEMS_ENABLE)), yes) - SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c - OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \ - -DMOUSE_ENABLE -endif - -ifeq ($(strip $(SERIAL_MOUSE_USE_SOFT)), yes) - SRC += $(PROTOCOL_DIR)/serial_soft.c -endif - -ifeq ($(strip $(SERIAL_MOUSE_USE_UART)), yes) - SRC += $(PROTOCOL_DIR)/serial_uart.c -endif - ifeq ($(strip $(USB_HID_ENABLE)), yes) include $(TMK_DIR)/protocol/usb_hid.mk endif diff --git a/tmk_core/protocol/serial_mouse.h b/tmk_core/protocol/serial_mouse.h deleted file mode 100644 index cb83cf4f6221..000000000000 --- a/tmk_core/protocol/serial_mouse.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright 2014 Robin Haberkorn - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#pragma once - -#include - -#include "serial.h" - -static inline uint8_t serial_mouse_init(void) { - serial_init(); - return 0; -} - -void serial_mouse_task(void); diff --git a/tmk_core/protocol/serial_mouse_microsoft.c b/tmk_core/protocol/serial_mouse_microsoft.c deleted file mode 100644 index eff0bf6e45f8..000000000000 --- a/tmk_core/protocol/serial_mouse_microsoft.c +++ /dev/null @@ -1,113 +0,0 @@ -/* -Copyright 2014 Robin Haberkorn - -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 . -*/ - -#include -#include -#include - -#include "serial.h" -#include "serial_mouse.h" -#include "report.h" -#include "host.h" -#include "timer.h" -#include "print.h" -#include "debug.h" - -#ifdef MAX -# undef MAX -#endif -#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) - -static void print_usb_data(const report_mouse_t *report); - -void serial_mouse_task(void) { - /* 3 byte ring buffer */ - static uint8_t buffer[3]; - static int buffer_cur = 0; - - static report_mouse_t report = {}; - - int16_t rcv; - - rcv = serial_recv2(); - if (rcv < 0) /* no new data */ - return; - - if (debug_mouse) xprintf("serial_mouse: byte: %04X\n", rcv); - - /* - * If bit 6 is one, this signals the beginning - * of a 3 byte sequence/packet. - */ - if (rcv & (1 << 6)) buffer_cur = 0; - - buffer[buffer_cur] = (uint8_t)rcv; - - if (buffer_cur == 0 && buffer[buffer_cur] == 0x20) { - /* - * Logitech extension: This must be a follow-up on - * the last 3-byte packet signaling a middle button click - */ - report.buttons |= MOUSE_BTN3; - report.x = report.y = 0; - - print_usb_data(&report); - host_mouse_send(&report); - return; - } - - buffer_cur++; - - if (buffer_cur < 3) return; - buffer_cur = 0; - - /* - * parse 3 byte packet. - * NOTE: We only get a complete packet - * if the mouse moved or the button states - * change. - */ - report.buttons = 0; - if (buffer[0] & (1 << 5)) report.buttons |= MOUSE_BTN1; - if (buffer[0] & (1 << 4)) report.buttons |= MOUSE_BTN2; - - report.x = (buffer[0] << 6) | buffer[1]; - report.y = ((buffer[0] << 4) & 0xC0) | buffer[2]; - - /* USB HID uses values from -127 to 127 only */ - report.x = MAX(report.x, -127); - report.y = MAX(report.y, -127); - -#if 0 - if (!report.buttons && !report.x && !report.y) { - /* - * Microsoft extension: Middle mouse button pressed - * FIXME: I don't know how exactly this extension works. - */ - report.buttons |= MOUSE_BTN3; - } -#endif - - print_usb_data(&report); - host_mouse_send(&report); -} - -static void print_usb_data(const report_mouse_t *report) { - if (!debug_mouse) return; - - xprintf("serial_mouse usb: [%02X|%d %d %d %d]\n", report->buttons, report->x, report->y, report->v, report->h); -} diff --git a/tmk_core/protocol/serial_mouse_mousesystems.c b/tmk_core/protocol/serial_mouse_mousesystems.c deleted file mode 100644 index 0ec2b0399aab..000000000000 --- a/tmk_core/protocol/serial_mouse_mousesystems.c +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2014 Robin Haberkorn - -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 . -*/ - -#include -#include -#include - -#include "serial.h" -#include "serial_mouse.h" -#include "report.h" -#include "host.h" -#include "timer.h" -#include "print.h" -#include "debug.h" - -#ifdef MAX -# undef MAX -#endif -#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) - -//#define SERIAL_MOUSE_CENTER_SCROLL - -static void print_usb_data(const report_mouse_t *report); - -void serial_mouse_task(void) { - /* 5 byte ring buffer */ - static uint8_t buffer[5]; - static int buffer_cur = 0; - - int16_t rcv; - - report_mouse_t report = {0, 0, 0, 0, 0}; - - rcv = serial_recv2(); - if (rcv < 0) /* no new data */ - return; - - if (debug_mouse) xprintf("serial_mouse: byte: %04X\n", rcv); - - /* - * Synchronization: mouse(4) says that all - * bytes but the first one in the packet have - * bit 7 == 0, but this is untrue. - * Therefore we discard all bytes up to the - * first one with the characteristic bit pattern. - */ - if (buffer_cur == 0 && (rcv >> 3) != 0x10) return; - - buffer[buffer_cur++] = (uint8_t)rcv; - - if (buffer_cur < 5) return; - buffer_cur = 0; - -#ifdef SERIAL_MOUSE_CENTER_SCROLL - if ((buffer[0] & 0x7) == 0x5 && (buffer[1] || buffer[2])) { - /* USB HID uses only values from -127 to 127 */ - report.h = MAX((int8_t)buffer[1], -127); - report.v = MAX((int8_t)buffer[2], -127); - - print_usb_data(&report); - host_mouse_send(&report); - - if (buffer[3] || buffer[4]) { - report.h = MAX((int8_t)buffer[3], -127); - report.v = MAX((int8_t)buffer[4], -127); - - print_usb_data(&report); - host_mouse_send(&report); - } - - return; - } -#endif - - /* - * parse 5 byte packet. - * NOTE: We only get a complete packet - * if the mouse moved or the button states - * change. - */ - if (!(buffer[0] & (1 << 2))) report.buttons |= MOUSE_BTN1; - if (!(buffer[0] & (1 << 1))) report.buttons |= MOUSE_BTN3; - if (!(buffer[0] & (1 << 0))) report.buttons |= MOUSE_BTN2; - - /* USB HID uses only values from -127 to 127 */ - report.x = MAX((int8_t)buffer[1], -127); - report.y = MAX(-(int8_t)buffer[2], -127); - - print_usb_data(&report); - host_mouse_send(&report); - - if (buffer[3] || buffer[4]) { - report.x = MAX((int8_t)buffer[3], -127); - report.y = MAX(-(int8_t)buffer[4], -127); - - print_usb_data(&report); - host_mouse_send(&report); - } -} - -static void print_usb_data(const report_mouse_t *report) { - if (!debug_mouse) return; - - xprintf("serial_mouse usb: [%02X|%d %d %d %d]\n", report->buttons, report->x, report->y, report->v, report->h); -} From 0c87e2e7025140ca6105b7fec2639c78c3cd8109 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 28 Oct 2021 21:02:22 +0100 Subject: [PATCH 0057/1136] Move LTO logic from common.mk (#14973) --- keyboards/hub20/config.h | 6 ++---- keyboards/latin17rgb/config.h | 6 ++---- keyboards/latin6rgb/config.h | 6 ++---- keyboards/smallkeyboard/config.h | 6 ++---- .../thevankeyboards/minivan/keymaps/josjoha/config.h | 4 ++-- tmk_core/common.mk | 12 ------------ tmk_core/rules.mk | 9 +++++++++ 7 files changed, 19 insertions(+), 30 deletions(-) diff --git a/keyboards/hub20/config.h b/keyboards/hub20/config.h index f8e5d6be8d1d..fa78db3d9701 100644 --- a/keyboards/hub20/config.h +++ b/keyboards/hub20/config.h @@ -108,7 +108,5 @@ along with this program. If not, see . #define LOCKING_RESYNC_ENABLE /* disable these deprecated features by default */ -#ifndef LINK_TIME_OPTIMIZATION_ENABLE - #define NO_ACTION_MACRO - #define NO_ACTION_FUNCTION -#endif +#define NO_ACTION_MACRO +#define NO_ACTION_FUNCTION diff --git a/keyboards/latin17rgb/config.h b/keyboards/latin17rgb/config.h index 6a7ea8e781bb..1f52f9a651ad 100644 --- a/keyboards/latin17rgb/config.h +++ b/keyboards/latin17rgb/config.h @@ -49,10 +49,8 @@ #define DEBOUNCE 3 /* disable these deprecated features by default */ -//#ifndef LINK_TIME_OPTIMIZATION_ENABLE -//# define NO_ACTION_MACRO -//# define NO_ACTION_FUNCTION -//#endif +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION #ifdef RGB_MATRIX_ENABLE # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects diff --git a/keyboards/latin6rgb/config.h b/keyboards/latin6rgb/config.h index fa9abbea6cc1..b356ded8161d 100644 --- a/keyboards/latin6rgb/config.h +++ b/keyboards/latin6rgb/config.h @@ -50,10 +50,8 @@ #define DEBOUNCE 3 /* disable these deprecated features by default */ -//#ifndef LINK_TIME_OPTIMIZATION_ENABLE -//# define NO_ACTION_MACRO -//# define NO_ACTION_FUNCTION -//#endif +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION #ifdef RGB_MATRIX_ENABLE # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects diff --git a/keyboards/smallkeyboard/config.h b/keyboards/smallkeyboard/config.h index 24c81258c75d..a343d767ff54 100644 --- a/keyboards/smallkeyboard/config.h +++ b/keyboards/smallkeyboard/config.h @@ -50,10 +50,8 @@ #define DEBOUNCE 3 /* disable these deprecated features by default */ -//#ifndef LINK_TIME_OPTIMIZATION_ENABLE -//# define NO_ACTION_MACRO -//# define NO_ACTION_FUNCTION -//#endif +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION #ifdef RGB_MATRIX_ENABLE # define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects diff --git a/keyboards/thevankeyboards/minivan/keymaps/josjoha/config.h b/keyboards/thevankeyboards/minivan/keymaps/josjoha/config.h index 809842278484..9db4d596de65 100644 --- a/keyboards/thevankeyboards/minivan/keymaps/josjoha/config.h +++ b/keyboards/thevankeyboards/minivan/keymaps/josjoha/config.h @@ -24,7 +24,7 @@ along with this program. If not, see . // place overrides here // Some defines meant to decrease the firmware size. The firmware is otherwise over the maximum (atmega32u4) -//# ifndef LINK_TIME_OPTIMIZATION_ENABLE +//# ifndef LTO_ENABLE //Disable old style macro handling: MACRO() & action_get_macro //# define NO_ACTION_MACRO // This saves 320 bytes //disable calling of action_function() from the fn_actions array (deprecated) @@ -40,7 +40,7 @@ along with this program. If not, see . // Attempts to reduce firmware size: - //#define LINK_TIME_OPTIMIZATION_ENABLE // Did not decrease firmware size when tested on 26 Jan 2020 + //#define LTO_ENABLE // Did not decrease firmware size when tested on 26 Jan 2020 //#define NO_DEBUG //disable debugging (already defined) //#define NO_PRINT JJdisable printing/debugging using hid_listen (already defined) //#define NO_ACTION_LAYER //disable layers (obviously need layers) diff --git a/tmk_core/common.mk b/tmk_core/common.mk index f0faa2dc3e1d..ce335f0d3c28 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -100,18 +100,6 @@ ifeq ($(strip $(SHARED_EP_ENABLE)), yes) TMK_COMMON_DEFS += -DSHARED_EP_ENABLE endif -ifeq ($(strip $(LTO_ENABLE)), yes) - ifeq ($(PLATFORM),CHIBIOS) - $(info Enabling LTO on ChibiOS-targeting boards is known to have a high likelihood of failure.) - $(info If unsure, set LTO_ENABLE = no.) - endif - EXTRAFLAGS += -flto - TMK_COMMON_DEFS += -DLTO_ENABLE - TMK_COMMON_DEFS += -DLINK_TIME_OPTIMIZATON_ENABLE -else ifdef LINK_TIME_OPTIMIZATION_ENABLE - $(error The LINK_TIME_OPTIMIZATION_ENABLE flag has been renamed to LTO_ENABLE.) -endif - # Search Path VPATH += $(TMK_PATH)/$(COMMON_DIR) VPATH += $(TMK_PATH)/$(PLATFORM_COMMON_DIR) diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index 56a331e28827..b17f85d375e5 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -82,6 +82,15 @@ endif # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. # -adhlns...: create assembler listing +ifeq ($(strip $(LTO_ENABLE)), yes) + ifeq ($(PLATFORM),CHIBIOS) + $(info Enabling LTO on ChibiOS-targeting boards is known to have a high likelihood of failure.) + $(info If unsure, set LTO_ENABLE = no.) + endif + CDEFS += -flto + CDEFS += -DLTO_ENABLE +endif + DEBUG_ENABLE ?= yes ifeq ($(strip $(SKIP_DEBUG_INFO)),yes) DEBUG_ENABLE=no From dcfffa7b67a072f7d9e37bd8c0029c53b61aeb0f Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 28 Oct 2021 22:31:59 +0100 Subject: [PATCH 0058/1136] Relocate protocol files within tmk_core/common/ (#14972) * Relocate non platform files within tmk_core/common/ * clang --- common_features.mk | 2 +- quantum/keyboard.c | 3 +++ {tmk_core/common => quantum}/raw_hid.h | 0 {tmk_core/common => quantum}/sync_timer.c | 0 {tmk_core/common => quantum}/sync_timer.h | 0 {tmk_core/common => quantum}/virtser.h | 2 ++ tmk_core/common.mk | 4 ---- tmk_core/protocol.mk | 6 ++++++ tmk_core/{common => protocol}/host.c | 0 tmk_core/{common => protocol}/host.h | 0 tmk_core/{common => protocol}/host_driver.h | 0 tmk_core/{common => protocol}/report.c | 4 ++-- tmk_core/{common => protocol}/report.h | 0 {quantum => tmk_core/protocol}/usb_device_state.c | 0 {quantum => tmk_core/protocol}/usb_device_state.h | 0 tmk_core/{common => protocol}/usb_util.c | 0 tmk_core/{common => protocol}/usb_util.h | 0 17 files changed, 14 insertions(+), 7 deletions(-) rename {tmk_core/common => quantum}/raw_hid.h (100%) rename {tmk_core/common => quantum}/sync_timer.c (100%) rename {tmk_core/common => quantum}/sync_timer.h (100%) rename {tmk_core/common => quantum}/virtser.h (89%) rename tmk_core/{common => protocol}/host.c (100%) rename tmk_core/{common => protocol}/host.h (100%) rename tmk_core/{common => protocol}/host_driver.h (100%) rename tmk_core/{common => protocol}/report.c (99%) rename tmk_core/{common => protocol}/report.h (100%) rename {quantum => tmk_core/protocol}/usb_device_state.c (100%) rename {quantum => tmk_core/protocol}/usb_device_state.h (100%) rename tmk_core/{common => protocol}/usb_util.c (100%) rename tmk_core/{common => protocol}/usb_util.h (100%) diff --git a/common_features.mk b/common_features.mk index af538b696f71..1d7e955cdfea 100644 --- a/common_features.mk +++ b/common_features.mk @@ -27,7 +27,7 @@ QUANTUM_SRC += \ $(QUANTUM_DIR)/keyboard.c \ $(QUANTUM_DIR)/keymap_common.c \ $(QUANTUM_DIR)/keycode_config.c \ - $(QUANTUM_DIR)/usb_device_state.c \ + $(QUANTUM_DIR)/sync_timer.c \ $(QUANTUM_DIR)/logging/debug.c \ $(QUANTUM_DIR)/logging/sendchar.c \ diff --git a/quantum/keyboard.c b/quantum/keyboard.c index 030fec2d3e99..806e4ef7e800 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -94,6 +94,9 @@ along with this program. If not, see . #ifdef DIGITIZER_ENABLE # include "digitizer.h" #endif +#ifdef VIRTSER_ENABLE +# include "virtser.h" +#endif static uint32_t last_input_modification_time = 0; uint32_t last_input_activity_time(void) { return last_input_modification_time; } diff --git a/tmk_core/common/raw_hid.h b/quantum/raw_hid.h similarity index 100% rename from tmk_core/common/raw_hid.h rename to quantum/raw_hid.h diff --git a/tmk_core/common/sync_timer.c b/quantum/sync_timer.c similarity index 100% rename from tmk_core/common/sync_timer.c rename to quantum/sync_timer.c diff --git a/tmk_core/common/sync_timer.h b/quantum/sync_timer.h similarity index 100% rename from tmk_core/common/sync_timer.h rename to quantum/sync_timer.h diff --git a/tmk_core/common/virtser.h b/quantum/virtser.h similarity index 89% rename from tmk_core/common/virtser.h rename to quantum/virtser.h index a0645f9e03ea..df7e87984c80 100644 --- a/tmk_core/common/virtser.h +++ b/quantum/virtser.h @@ -1,5 +1,7 @@ #pragma once +void virtser_init(void); + /* Define this function in your code to process incoming bytes */ void virtser_recv(const uint8_t ch); diff --git a/tmk_core/common.mk b/tmk_core/common.mk index ce335f0d3c28..8fa1a31e803f 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -2,10 +2,6 @@ COMMON_DIR = common PLATFORM_COMMON_DIR = $(COMMON_DIR)/$(PLATFORM_KEY) TMK_COMMON_SRC += \ - $(COMMON_DIR)/host.c \ - $(COMMON_DIR)/report.c \ - $(COMMON_DIR)/sync_timer.c \ - $(COMMON_DIR)/usb_util.c \ $(PLATFORM_COMMON_DIR)/platform.c \ $(PLATFORM_COMMON_DIR)/suspend.c \ $(PLATFORM_COMMON_DIR)/timer.c \ diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index d4ad50db6a75..359ddbfef1bf 100644 --- a/tmk_core/protocol.mk +++ b/tmk_core/protocol.mk @@ -1,5 +1,11 @@ PROTOCOL_DIR = protocol +TMK_COMMON_SRC += \ + $(PROTOCOL_DIR)/host.c \ + $(PROTOCOL_DIR)/report.c \ + $(PROTOCOL_DIR)/usb_device_state.c \ + $(PROTOCOL_DIR)/usb_util.c \ + ifeq ($(strip $(USB_HID_ENABLE)), yes) include $(TMK_DIR)/protocol/usb_hid.mk endif diff --git a/tmk_core/common/host.c b/tmk_core/protocol/host.c similarity index 100% rename from tmk_core/common/host.c rename to tmk_core/protocol/host.c diff --git a/tmk_core/common/host.h b/tmk_core/protocol/host.h similarity index 100% rename from tmk_core/common/host.h rename to tmk_core/protocol/host.h diff --git a/tmk_core/common/host_driver.h b/tmk_core/protocol/host_driver.h similarity index 100% rename from tmk_core/common/host_driver.h rename to tmk_core/protocol/host_driver.h diff --git a/tmk_core/common/report.c b/tmk_core/protocol/report.c similarity index 99% rename from tmk_core/common/report.c rename to tmk_core/protocol/report.c index 2a7fc006c436..854b59ae4817 100644 --- a/tmk_core/common/report.c +++ b/tmk_core/protocol/report.c @@ -24,8 +24,8 @@ #ifdef RING_BUFFERED_6KRO_REPORT_ENABLE # define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS) # define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS) -# define RO_INC(a) RO_ADD(a, 1) -# define RO_DEC(a) RO_SUB(a, 1) +# define RO_INC(a) RO_ADD(a, 1) +# define RO_DEC(a) RO_SUB(a, 1) static int8_t cb_head = 0; static int8_t cb_tail = 0; static int8_t cb_count = 0; diff --git a/tmk_core/common/report.h b/tmk_core/protocol/report.h similarity index 100% rename from tmk_core/common/report.h rename to tmk_core/protocol/report.h diff --git a/quantum/usb_device_state.c b/tmk_core/protocol/usb_device_state.c similarity index 100% rename from quantum/usb_device_state.c rename to tmk_core/protocol/usb_device_state.c diff --git a/quantum/usb_device_state.h b/tmk_core/protocol/usb_device_state.h similarity index 100% rename from quantum/usb_device_state.h rename to tmk_core/protocol/usb_device_state.h diff --git a/tmk_core/common/usb_util.c b/tmk_core/protocol/usb_util.c similarity index 100% rename from tmk_core/common/usb_util.c rename to tmk_core/protocol/usb_util.c diff --git a/tmk_core/common/usb_util.h b/tmk_core/protocol/usb_util.h similarity index 100% rename from tmk_core/common/usb_util.h rename to tmk_core/protocol/usb_util.h From 0f9261424097863d23b6f4835dd3f374c6776ec7 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Thu, 28 Oct 2021 23:43:57 +0100 Subject: [PATCH 0059/1136] Fix develop after recent changes (#14975) * Fix sleep led issues * Fix tests --- build_test.mk | 1 + quantum/keyboard.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/build_test.mk b/build_test.mk index 8f1ff1e849b3..6e4494d77f5c 100644 --- a/build_test.mk +++ b/build_test.mk @@ -55,6 +55,7 @@ endif include common_features.mk include $(BUILDDEFS_PATH)/generic_features.mk include $(TMK_PATH)/common.mk +include $(TMK_PATH)/protocol.mk include $(QUANTUM_PATH)/debounce/tests/rules.mk include $(QUANTUM_PATH)/sequencer/tests/rules.mk include $(TMK_PATH)/common/test/rules.mk diff --git a/quantum/keyboard.c b/quantum/keyboard.c index 806e4ef7e800..3bca05aab7cf 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -97,6 +97,9 @@ along with this program. If not, see . #ifdef VIRTSER_ENABLE # include "virtser.h" #endif +#ifdef SLEEP_LED_ENABLE +# include "sleep_led.h" +#endif static uint32_t last_input_modification_time = 0; uint32_t last_input_activity_time(void) { return last_input_modification_time; } From 55fb468d7453eb31bc1793772938e2d28881fcaa Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Fri, 29 Oct 2021 11:16:19 +0100 Subject: [PATCH 0060/1136] More platform/protocol alignment (#14976) --- builddefs/generic_features.mk | 1 + common_features.mk | 7 +++ tmk_core/common.mk | 86 ----------------------------------- tmk_core/protocol.mk | 76 +++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 86 deletions(-) diff --git a/builddefs/generic_features.mk b/builddefs/generic_features.mk index ff02d56bbe0a..2281a82917e6 100644 --- a/builddefs/generic_features.mk +++ b/builddefs/generic_features.mk @@ -31,6 +31,7 @@ GENERIC_FEATURES = \ LEADER \ PROGRAMMABLE_BUTTON \ SPACE_CADET \ + SWAP_HANDS \ TAP_DANCE \ VELOCIKEY \ WPM \ diff --git a/common_features.mk b/common_features.mk index 1d7e955cdfea..0d6b86b1ef3e 100644 --- a/common_features.mk +++ b/common_features.mk @@ -326,6 +326,13 @@ ifneq ($(strip $(VARIABLE_TRACE)),no) endif endif +ifeq ($(strip $(SLEEP_LED_ENABLE)), yes) + SRC += $(PLATFORM_COMMON_DIR)/sleep_led.c + OPT_DEFS += -DSLEEP_LED_ENABLE + + NO_SUSPEND_POWER_DOWN := yes +endif + VALID_BACKLIGHT_TYPES := pwm timer software custom BACKLIGHT_ENABLE ?= no diff --git a/tmk_core/common.mk b/tmk_core/common.mk index 8fa1a31e803f..555b942c9da7 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -10,92 +10,6 @@ TMK_COMMON_SRC += \ # Use platform provided print if it exists -include $(TMK_PATH)/$(PLATFORM_COMMON_DIR)/printf.mk -SHARED_EP_ENABLE = no -MOUSE_SHARED_EP ?= yes -ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes) - TMK_COMMON_DEFS += -DKEYBOARD_SHARED_EP - SHARED_EP_ENABLE = yes - # With the current usb_descriptor.c code, - # you can't share kbd without sharing mouse; - # that would be a very unexpected use case anyway - MOUSE_SHARED_EP = yes -endif - -ifeq ($(strip $(MOUSE_ENABLE)), yes) - OPT_DEFS += -DMOUSE_ENABLE - ifeq ($(strip $(MOUSE_SHARED_EP)), yes) - TMK_COMMON_DEFS += -DMOUSE_SHARED_EP - SHARED_EP_ENABLE = yes - endif -endif - -ifeq ($(strip $(EXTRAKEY_ENABLE)), yes) - TMK_COMMON_DEFS += -DEXTRAKEY_ENABLE - SHARED_EP_ENABLE = yes -endif - -ifeq ($(strip $(RAW_ENABLE)), yes) - TMK_COMMON_DEFS += -DRAW_ENABLE -endif - -ifeq ($(strip $(CONSOLE_ENABLE)), yes) - TMK_COMMON_DEFS += -DCONSOLE_ENABLE -else - # TODO: decouple this so other print backends can exist - TMK_COMMON_DEFS += -DNO_PRINT - TMK_COMMON_DEFS += -DNO_DEBUG -endif - -ifeq ($(strip $(NKRO_ENABLE)), yes) - ifeq ($(PROTOCOL), VUSB) - $(info NKRO is not currently supported on V-USB, and has been disabled.) - else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) - $(info NKRO is not currently supported with Bluetooth, and has been disabled.) - else - TMK_COMMON_DEFS += -DNKRO_ENABLE - SHARED_EP_ENABLE = yes - endif -endif - -ifeq ($(strip $(RING_BUFFERED_6KRO_REPORT_ENABLE)), yes) - TMK_COMMON_DEFS += -DRING_BUFFERED_6KRO_REPORT_ENABLE -endif - -ifeq ($(strip $(SLEEP_LED_ENABLE)), yes) - TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/sleep_led.c - TMK_COMMON_DEFS += -DSLEEP_LED_ENABLE - TMK_COMMON_DEFS += -DNO_SUSPEND_POWER_DOWN -endif - -ifeq ($(strip $(NO_SUSPEND_POWER_DOWN)), yes) - TMK_COMMON_DEFS += -DNO_SUSPEND_POWER_DOWN -endif - -ifeq ($(strip $(SWAP_HANDS_ENABLE)), yes) - TMK_COMMON_DEFS += -DSWAP_HANDS_ENABLE -endif - -ifeq ($(strip $(NO_USB_STARTUP_CHECK)), yes) - TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK -endif - -ifeq ($(strip $(DIGITIZER_SHARED_EP)), yes) - TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP - SHARED_EP_ENABLE = yes -endif - -ifeq ($(strip $(DIGITIZER_ENABLE)), yes) - TMK_COMMON_DEFS += -DDIGITIZER_ENABLE - ifeq ($(strip $(SHARED_EP_ENABLE)), yes) - TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP - SHARED_EP_ENABLE = yes - endif -endif - -ifeq ($(strip $(SHARED_EP_ENABLE)), yes) - TMK_COMMON_DEFS += -DSHARED_EP_ENABLE -endif - # Search Path VPATH += $(TMK_PATH)/$(COMMON_DIR) VPATH += $(TMK_PATH)/$(PLATFORM_COMMON_DIR) diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk index 359ddbfef1bf..a8723e6b2e44 100644 --- a/tmk_core/protocol.mk +++ b/tmk_core/protocol.mk @@ -6,6 +6,82 @@ TMK_COMMON_SRC += \ $(PROTOCOL_DIR)/usb_device_state.c \ $(PROTOCOL_DIR)/usb_util.c \ +SHARED_EP_ENABLE = no +MOUSE_SHARED_EP ?= yes +ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes) + TMK_COMMON_DEFS += -DKEYBOARD_SHARED_EP + SHARED_EP_ENABLE = yes + # With the current usb_descriptor.c code, + # you can't share kbd without sharing mouse; + # that would be a very unexpected use case anyway + MOUSE_SHARED_EP = yes +endif + +ifeq ($(strip $(MOUSE_ENABLE)), yes) + OPT_DEFS += -DMOUSE_ENABLE + ifeq ($(strip $(MOUSE_SHARED_EP)), yes) + TMK_COMMON_DEFS += -DMOUSE_SHARED_EP + SHARED_EP_ENABLE = yes + endif +endif + +ifeq ($(strip $(EXTRAKEY_ENABLE)), yes) + TMK_COMMON_DEFS += -DEXTRAKEY_ENABLE + SHARED_EP_ENABLE = yes +endif + +ifeq ($(strip $(RAW_ENABLE)), yes) + TMK_COMMON_DEFS += -DRAW_ENABLE +endif + +ifeq ($(strip $(CONSOLE_ENABLE)), yes) + TMK_COMMON_DEFS += -DCONSOLE_ENABLE +else + # TODO: decouple this so other print backends can exist + TMK_COMMON_DEFS += -DNO_PRINT + TMK_COMMON_DEFS += -DNO_DEBUG +endif + +ifeq ($(strip $(NKRO_ENABLE)), yes) + ifeq ($(PROTOCOL), VUSB) + $(info NKRO is not currently supported on V-USB, and has been disabled.) + else ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) + $(info NKRO is not currently supported with Bluetooth, and has been disabled.) + else + TMK_COMMON_DEFS += -DNKRO_ENABLE + SHARED_EP_ENABLE = yes + endif +endif + +ifeq ($(strip $(RING_BUFFERED_6KRO_REPORT_ENABLE)), yes) + TMK_COMMON_DEFS += -DRING_BUFFERED_6KRO_REPORT_ENABLE +endif + +ifeq ($(strip $(NO_SUSPEND_POWER_DOWN)), yes) + TMK_COMMON_DEFS += -DNO_SUSPEND_POWER_DOWN +endif + +ifeq ($(strip $(NO_USB_STARTUP_CHECK)), yes) + TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK +endif + +ifeq ($(strip $(DIGITIZER_SHARED_EP)), yes) + TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP + SHARED_EP_ENABLE = yes +endif + +ifeq ($(strip $(DIGITIZER_ENABLE)), yes) + TMK_COMMON_DEFS += -DDIGITIZER_ENABLE + ifeq ($(strip $(SHARED_EP_ENABLE)), yes) + TMK_COMMON_DEFS += -DDIGITIZER_SHARED_EP + SHARED_EP_ENABLE = yes + endif +endif + +ifeq ($(strip $(SHARED_EP_ENABLE)), yes) + TMK_COMMON_DEFS += -DSHARED_EP_ENABLE +endif + ifeq ($(strip $(USB_HID_ENABLE)), yes) include $(TMK_DIR)/protocol/usb_hid.mk endif From 736d9fa5384977159abf55b72251c93a5dba8356 Mon Sep 17 00:00:00 2001 From: just-another-jxliu Date: Fri, 29 Oct 2021 13:11:48 -0700 Subject: [PATCH 0061/1136] Stop-gap forward-port Drop LED features for CTRL and ALT (#14967) --- keyboards/massdrop/alt/config_led.h | 37 ++++---- .../massdrop/alt/keymaps/default_md/keymap.c | 87 +++++++++++++++++- .../massdrop/alt/keymaps/mac_md/keymap.c | 87 +++++++++++++++++- keyboards/massdrop/ctrl/config_led.h | 34 +++---- .../massdrop/ctrl/keymaps/default_md/keymap.c | 91 +++++++++++++++++-- .../massdrop/ctrl/keymaps/mac_md/keymap.c | 87 +++++++++++++++++- tmk_core/protocol/arm_atsam/md_rgb_matrix.c | 48 +++++++++- tmk_core/protocol/arm_atsam/md_rgb_matrix.h | 21 +++++ 8 files changed, 430 insertions(+), 62 deletions(-) diff --git a/keyboards/massdrop/alt/config_led.h b/keyboards/massdrop/alt/config_led.h index 82117b33279e..b600dd23b98f 100644 --- a/keyboards/massdrop/alt/config_led.h +++ b/keyboards/massdrop/alt/config_led.h @@ -58,7 +58,7 @@ along with this program. If not, see . //swr: Matrix wiring SW Red row (1-12) //swg: Matrix wiring SW Green row (1-12) //swb: Matrix wiring SW Blue row (1-12) -//scan: Associated key scancode if any +//scan: Associated key matrix scancode (set 255 if none or 254 for LED to turn off in alternating mode) //Note: Origin 0,0 may be located anywhere as the software will do the final layout #define ISSI3733_LED_MAP { \ { .id = 1, .x = 0, .y = 0, .adr = { .drv = 2, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 0 }, \ @@ -129,46 +129,45 @@ along with this program. If not, see . { .id = 66, .x = 10.5, .y = -3, .adr = { .drv = 1, .cs = 12, .swr = 8, .swg = 7, .swb = 9 }, .scan = 73 }, \ { .id = 67, .x = 11.25, .y = -3, .adr = { .drv = 1, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 74 }, \ { .id = 68, .x = -0.338, .y = -3.338, .adr = { .drv = 2, .cs = 11, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 69, .x = 0.39, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 69, .x = 0.39, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 70, .x = 1.263, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ - { .id = 71, .x = 2.135, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 71, .x = 2.135, .y = -3.443, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 72, .x = 3.008, .y = -3.443, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 73, .x = 3.88, .y = -3.443, .adr = { .drv = 2, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 73, .x = 3.88, .y = -3.443, .adr = { .drv = 2, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 74, .x = 4.753, .y = -3.443, .adr = { .drv = 2, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ - { .id = 75, .x = 5.625, .y = -3.443, .adr = { .drv = 2, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 75, .x = 5.625, .y = -3.443, .adr = { .drv = 2, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 76, .x = 6.497, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ - { .id = 77, .x = 7.37, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 77, .x = 7.37, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 78, .x = 8.242, .y = -3.443, .adr = { .drv = 1, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 79, .x = 9.115, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 79, .x = 9.115, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 80, .x = 9.987, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ - { .id = 81, .x = 10.86, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 81, .x = 10.86, .y = -3.443, .adr = { .drv = 1, .cs = 13, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 82, .x = 11.588, .y = -3.338, .adr = { .drv = 1, .cs = 13, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 83, .x = 11.693, .y = -2.623, .adr = { .drv = 1, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 83, .x = 11.693, .y = -2.623, .adr = { .drv = 1, .cs = 12, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ { .id = 84, .x = 11.693, .y = -1.873, .adr = { .drv = 1, .cs = 8, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ { .id = 85, .x = 11.693, .y = -1.123, .adr = { .drv = 1, .cs = 8, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ - { .id = 86, .x = 11.693, .y = -0.373, .adr = { .drv = 1, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 86, .x = 11.693, .y = -0.373, .adr = { .drv = 1, .cs = 8, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 87, .x = 11.588, .y = 0.338, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ { .id = 88, .x = 9.908, .y = 0.443, .adr = { .drv = 1, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 89, .x = 9.288, .y = 0.443, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 89, .x = 9.288, .y = 0.443, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 90, .x = 8.625, .y = 0.443, .adr = { .drv = 1, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 91, .x = 7.875, .y = 0.443, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 91, .x = 7.875, .y = 0.443, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 92, .x = 7.125, .y = 0.443, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 93, .x = 6.375, .y = 0.443, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 93, .x = 6.375, .y = 0.443, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 94, .x = 5.625, .y = 0.443, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 95, .x = 4.875, .y = 0.443, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 95, .x = 4.875, .y = 0.443, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 96, .x = 4.125, .y = 0.443, .adr = { .drv = 2, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 97, .x = 3.375, .y = 0.443, .adr = { .drv = 2, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 97, .x = 3.375, .y = 0.443, .adr = { .drv = 2, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 98, .x = 2.625, .y = 0.443, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 99, .x = 1.875, .y = 0.443, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 99, .x = 1.875, .y = 0.443, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 100, .x = 1.125, .y = 0.443, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ { .id = 101, .x = -0.338, .y = 0.338, .adr = { .drv = 2, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 102, .x = -0.443, .y = -0.373, .adr = { .drv = 2, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 102, .x = -0.443, .y = -0.373, .adr = { .drv = 2, .cs = 1, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ { .id = 103, .x = -0.443, .y = -1.123, .adr = { .drv = 2, .cs = 1, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ { .id = 104, .x = -0.443, .y = -1.873, .adr = { .drv = 2, .cs = 1, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 105, .x = -0.443, .y = -2.623, .adr = { .drv = 2, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 105, .x = -0.443, .y = -2.623, .adr = { .drv = 2, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ }; - #define USB_LED_INDICATOR_ENABLE //Comment out to disable indicator functionality #ifdef USB_LED_INDICATOR_ENABLE //Scan codes refer to actual key matrix codes, not KC_* (255 to disable) #define USB_LED_NUM_LOCK_SCANCODE 255 diff --git a/keyboards/massdrop/alt/keymaps/default_md/keymap.c b/keyboards/massdrop/alt/keymaps/default_md/keymap.c index 810585a3df47..5bd543ed63f4 100644 --- a/keyboards/massdrop/alt/keymaps/default_md/keymap.c +++ b/keyboards/massdrop/alt/keymaps/default_md/keymap.c @@ -3,10 +3,15 @@ enum alt_keycodes { L_BRI = SAFE_RANGE, //LED Brightness Increase //Working L_BRD, //LED Brightness Decrease //Working + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode L_PTN, //LED Pattern Select Next //Working L_PTP, //LED Pattern Select Previous //Working L_PSI, //LED Pattern Speed Increase //Working L_PSD, //LED Pattern Speed Decrease //Working + L_RATIOD, + L_RATIOI, L_T_MD, //LED Toggle Mode //Working L_T_ONF, //LED Toggle On / Off //Broken L_ON, //LED On //Broken @@ -18,6 +23,7 @@ enum alt_keycodes { DBG_MTRX, //DEBUG Toggle Matrix Prints // DBG_KBD, //DEBUG Toggle Keyboard Prints // DBG_MOU, //DEBUG Toggle Mouse Prints // + DBG_FAC, //DEBUG Factory light testing (All on white) MD_BOOT //Restart into bootloader after hold timeout //Working }; @@ -31,10 +37,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ - _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ + _______, _______, _______, DBG_FAC, _______, _______, KC_HOME, KC_PGDN, KC_END \ ), /* [X] = LAYOUT( @@ -53,6 +59,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -69,6 +76,38 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_RATIOI: + if (record->event.pressed) { + led_ratio_brightness += 0.2; + if (led_ratio_brightness > 2.0) { led_ratio_brightness = 2.0; } + } + return false; + case L_RATIOD: + if (record->event.pressed) { + led_ratio_brightness -= 0.2; + if (led_ratio_brightness < 0.0) { led_ratio_brightness = 0.0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -128,7 +167,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -136,6 +201,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/keyboards/massdrop/alt/keymaps/mac_md/keymap.c b/keyboards/massdrop/alt/keymaps/mac_md/keymap.c index b3626c1b6113..bfcadf890026 100644 --- a/keyboards/massdrop/alt/keymaps/mac_md/keymap.c +++ b/keyboards/massdrop/alt/keymaps/mac_md/keymap.c @@ -3,10 +3,15 @@ enum alt_keycodes { L_BRI = SAFE_RANGE, //LED Brightness Increase //Working L_BRD, //LED Brightness Decrease //Working + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode L_PTN, //LED Pattern Select Next //Working L_PTP, //LED Pattern Select Previous //Working L_PSI, //LED Pattern Speed Increase //Working L_PSD, //LED Pattern Speed Decrease //Working + L_RATIOD, + L_RATIOI, L_T_MD, //LED Toggle Mode //Working L_T_ONF, //LED Toggle On / Off //Broken L_ON, //LED On //Broken @@ -18,6 +23,7 @@ enum alt_keycodes { DBG_MTRX, //DEBUG Toggle Matrix Prints // DBG_KBD, //DEBUG Toggle Keyboard Prints // DBG_MOU, //DEBUG Toggle Mouse Prints // + DBG_FAC, //DEBUG Factory light testing (All on white) MD_BOOT //Restart into bootloader after hold timeout //Working }; @@ -31,10 +37,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_MUTE, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ - _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_END \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, KC_PSCR, KC_SLCK, KC_PAUS, _______, KC_END, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, KC_VOLU, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, KC_PGUP, KC_VOLD, \ + _______, _______, _______, DBG_FAC, _______, _______, KC_HOME, KC_PGDN, KC_END \ ), /* [X] = LAYOUT( @@ -53,6 +59,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -69,6 +76,38 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_RATIOI: + if (record->event.pressed) { + led_ratio_brightness += 0.2; + if (led_ratio_brightness > 2.0) { led_ratio_brightness = 2.0; } + } + return false; + case L_RATIOD: + if (record->event.pressed) { + led_ratio_brightness -= 0.2; + if (led_ratio_brightness < 0.0) { led_ratio_brightness = 0.0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -128,7 +167,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -136,6 +201,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/keyboards/massdrop/ctrl/config_led.h b/keyboards/massdrop/ctrl/config_led.h index 0c91a0c80baf..de897ce1bd95 100644 --- a/keyboards/massdrop/ctrl/config_led.h +++ b/keyboards/massdrop/ctrl/config_led.h @@ -58,7 +58,7 @@ along with this program. If not, see . //swr: Matrix wiring SW Red row (1-12) //swg: Matrix wiring SW Green row (1-12) //swb: Matrix wiring SW Blue row (1-12) -//scan: Associated key scancode if any +//scan: Associated key matrix scancode (set 255 if none or 254 for LED to turn off in alternating mode) //Note: Origin 0,0 may be located anywhere as the software will do the final layout #define ISSI3733_LED_MAP { \ { .id = 1, .x = 0, .y = 0, .adr = { .drv = 2, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 0 }, \ @@ -149,37 +149,37 @@ along with this program. If not, see . { .id = 86, .x = 12.375, .y = -4.125, .adr = { .drv = 1, .cs = 12, .swr = 5, .swg = 4, .swb = 6 }, .scan = 85 }, \ { .id = 87, .x = 13.125, .y = -4.125, .adr = { .drv = 1, .cs = 11, .swr = 5, .swg = 4, .swb = 6 }, .scan = 86 }, \ { .id = 88, .x = 13.433, .y = -4.43, .adr = { .drv = 1, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 89, .x = 12.285, .y = -4.535, .adr = { .drv = 1, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 89, .x = 12.285, .y = -4.535, .adr = { .drv = 1, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 90, .x = 11.14, .y = -4.535, .adr = { .drv = 1, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 91, .x = 9.995, .y = -4.535, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 91, .x = 9.995, .y = -4.535, .adr = { .drv = 1, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 92, .x = 8.85, .y = -4.535, .adr = { .drv = 1, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 93, .x = 7.705, .y = -4.535, .adr = { .drv = 1, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 93, .x = 7.705, .y = -4.535, .adr = { .drv = 1, .cs = 16, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 94, .x = 6.56, .y = -4.535, .adr = { .drv = 2, .cs = 9, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 95, .x = 5.415, .y = -4.535, .adr = { .drv = 2, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 95, .x = 5.415, .y = -4.535, .adr = { .drv = 2, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 96, .x = 4.27, .y = -4.535, .adr = { .drv = 2, .cs = 11, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 97, .x = 3.125, .y = -4.535, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 97, .x = 3.125, .y = -4.535, .adr = { .drv = 2, .cs = 12, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 98, .x = 1.98, .y = -4.535, .adr = { .drv = 2, .cs = 13, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 99, .x = 0.835, .y = -4.535, .adr = { .drv = 2, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 99, .x = 0.835, .y = -4.535, .adr = { .drv = 2, .cs = 14, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 100, .x = -0.307, .y = -4.43, .adr = { .drv = 2, .cs = 15, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 101, .x = -0.41, .y = -3.245, .adr = { .drv = 2, .cs = 15, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ + { .id = 101, .x = -0.41, .y = -3.245, .adr = { .drv = 2, .cs = 15, .swr = 11, .swg = 10, .swb = 12 }, .scan = 254 }, \ { .id = 102, .x = -0.41, .y = -2.06, .adr = { .drv = 2, .cs = 15, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ - { .id = 103, .x = -0.41, .y = -0.875, .adr = { .drv = 2, .cs = 15, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 103, .x = -0.41, .y = -0.875, .adr = { .drv = 2, .cs = 15, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 104, .x = -0.308, .y = 0.31, .adr = { .drv = 2, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 105, .x = 0.835, .y = 0.415, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 105, .x = 0.835, .y = 0.415, .adr = { .drv = 2, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 106, .x = 1.98, .y = 0.415, .adr = { .drv = 2, .cs = 4, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 107, .x = 3.125, .y = 0.415, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 107, .x = 3.125, .y = 0.415, .adr = { .drv = 2, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 108, .x = 4.27, .y = 0.415, .adr = { .drv = 2, .cs = 7, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 109, .x = 5.415, .y = 0.415, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 109, .x = 5.415, .y = 0.415, .adr = { .drv = 2, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 110, .x = 6.56, .y = 0.415, .adr = { .drv = 1, .cs = 1, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 111, .x = 7.705, .y = 0.415, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 111, .x = 7.705, .y = 0.415, .adr = { .drv = 1, .cs = 2, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 112, .x = 8.85, .y = 0.415, .adr = { .drv = 1, .cs = 3, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 113, .x = 9.995, .y = 0.415, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 113, .x = 9.995, .y = 0.415, .adr = { .drv = 1, .cs = 5, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 114, .x = 11.14, .y = 0.415, .adr = { .drv = 1, .cs = 6, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 115, .x = 12.285, .y = 0.415, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ + { .id = 115, .x = 12.285, .y = 0.415, .adr = { .drv = 1, .cs = 8, .swr = 2, .swg = 1, .swb = 3 }, .scan = 254 }, \ { .id = 116, .x = 13.432, .y = 0.31, .adr = { .drv = 1, .cs = 10, .swr = 2, .swg = 1, .swb = 3 }, .scan = 255 }, \ - { .id = 117, .x = 13.535, .y = -0.875, .adr = { .drv = 1, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 255 }, \ + { .id = 117, .x = 13.535, .y = -0.875, .adr = { .drv = 1, .cs = 10, .swr = 8, .swg = 7, .swb = 9 }, .scan = 254 }, \ { .id = 118, .x = 13.535, .y = -2.06, .adr = { .drv = 1, .cs = 10, .swr = 11, .swg = 10, .swb = 12 }, .scan = 255 }, \ - { .id = 119, .x = 13.535, .y = -3.245, .adr = { .drv = 1, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 255 }, \ + { .id = 119, .x = 13.535, .y = -3.245, .adr = { .drv = 1, .cs = 10, .swr = 5, .swg = 4, .swb = 6 }, .scan = 254 }, \ }; #define USB_LED_INDICATOR_ENABLE //Comment out to disable indicator functionality diff --git a/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c b/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c index 1083571ef948..cf4eea646d47 100644 --- a/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/default_md/keymap.c @@ -3,10 +3,15 @@ enum ctrl_keycodes { L_BRI = SAFE_RANGE, //LED Brightness Increase //Working L_BRD, //LED Brightness Decrease //Working + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode L_PTN, //LED Pattern Select Next //Working L_PTP, //LED Pattern Select Previous //Working L_PSI, //LED Pattern Speed Increase //Working L_PSD, //LED Pattern Speed Decrease //Working + L_RATIOD, + L_RATIOI, L_T_MD, //LED Toggle Mode //Working L_T_ONF, //LED Toggle On / Off //Broken L_ON, //LED On //Broken @@ -18,6 +23,7 @@ enum ctrl_keycodes { DBG_MTRX, //DEBUG Toggle Matrix Prints // DBG_KBD, //DEBUG Toggle Keyboard Prints // DBG_MOU, //DEBUG Toggle Mouse Prints // + DBG_FAC, //DEBUG Factory light testing (All on white) MD_BOOT //Restart into bootloader after hold timeout //Working }; @@ -33,10 +39,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, DBG_FAC, _______, _______, _______, _______, _______, _______, _______ \ ), /* [X] = LAYOUT( @@ -56,6 +62,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -72,6 +79,38 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_RATIOI: + if (record->event.pressed) { + led_ratio_brightness += 0.2; + if (led_ratio_brightness > 2.0) { led_ratio_brightness = 2.0; } + } + return false; + case L_RATIOD: + if (record->event.pressed) { + led_ratio_brightness -= 0.2; + if (led_ratio_brightness < 0.0) { led_ratio_brightness = 0.0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -131,7 +170,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -139,6 +204,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); @@ -179,7 +256,7 @@ led_instruction_t led_instructions[] = { //Flags can be found in tmk_core/protocol/arm_atsam/md_rgb_matrix.h (prefixed with LED_FLAG_) //LED IDs can be found in config_led.h in the keyboard's directory //Examples are below - + //All LEDs use the user's selected pattern (this is the factory default) { .flags = LED_FLAG_USE_ROTATE_PATTERN }, @@ -188,7 +265,7 @@ led_instruction_t led_instructions[] = { //Specific LEDs use specified RGB values while all others are off // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFF, .id1 = 0x00FF, .id2 = 0x0000FF00, .id3 = 0xFF000000, .r = 75, .g = 150, .b = 225 }, - + //All LEDs use the user's selected pattern //On layer 1, all key LEDs (except the top row which keeps active pattern) are red while all edge LEDs are green //When layer 1 is active, key LEDs use red (id0 32 - 17: 1111 1111 1111 1111 0000 0000 0000 0000 = 0xFFFF0000) (except top row 16 - 1) diff --git a/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c b/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c index ba02d5e506a3..4a85b375b39e 100644 --- a/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/mac_md/keymap.c @@ -3,10 +3,15 @@ enum ctrl_keycodes { L_BRI = SAFE_RANGE, //LED Brightness Increase //Working L_BRD, //LED Brightness Decrease //Working + L_EDG_I, //LED Edge Brightness Increase + L_EDG_D, //LED Edge Brightness Decrease + L_EDG_M, //LED Edge lighting mode L_PTN, //LED Pattern Select Next //Working L_PTP, //LED Pattern Select Previous //Working L_PSI, //LED Pattern Speed Increase //Working L_PSD, //LED Pattern Speed Decrease //Working + L_RATIOD, + L_RATIOI, L_T_MD, //LED Toggle Mode //Working L_T_ONF, //LED Toggle On / Off //Broken L_ON, //LED On //Broken @@ -18,6 +23,7 @@ enum ctrl_keycodes { DBG_MTRX, //DEBUG Toggle Matrix Prints // DBG_KBD, //DEBUG Toggle Keyboard Prints // DBG_MOU, //DEBUG Toggle Mouse Prints // + DBG_FAC, //DEBUG Factory light testing (All on white) MD_BOOT //Restart into bootloader after hold timeout //Working }; @@ -33,10 +39,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MPLY, KC_MSTP, KC_VOLU, \ - L_T_BR, L_PSD, L_BRI, L_PSI, _______, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ - L_T_PTD, L_PTP, L_BRD, L_PTN, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ - _______, L_T_MD, L_T_ONF, _______, _______, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, _______, \ - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \ + L_T_BR, L_PSD, L_BRI, L_PSI, L_EDG_I, _______, _______, _______, U_T_AGCR,_______, _______, _______, _______, _______, KC_MPRV, KC_MNXT, KC_VOLD, \ + L_T_PTD, L_PTP, L_BRD, L_PTN, L_EDG_D, _______, _______, _______, _______, _______, _______, _______, _______, \ + _______, L_T_MD, L_T_ONF, _______, L_EDG_M, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______, _______, \ + _______, _______, _______, DBG_FAC, _______, _______, _______, _______, _______, _______, _______ \ ), /* [X] = LAYOUT( @@ -64,6 +70,7 @@ void matrix_scan_user(void) { bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; + static uint8_t scroll_effect = 0; switch (keycode) { case L_BRI: @@ -80,6 +87,38 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; + case L_EDG_M: + if (record->event.pressed) { + led_edge_mode++; + if (led_edge_mode > LED_EDGE_MODE_MAX) { + led_edge_mode = LED_EDGE_MODE_ALL; + } + } + return false; + case L_EDG_I: + if (record->event.pressed) { + led_edge_brightness += 0.1; + if (led_edge_brightness > 1) { led_edge_brightness = 1; } + } + return false; + case L_EDG_D: + if (record->event.pressed) { + led_edge_brightness -= 0.1; + if (led_edge_brightness < 0) { led_edge_brightness = 0; } + } + return false; + case L_RATIOI: + if (record->event.pressed) { + led_ratio_brightness += 0.2; + if (led_ratio_brightness > 2.0) { led_ratio_brightness = 2.0; } + } + return false; + case L_RATIOD: + if (record->event.pressed) { + led_ratio_brightness -= 0.2; + if (led_ratio_brightness < 0.0) { led_ratio_brightness = 0.0; } + } + return false; case L_PTN: if (record->event.pressed) { if (led_animation_id == led_setups_count - 1) led_animation_id = 0; @@ -139,7 +178,33 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { return false; case L_T_PTD: if (record->event.pressed) { - led_animation_direction = !led_animation_direction; + scroll_effect++; + if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 0; + } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) + led_animation_direction = 1; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) + led_animation_direction = 0; + led_animation_orientation = 1; + led_animation_circular = 0; + } else if (scroll_effect == 4) { //Patterns with scroll explode from center + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 1; + } else if (scroll_effect == 5) { //Patterns with scroll implode on center + led_animation_direction = 1; + led_animation_orientation = 0; + led_animation_circular = 1; + } else { //Patterns with scroll move horizontal (Left to right) + scroll_effect = 0; + led_animation_direction = 0; + led_animation_orientation = 0; + led_animation_circular = 0; + } } return false; case U_T_AGCR: @@ -147,6 +212,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; + case DBG_FAC: + if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { + led_lighting_mode = LED_MODE_NORMAL; + led_edge_brightness = 1; + led_edge_mode = LED_EDGE_MODE_ALL; + led_animation_breathing = 0; + led_animation_id = 7; //led_programs.c led_setups leds_white index + gcr_desired = LED_GCR_MAX; + led_enabled = 1; + I2C3733_Control_Set(led_enabled); + } + return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c index 98967aac8862..43d9f2ee6080 100644 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.c +++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix.c @@ -341,6 +341,10 @@ uint8_t led_lighting_mode = LED_MODE_NORMAL; uint8_t led_enabled = 1; uint8_t led_animation_breathe_cur = BREATHE_MIN_STEP; uint8_t breathe_dir = 1; +uint8_t led_animation_circular = 0; +float led_edge_brightness = 1.0f; +float led_ratio_brightness = 1.0f; +uint8_t led_edge_mode = LED_EDGE_MODE_ALL; static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) { float po; @@ -398,16 +402,32 @@ static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, flo } } +# define RGB_MAX_DISTANCE 232.9635f + static void md_rgb_matrix_config_override(int i) { float ro = 0; float go = 0; float bo = 0; - - float po = (led_animation_orientation) ? (float)g_led_config.point[i].y / 64.f * 100 : (float)g_led_config.point[i].x / 224.f * 100; + float po; uint8_t highest_active_layer = biton32(layer_state); - if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { + if (led_animation_circular) { + // TODO: should use min/max values from LED configuration instead of + // hard-coded 224, 64 + // po = sqrtf((powf(fabsf((disp.width / 2) - (led_cur->x - disp.left)), 2) + powf(fabsf((disp.height / 2) - (led_cur->y - disp.bottom)), 2))) / disp.max_distance * 100; + po = sqrtf((powf(fabsf((224 / 2) - (float)g_led_config.point[i].x), 2) + powf(fabsf((64 / 2) - (float)g_led_config.point[i].y), 2))) / RGB_MAX_DISTANCE * 100; + } else { + if (led_animation_orientation) { + po = (float)g_led_config.point[i].y / 64.f * 100; + } else { + po = (float)g_led_config.point[i].x / 224.f * 100; + } + } + + if (led_edge_mode == LED_EDGE_MODE_ALTERNATE && LED_IS_EDGE_ALT(led_map[i].scan)) { + // Do not act on this LED (Edge alternate lighting mode) + } else if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { // Do not act on this LED } else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) { // Do not act on this LED @@ -465,10 +485,30 @@ static void md_rgb_matrix_config_override(int i) { } } + // Adjust edge LED brightness + if (led_edge_brightness != 1 && LED_IS_EDGE(led_map[i].scan)) { + ro *= led_edge_brightness; + go *= led_edge_brightness; + bo *= led_edge_brightness; + } + + // Adjust ratio of key vs. underglow (edge) LED brightness + if (LED_IS_EDGE(led_map[i].scan) && led_ratio_brightness > 1.0) { + // Decrease edge (underglow) LEDs + ro *= (2.0 - led_ratio_brightness); + go *= (2.0 - led_ratio_brightness); + bo *= (2.0 - led_ratio_brightness); + } else if (LED_IS_KEY(led_map[i].scan) && led_ratio_brightness < 1.0) { + // Decrease KEY LEDs + ro *= led_ratio_brightness; + go *= led_ratio_brightness; + bo *= led_ratio_brightness; + } + led_buffer[i].r = (uint8_t)ro; led_buffer[i].g = (uint8_t)go; led_buffer[i].b = (uint8_t)bo; } # endif // USE_MASSDROP_CONFIGURATOR -#endif // RGB_MATRIX_ENABLE \ No newline at end of file +#endif // RGB_MATRIX_ENABLE diff --git a/tmk_core/protocol/arm_atsam/md_rgb_matrix.h b/tmk_core/protocol/arm_atsam/md_rgb_matrix.h index 76ccaa678b53..f72dca298551 100644 --- a/tmk_core/protocol/arm_atsam/md_rgb_matrix.h +++ b/tmk_core/protocol/arm_atsam/md_rgb_matrix.h @@ -128,6 +128,8 @@ typedef struct led_instruction_s { uint32_t id1; // Bitwise id, IDs 32-63 uint32_t id2; // Bitwise id, IDs 64-95 uint32_t id3; // Bitwise id, IDs 96-127 + uint32_t id4; // Bitwise id, IDs 128-159 + uint32_t id5; // Bitwise id, IDs 160-191 uint8_t layer; uint8_t r; uint8_t g; @@ -146,6 +148,11 @@ extern uint8_t led_enabled; extern uint8_t led_animation_breathe_cur; extern uint8_t led_animation_direction; extern uint8_t breathe_dir; +extern uint8_t led_animation_orientation; +extern uint8_t led_animation_circular; +extern float led_edge_brightness; +extern float led_ratio_brightness; +extern uint8_t led_edge_mode; # define LED_MODE_NORMAL 0 // Must be 0 # define LED_MODE_KEYS_ONLY 1 @@ -153,6 +160,20 @@ extern uint8_t breathe_dir; # define LED_MODE_INDICATORS_ONLY 3 # define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY // Must be highest value +# define LED_EDGE_MODE_ALL 0 // All edge LEDs are active (Must be 0) +# define LED_EDGE_MODE_ALTERNATE 1 // Alternate mode of edge LEDs are active (Intention is for 'only every other edge LED' to be active) +# define LED_EDGE_MODE_MAX LED_EDGE_MODE_ALTERNATE // Must be the highest valued LED edge mode + +# define LED_EDGE_FULL_MODE 255 // LEDs configured with this scan code will always be on for edge lighting modes +# define LED_EDGE_ALT_MODE 254 // LEDs configured with this scan code will turn off in edge alternating mode +# define LED_EDGE_MIN_SCAN 254 // LEDs configured with scan code >= to this are assigned as edge LEDs +# define LED_INDICATOR_SCAN 253 // LEDs configured as dedicated indicators + +# define LED_IS_KEY(scan) (scan < LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a key LED +# define LED_IS_EDGE(scan) (scan >= LED_EDGE_MIN_SCAN) // Return true if an LED's scan value indicates an edge LED +# define LED_IS_EDGE_ALT(scan) (scan == LED_EDGE_ALT_MODE) // Return true if an LED's scan value indicates an alternate edge mode LED +# define LED_IS_INDICATOR(scan) (scan == LED_INDICATOR_SCAN) // Return true if an LED's scan value indicates it is a dedicated Indicator + #endif // USE_MASSDROP_CONFIGURATOR #endif //_LED_MATRIX_H_ From 70e396e8829dcdae363481af0acbd9f26a5982b1 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Fri, 29 Oct 2021 16:25:17 -0700 Subject: [PATCH 0062/1136] [Keyboard] Fix Compile issues for lefty (#14982) --- keyboards/lefty/keymaps/default/keymap.c | 31 ++++++++++++------------ keyboards/lefty/keymaps/via/keymap.c | 30 +++++++++++------------ keyboards/lefty/rev1/rules.mk | 0 keyboards/lefty/rev2/rules.mk | 0 4 files changed, 30 insertions(+), 31 deletions(-) create mode 100644 keyboards/lefty/rev1/rules.mk create mode 100644 keyboards/lefty/rev2/rules.mk diff --git a/keyboards/lefty/keymaps/default/keymap.c b/keyboards/lefty/keymaps/default/keymap.c index 0e1f56c03676..ecedbac39052 100644 --- a/keyboards/lefty/keymaps/default/keymap.c +++ b/keyboards/lefty/keymaps/default/keymap.c @@ -39,27 +39,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [_LOWER] = LAYOUT_all( - ____, ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____ + _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______ ), [_RAISE] = LAYOUT_all( - ____, ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____ + _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______ ), [_SPECIAL] = LAYOUT_all( - ____, ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____ + _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______ ) }; - diff --git a/keyboards/lefty/keymaps/via/keymap.c b/keyboards/lefty/keymaps/via/keymap.c index 764aa80c826e..5acf16c04461 100644 --- a/keyboards/lefty/keymaps/via/keymap.c +++ b/keyboards/lefty/keymaps/via/keymap.c @@ -40,26 +40,26 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [_LOWER] = LAYOUT_all( - ____, ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____ + _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______ ), [_RAISE] = LAYOUT_all( - ____, ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____ + _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______ ), [_SPECIAL] = LAYOUT_all( - ____, ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____, ____, ____, - ____, ____, ____, ____ + _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______ ) }; diff --git a/keyboards/lefty/rev1/rules.mk b/keyboards/lefty/rev1/rules.mk new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/keyboards/lefty/rev2/rules.mk b/keyboards/lefty/rev2/rules.mk new file mode 100644 index 000000000000..e69de29bb2d1 From 28120c1a63bbc64649765d9214b14e63709933aa Mon Sep 17 00:00:00 2001 From: Alan Pocklington Date: Sat, 30 Oct 2021 00:30:23 +0100 Subject: [PATCH 0063/1136] [Keymap] ajp10304: add mouse scroll keys (#14953) --- keyboards/acheron/shark/keymaps/ajp10304/readme.md | 5 ++--- keyboards/handwired/atreus50/keymaps/ajp10304/keymap.c | 10 +++++----- .../handwired/atreus50/keymaps/ajp10304/readme.md | 5 ++--- keyboards/kprepublic/jj40/keymaps/ajp10304/readme.md | 6 ++---- keyboards/planck/keymaps/ajp10304/readme.md | 6 ++---- keyboards/quark/keymaps/ajp10304/readme.md | 5 ++--- layouts/community/ortho_4x12/ajp10304/keymap.c | 10 +++++----- layouts/community/ortho_4x12/ajp10304/readme.md | 2 +- users/ajp10304/readme.md | 4 ++-- 9 files changed, 23 insertions(+), 30 deletions(-) diff --git a/keyboards/acheron/shark/keymaps/ajp10304/readme.md b/keyboards/acheron/shark/keymaps/ajp10304/readme.md index c17232162475..cb8bcdae90a5 100644 --- a/keyboards/acheron/shark/keymaps/ajp10304/readme.md +++ b/keyboards/acheron/shark/keymaps/ajp10304/readme.md @@ -7,8 +7,7 @@ the second is the output when shift is applied. **Note:** The below tables assume a UK layout. #### Flashing - -`make acheron/shark:ajp10304:flash` +Refer to the README.md of the keyboard you want to flash. ##### Main Qwerty Layer @@ -102,7 +101,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | BTN3 | | | | +| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | | | | | | | diff --git a/keyboards/handwired/atreus50/keymaps/ajp10304/keymap.c b/keyboards/handwired/atreus50/keymaps/ajp10304/keymap.c index 2b0616ad7e72..012245516774 100644 --- a/keyboards/handwired/atreus50/keymaps/ajp10304/keymap.c +++ b/keyboards/handwired/atreus50/keymaps/ajp10304/keymap.c @@ -112,7 +112,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Mouse * ,------------------------------------------ |-----------------------------------------. - * | ESC | | | | | | | | | BTN3 | | | | + * | ESC | | | | | | | WH_L | WH_UP| BTN3 | WH_D | WH_R | | * |------+------+------+------+------+------- |------+------+------+------+------+------| * | ACC0 | ACC1 | ACC2 | | | | | | BTN1 | UP | BTN2 | | | * |------+------+------+------+------+------| |------+------+------+------+------+------| @@ -122,10 +122,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-------------------------------------------------------------------------------------------------' */ [_MOUSE] = LAYOUT( - KC_ESC , _______, _______, _______, _______, _______, _______, _______, KC_MS_BTN3, _______, _______, _______ , - KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, _______, _______ , - KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, _______, _______ , - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + KC_ESC , _______, _______, _______, _______, _______, KC_MS_WH_LEFT, KC_MS_WH_UP, KC_MS_BTN3, KC_MS_WH_DOWN, KC_MS_WH_RIGHT, _______ , + KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, _______, _______ , + KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, _______, _______ , + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), diff --git a/keyboards/handwired/atreus50/keymaps/ajp10304/readme.md b/keyboards/handwired/atreus50/keymaps/ajp10304/readme.md index 4f1bac8da930..640bcc46f6c4 100644 --- a/keyboards/handwired/atreus50/keymaps/ajp10304/readme.md +++ b/keyboards/handwired/atreus50/keymaps/ajp10304/readme.md @@ -7,8 +7,7 @@ the second is the output when shift is applied. **Note:** The below tables assume a UK layout. #### Flashing - -`make handwired/atreus50:ajp10304:flash` +Refer to the README.md of the keyboard you want to flash. ##### Main Qwerty Layer @@ -102,7 +101,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | | | BTN3 | | | | +| ESC | | | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | Ctrl | Alt | | | | | | | diff --git a/keyboards/kprepublic/jj40/keymaps/ajp10304/readme.md b/keyboards/kprepublic/jj40/keymaps/ajp10304/readme.md index 7336b1994bc0..8a7562d7422a 100644 --- a/keyboards/kprepublic/jj40/keymaps/ajp10304/readme.md +++ b/keyboards/kprepublic/jj40/keymaps/ajp10304/readme.md @@ -7,9 +7,7 @@ the second is the output when shift is applied. **Note:** The below tables assume a UK layout. #### Flashing -Use sleep to get a chance to get into boot mode. - -`make jj40:ajp10304:flash` +Refer to the README.md of the keyboard you want to flash. ##### Main Qwerty Layer @@ -103,7 +101,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | BTN3 | | | | +| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | | | | | | | diff --git a/keyboards/planck/keymaps/ajp10304/readme.md b/keyboards/planck/keymaps/ajp10304/readme.md index 97f0a0093198..c68ba49283b6 100644 --- a/keyboards/planck/keymaps/ajp10304/readme.md +++ b/keyboards/planck/keymaps/ajp10304/readme.md @@ -7,9 +7,7 @@ the second is the output when shift is applied. **Note:** The below tables assume a UK layout. #### Flashing -Rev <=5: `make planck:ajp10304:flash` - -Rev 6: `make planck/rev6:ajp10304:flash` +Refer to the README.md of the keyboard you want to flash. ##### Main Qwerty Layer @@ -103,7 +101,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | BTN3 | | | | +| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | | | | | | | diff --git a/keyboards/quark/keymaps/ajp10304/readme.md b/keyboards/quark/keymaps/ajp10304/readme.md index 12090ccd4469..83af702e2a79 100644 --- a/keyboards/quark/keymaps/ajp10304/readme.md +++ b/keyboards/quark/keymaps/ajp10304/readme.md @@ -7,8 +7,7 @@ the second is the output when shift is applied. **Note:** The below tables assume a UK layout. #### Flashing - -`make quark:ajp10304:flash` +Refer to the README.md of the keyboard you want to flash. ##### Main Qwerty Layer @@ -102,7 +101,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | BTN3 | | | | +| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | | | | | | | diff --git a/layouts/community/ortho_4x12/ajp10304/keymap.c b/layouts/community/ortho_4x12/ajp10304/keymap.c index c55e99af79b5..4d9ddb124533 100644 --- a/layouts/community/ortho_4x12/ajp10304/keymap.c +++ b/layouts/community/ortho_4x12/ajp10304/keymap.c @@ -111,7 +111,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Mouse * ,-----------------------------------------------------------------------------------. - * | ESC | | | | | | | | BTN3 | | | | + * | ESC | | | | | | WH_L | WH_UP| BTN3 | WH_D | WH_R | | * |------+------+------+------+------+-------------+------+------+------+------+------| * | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | * |------+------+------+------+------+------|------+------+------+------+------+------| @@ -121,10 +121,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_MOUSE] = LAYOUT_ortho_4x12( - KC_ESC , _______, _______, _______, _______, _______, _______, _______, KC_MS_BTN3, _______, _______, _______, - KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, _______, _______, - KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + KC_ESC , _______, _______, _______, _______, _______, KC_MS_WH_LEFT, KC_MS_WH_UP, KC_MS_BTN3, KC_MS_WH_DOWN, KC_MS_WH_RIGHT, _______, + KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, _______, _______, + KC_MS_ACCEL0, KC_MS_ACCEL1, KC_MS_ACCEL2, _______, _______, _______, _______, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), /* Num Pad diff --git a/layouts/community/ortho_4x12/ajp10304/readme.md b/layouts/community/ortho_4x12/ajp10304/readme.md index be6afa6fe4ae..6db0b851d92b 100644 --- a/layouts/community/ortho_4x12/ajp10304/readme.md +++ b/layouts/community/ortho_4x12/ajp10304/readme.md @@ -101,7 +101,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | BTN3 | | | | +| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | | | | | | | diff --git a/users/ajp10304/readme.md b/users/ajp10304/readme.md index 2ac0a69964ec..bfc39535c1ce 100644 --- a/users/ajp10304/readme.md +++ b/users/ajp10304/readme.md @@ -1,4 +1,4 @@ -Copyright 2020 Alan Pocklington @ajp10304 +Copyright 2021 Alan Pocklington @ajp10304 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 @@ -116,7 +116,7 @@ Activated when `fn` and `raise` held together. | | | | | | | | | | | | | | :---: | :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| :---:| -| ESC | | | | | | | | BTN3 | | | | +| ESC | | | | | | W_L | W_UP | BTN3 | W_DWN| W_R | | | ACC0 | ACC1 | ACC2 | | | | | BTN1 | UP | BTN2 | | | | ACC0 | ACC1 | ACC2 | | | | | LEFT | DOWN | RIGHT| | | | | | | | | | | | | | | | From fb739a67c92483f6c072886b9ffbb90e55b6582d Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sat, 30 Oct 2021 15:13:40 +0100 Subject: [PATCH 0064/1136] Enable configuration of PWM frequency for IS31FL3733B (#14983) * Enable PWM frequency for IS31FL3733B * Document config option * clang --- docs/feature_rgb_matrix.md | 1 + drivers/led/issi/is31fl3733.c | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 2660aad09b03..708cb9f73ed9 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -82,6 +82,7 @@ You can use between 1 and 4 IS31FL3733 IC's. Do not specify `DRIVER_ADDR_` de |----------|-------------|---------| | `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | | `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | +| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 | | `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | | `DRIVER_LED_TOTAL` | (Required) How many RGB lights are present across all drivers | | | `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | | diff --git a/drivers/led/issi/is31fl3733.c b/drivers/led/issi/is31fl3733.c index d99e5339c912..4ddd827caf40 100644 --- a/drivers/led/issi/is31fl3733.c +++ b/drivers/led/issi/is31fl3733.c @@ -56,6 +56,10 @@ # define ISSI_PERSISTENCE 0 #endif +#ifndef ISSI_PWM_FREQUENCY +# define ISSI_PWM_FREQUENCY 0b000 // PFS - IS31FL3733B only +#endif + // Transfer buffer for TWITransmitData() uint8_t g_twi_transfer_buffer[20]; @@ -157,7 +161,7 @@ void IS31FL3733_init(uint8_t addr, uint8_t sync) { // Set global current to maximum. IS31FL3733_write_register(addr, ISSI_REG_GLOBALCURRENT, 0xFF); // Disable software shutdown. - IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, (sync << 6) | 0x01); + IS31FL3733_write_register(addr, ISSI_REG_CONFIGURATION, ((sync & 0b11) << 6) | ((ISSI_PWM_FREQUENCY & 0b111) << 3) | 0x01); // Wait 10ms to ensure the device has woken up. wait_ms(10); From 5334e087ef848d54266537ecdc0b87cac976517e Mon Sep 17 00:00:00 2001 From: jonavin <71780717+Jonavin@users.noreply.github.com> Date: Sat, 30 Oct 2021 14:53:58 -0400 Subject: [PATCH 0065/1136] [Keymap] Jonavin userspace encoder alt tab scrolling (#14979) Co-authored-by: Jonavin <=> --- .../mechwild/obe/keymaps/jonavin/keymap.c | 4 +- .../mechwild/obe/keymaps/jonavin/readme.md | 4 + .../mechwild/obe/keymaps/jonavin/rules.mk | 2 + users/jonavin/jonavin.c | 177 ++------------ users/jonavin/jonavin.h | 8 + users/jonavin/jonavin_encoder.c | 219 ++++++++++++++++++ users/jonavin/readme.md | 11 +- users/jonavin/rules.mk | 11 +- 8 files changed, 271 insertions(+), 165 deletions(-) create mode 100644 users/jonavin/jonavin_encoder.c diff --git a/keyboards/mechwild/obe/keymaps/jonavin/keymap.c b/keyboards/mechwild/obe/keymaps/jonavin/keymap.c index 9e667fba1568..27d09c718d95 100644 --- a/keyboards/mechwild/obe/keymaps/jonavin/keymap.c +++ b/keyboards/mechwild/obe/keymaps/jonavin/keymap.c @@ -25,14 +25,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* Base */ [_BASE] = LAYOUT( - KC_MUTE, KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL, + KC_TSTOG,KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL, KC_PGUP, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_PGDN, TT(_RAISE), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_LSFTCAPSWIN,KC_Z, KC_X, KC_C, KC_V, KC_B, LT(_LOWER,KC_B), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_SFTUP,KC_RSFT, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN1), KC_RAISESPC, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT ), [_FN1] = LAYOUT( - KC_NO, KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_INS, + KC_MUTE, KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_INS, KC_HOME, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_PSCR, KC_SLCK, KC_PAUS, KC_NO, KC_NO, KC_NO, RESET, KC_END, KC_CAPS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_NLCK, KC_NO, KC_NO, KC_NO, KC_NO, KC_PGUP, KC_TRNS, diff --git a/keyboards/mechwild/obe/keymaps/jonavin/readme.md b/keyboards/mechwild/obe/keymaps/jonavin/readme.md index f903a36f12c1..ec17981cafae 100644 --- a/keyboards/mechwild/obe/keymaps/jonavin/readme.md +++ b/keyboards/mechwild/obe/keymaps/jonavin/readme.md @@ -18,6 +18,7 @@ Features - left spacebar Backspace - add double tap of Left Shift to toggle Caps Lock - Up arrow is also Shift when held +- Pushing the encoder switches the default encoder scroll between volume control and Alt-Tab rules.mk OPTIONS - Active features from userspace @@ -46,5 +47,8 @@ EMOTICON_ENABLE INVERT_NUMLOCK_INDICATOR - inverts the Num lock indicator, LED is on when num lokc is off +ALTTAB_SCROLL_ENABLE + - bind KS_TSTOG to a different key to change how this toggle happens + ## All layers diagram ![image](https://user-images.githubusercontent.com/71780717/137356366-6b23c71b-9499-473e-a1e3-c65644135fc6.png) diff --git a/keyboards/mechwild/obe/keymaps/jonavin/rules.mk b/keyboards/mechwild/obe/keymaps/jonavin/rules.mk index 008d0e1de941..6a9acf5d0712 100644 --- a/keyboards/mechwild/obe/keymaps/jonavin/rules.mk +++ b/keyboards/mechwild/obe/keymaps/jonavin/rules.mk @@ -10,3 +10,5 @@ STARTUP_NUMLOCK_ON = yes ENCODER_DEFAULTACTIONS_ENABLE = yes EMOTICON_ENABLE = yes INVERT_NUMLOCK_INDICATOR = yes + +ALTTAB_SCROLL_ENABLE = yes diff --git a/users/jonavin/jonavin.c b/users/jonavin/jonavin.c index 367601dfbabf..b66b444f365c 100644 --- a/users/jonavin/jonavin.c +++ b/users/jonavin/jonavin.c @@ -95,171 +95,21 @@ along with this program. If not, see . } // timeout_threshold = 0 will disable timeout } +#endif // IDLE_TIMEOUT_ENABLE + +#if defined(ALTTAB_SCROLL_ENABLE) || defined(IDLE_TIMEOUT_ENABLE) // timer features __attribute__((weak)) void matrix_scan_keymap(void) {} void matrix_scan_user(void) { - timeout_tick_timer(); + #ifdef ALTTAB_SCROLL_ENABLE + encoder_tick_alttabscroll(); + #endif + #ifdef IDLE_TIMEOUT_ENABLE + timeout_tick_timer(); + #endif matrix_scan_keymap(); } -#endif // IDLE_TIMEOUT_ENABLE - - -#ifdef ENCODER_ENABLE - #ifndef DYNAMIC_KEYMAP_LAYER_COUNT - #define DYNAMIC_KEYMAP_LAYER_COUNT 4 //default in case this is not already defined elsewhere - #endif - #ifndef ENCODER_DEFAULTACTIONS_INDEX - #define ENCODER_DEFAULTACTIONS_INDEX 0 // can select encoder index if there are multiple encoders - #endif - - void encoder_action_volume(bool clockwise) { - if (clockwise) - tap_code(KC_VOLU); - else - tap_code(KC_VOLD); - } - - void encoder_action_mediatrack(bool clockwise) { - if (clockwise) - tap_code(KC_MEDIA_NEXT_TRACK); - else - tap_code(KC_MEDIA_PREV_TRACK); - } - - void encoder_action_navword(bool clockwise) { - if (clockwise) - tap_code16(LCTL(KC_RGHT)); - else - tap_code16(LCTL(KC_LEFT)); - } - - void encoder_action_navpage(bool clockwise) { - if (clockwise) - tap_code16(KC_PGUP); - else - tap_code16(KC_PGDN); - } - - // LAYER HANDLING - uint8_t selected_layer = 0; - - uint8_t get_selected_layer(void) { - return selected_layer; - } - - void encoder_action_layerchange(bool clockwise) { - if (clockwise) { - if(selected_layer < (DYNAMIC_KEYMAP_LAYER_COUNT - 1)) { - selected_layer ++; - layer_move(selected_layer); - } - } else { - if (selected_layer > 0) { - selected_layer --; - layer_move(selected_layer); - } - } - } - - #ifdef RGB_MATRIX_ENABLE - void encoder_action_rgb_speed(bool clockwise) { - if (clockwise) - rgb_matrix_increase_speed_noeeprom(); - else - rgb_matrix_decrease_speed_noeeprom(); - } - void encoder_action_rgb_hue(bool clockwise) { - if (clockwise) - rgb_matrix_increase_hue_noeeprom(); - else - rgb_matrix_decrease_hue_noeeprom(); - } - void encoder_action_rgb_saturation(bool clockwise) { - if (clockwise) - rgb_matrix_increase_sat_noeeprom(); - else - rgb_matrix_decrease_sat_noeeprom(); - } - void encoder_action_rgb_brightness(bool clockwise) { - if (clockwise) - rgb_matrix_increase_val_noeeprom(); - else - rgb_matrix_decrease_val_noeeprom(); - } - void encoder_action_rgb_mode(bool clockwise) { - if (clockwise) - rgb_matrix_step_noeeprom(); - else - rgb_matrix_step_reverse_noeeprom(); - } - #elif defined(RGBLIGHT_ENABLE) - void encoder_action_rgb_speed(bool clockwise) { - if (clockwise) - rgblight_increase_speed_noeeprom(); - else - rgblight_decrease_speed_noeeprom(); - } - void encoder_action_rgb_hue(bool clockwise) { - if (clockwise) - rgblight_increase_hue_noeeprom(); - else - rgblight_decrease_hue_noeeprom(); - } - void encoder_action_rgb_saturation(bool clockwise) { - if (clockwise) - rgblight_increase_sat_noeeprom(); - else - rgblight_decrease_sat_noeeprom(); - } - void encoder_action_rgb_brightness(bool clockwise) { - if (clockwise) - rgblight_increase_val_noeeprom(); - else - rgblight_decrease_val_noeeprom(); - } - void encoder_action_rgb_mode(bool clockwise) { - if (clockwise) - rgblight_step_noeeprom(); - else - rgblight_step_reverse_noeeprom(); - } - #endif // RGB_MATRIX_ENABLE || RGBLIGHT_ENABLE -#endif // ENCODER_ENABLE - -#if defined(ENCODER_ENABLE) && defined(ENCODER_DEFAULTACTIONS_ENABLE) // Encoder Functionality - - __attribute__((weak)) bool encoder_update_keymap(uint8_t index, bool clockwise) { return true; } - - bool encoder_update_user(uint8_t index, bool clockwise) { - if (!encoder_update_keymap(index, clockwise)) { return false; } - if (index != ENCODER_DEFAULTACTIONS_INDEX) {return true;} // exit if the index doesn't match - uint8_t mods_state = get_mods(); - if (mods_state & MOD_BIT(KC_LSFT) ) { // If you are holding L shift, encoder changes layers - encoder_action_layerchange(clockwise); - } else if (mods_state & MOD_BIT(KC_RSFT) ) { // If you are holding R shift, Page up/dn - unregister_mods(MOD_BIT(KC_RSFT)); - encoder_action_navpage(clockwise); - register_mods(MOD_BIT(KC_RSFT)); - } else if (mods_state & MOD_BIT(KC_LCTL)) { // if holding Left Ctrl, navigate next/prev word - encoder_action_navword(clockwise); - } else if (mods_state & MOD_BIT(KC_LALT)) { // if holding Left Alt, change media next/prev track - encoder_action_mediatrack(clockwise); - } else { - switch(get_highest_layer(layer_state)) { - case _FN1: - #ifdef IDLE_TIMEOUT_ENABLE - timeout_update_threshold(clockwise); - #endif - break; - default: - encoder_action_volume(clockwise); // Otherwise it just changes volume - break; - } - } - return false; - } -#endif // ENCODER_ENABLE - +#endif // ALTTAB_SCROLL_ENABLE or IDLE_TIMEOUT_ENABLE // PROCESS KEY CODES __attribute__ ((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; } @@ -326,6 +176,13 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { break; #endif // EMOTICON_ENABLE + #ifdef ALTTAB_SCROLL_ENABLE + case KC_TSTOG: + if (record->event.pressed) encoder_toggle_alttabscroll(); + else unregister_code16(keycode); + break; + #endif // ALTTAB_SCROLL_ENABLE + default: if (record->event.pressed) { #ifdef RGB_MATRIX_ENABLE diff --git a/users/jonavin/jonavin.h b/users/jonavin/jonavin.h index 21b972ed75e3..ab2ce0dff2f2 100644 --- a/users/jonavin/jonavin.h +++ b/users/jonavin/jonavin.h @@ -45,6 +45,8 @@ enum custom_user_keycodes { EMO_JOY, // (^o^) EMO_TEARS, // (T_T) + KC_TSTOG, // Tab Scroll Toggle + NEW_SAFE_RANGE // new safe range for keymap level custom keycodes }; @@ -91,6 +93,12 @@ enum custom_user_keycodes { void encoder_action_rgb_brightness(bool clockwise); void encoder_action_rgb_mode(bool clockwise); #endif // RGB_MATRIX_ENABLE / RGBLIGHT_ENABLE + + #ifdef ALTTAB_SCROLL_ENABLE + void encoder_action_alttabscroll(bool clockwise); + void encoder_toggle_alttabscroll(void); + void encoder_tick_alttabscroll(void); + #endif // ALTTAB_SCROLL_ENABLE #endif // ENCODER_ENABLE diff --git a/users/jonavin/jonavin_encoder.c b/users/jonavin/jonavin_encoder.c new file mode 100644 index 000000000000..387ed5f43006 --- /dev/null +++ b/users/jonavin/jonavin_encoder.c @@ -0,0 +1,219 @@ + +/* Copyright 2021 Jonavin Eng @Jonavin + +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 . +*/ + + +#include QMK_KEYBOARD_H +#include "jonavin.h" + +#ifdef ENCODER_ENABLE + #ifndef DYNAMIC_KEYMAP_LAYER_COUNT + #define DYNAMIC_KEYMAP_LAYER_COUNT 4 //default in case this is not already defined elsewhere + #endif + #ifndef ENCODER_DEFAULTACTIONS_INDEX + #define ENCODER_DEFAULTACTIONS_INDEX 0 // can select encoder index if there are multiple encoders + #endif + + void encoder_action_volume(bool clockwise) { + if (clockwise) + tap_code(KC_VOLU); + else + tap_code(KC_VOLD); + } + + void encoder_action_mediatrack(bool clockwise) { + if (clockwise) + tap_code(KC_MEDIA_NEXT_TRACK); + else + tap_code(KC_MEDIA_PREV_TRACK); + } + + void encoder_action_navword(bool clockwise) { + if (clockwise) + tap_code16(LCTL(KC_RGHT)); + else + tap_code16(LCTL(KC_LEFT)); + } + + void encoder_action_navpage(bool clockwise) { + if (clockwise) + tap_code16(KC_PGUP); + else + tap_code16(KC_PGDN); + } + + // LAYER HANDLING + uint8_t selected_layer = 0; + + uint8_t get_selected_layer(void) { + return selected_layer; + } + + void encoder_action_layerchange(bool clockwise) { + if (clockwise) { + if(selected_layer < (DYNAMIC_KEYMAP_LAYER_COUNT - 1)) { + selected_layer ++; + layer_move(selected_layer); + } + } else { + if (selected_layer > 0) { + selected_layer --; + layer_move(selected_layer); + } + } + } + + #ifdef RGB_MATRIX_ENABLE + void encoder_action_rgb_speed(bool clockwise) { + if (clockwise) + rgb_matrix_increase_speed_noeeprom(); + else + rgb_matrix_decrease_speed_noeeprom(); + } + void encoder_action_rgb_hue(bool clockwise) { + if (clockwise) + rgb_matrix_increase_hue_noeeprom(); + else + rgb_matrix_decrease_hue_noeeprom(); + } + void encoder_action_rgb_saturation(bool clockwise) { + if (clockwise) + rgb_matrix_increase_sat_noeeprom(); + else + rgb_matrix_decrease_sat_noeeprom(); + } + void encoder_action_rgb_brightness(bool clockwise) { + if (clockwise) + rgb_matrix_increase_val_noeeprom(); + else + rgb_matrix_decrease_val_noeeprom(); + } + void encoder_action_rgb_mode(bool clockwise) { + if (clockwise) + rgb_matrix_step_noeeprom(); + else + rgb_matrix_step_reverse_noeeprom(); + } + #elif defined(RGBLIGHT_ENABLE) + void encoder_action_rgb_speed(bool clockwise) { + if (clockwise) + rgblight_increase_speed_noeeprom(); + else + rgblight_decrease_speed_noeeprom(); + } + void encoder_action_rgb_hue(bool clockwise) { + if (clockwise) + rgblight_increase_hue_noeeprom(); + else + rgblight_decrease_hue_noeeprom(); + } + void encoder_action_rgb_saturation(bool clockwise) { + if (clockwise) + rgblight_increase_sat_noeeprom(); + else + rgblight_decrease_sat_noeeprom(); + } + void encoder_action_rgb_brightness(bool clockwise) { + if (clockwise) + rgblight_increase_val_noeeprom(); + else + rgblight_decrease_val_noeeprom(); + } + void encoder_action_rgb_mode(bool clockwise) { + if (clockwise) + rgblight_step_noeeprom(); + else + rgblight_step_reverse_noeeprom(); + } + #endif // RGB_MATRIX_ENABLE || RGBLIGHT_ENABLE + + #ifdef ALTTAB_SCROLL_ENABLE + bool is_tab_scrolling = false; + bool is_alt_tab_active = false; + uint16_t alt_tab_timer = 0; + + + void encoder_toggle_alttabscroll(void) { + is_tab_scrolling = !is_tab_scrolling; + } + + void encoder_action_alttabscroll(bool clockwise) { + if (clockwise) { + if (!is_alt_tab_active) { + is_alt_tab_active = true; + register_mods(MOD_RALT); + } + tap_code16(KC_TAB); + } + else { + tap_code16(S(KC_TAB)); + } + alt_tab_timer = timer_read(); + } + + void encoder_tick_alttabscroll(void) { + if (is_alt_tab_active) { + if (timer_elapsed(alt_tab_timer) > 600) { + unregister_mods(MOD_RALT); + is_alt_tab_active = false; + } + } + } + #endif // ALTTAB_SCROLL_ENABLE +#endif // ENCODER_ENABLE + +#if defined(ENCODER_ENABLE) && defined(ENCODER_DEFAULTACTIONS_ENABLE) // Encoder Functionality + + __attribute__((weak)) bool encoder_update_keymap(uint8_t index, bool clockwise) { return true; } + + bool encoder_update_user(uint8_t index, bool clockwise) { + if (!encoder_update_keymap(index, clockwise)) { return false; } + if (index != ENCODER_DEFAULTACTIONS_INDEX) {return true;} // exit if the index doesn't match + uint8_t mods_state = get_mods(); + if (mods_state & MOD_BIT(KC_LSFT) ) { // If you are holding L shift, encoder changes layers + encoder_action_layerchange(clockwise); + } else if (mods_state & MOD_BIT(KC_RSFT) ) { // If you are holding R shift, Page up/dn + unregister_mods(MOD_BIT(KC_RSFT)); + encoder_action_navpage(clockwise); + register_mods(MOD_BIT(KC_RSFT)); + } else if (mods_state & MOD_BIT(KC_LCTL)) { // if holding Left Ctrl, navigate next/prev word + encoder_action_navword(clockwise); + } else if (mods_state & MOD_BIT(KC_LALT)) { // if holding Left Alt, change media next/prev track + encoder_action_mediatrack(clockwise); + } else { + switch(get_highest_layer(layer_state)) { + case _FN1: + #ifdef IDLE_TIMEOUT_ENABLE + timeout_update_threshold(clockwise); + #endif + break; + default: + #ifdef ALTTAB_SCROLL_ENABLE + if (is_tab_scrolling) + encoder_action_alttabscroll(clockwise); + else + encoder_action_volume(clockwise); // Otherwise it just changes volume + #else + encoder_action_volume(clockwise); // Otherwise it just changes volume + #endif // ALTTAB_SCROLL_ENABLE + break; + } + } + return false; + } +#endif // ENCODER_ENABLE + + diff --git a/users/jonavin/readme.md b/users/jonavin/readme.md index 1b064ddc3cdd..8ec0e0ea16ba 100644 --- a/users/jonavin/readme.md +++ b/users/jonavin/readme.md @@ -35,6 +35,7 @@ KEYCODES: - KC_SFTUP RShift when held, Up arrow when tapped - KC_RAISESPC _RAISE layer mod when held, space when tapped - KC_LOWERSPC _LOWER layer mod when held, space when tapped +- KC_TSTOG toggles between volume and Alt-Tab encoder control - When EMOTICON_ENABLE = yes - EMO_SHRUG `\_("/)_/` @@ -59,7 +60,9 @@ AVAILABLE ENCODER ACTIONS: - void encoder_action_rgb_saturation(bool clockwise); - void encoder_action_rgb_brightness(bool clockwise); - void encoder_action_rgb_mode(bool clockwise); - +- +- void encoder_action_alttabscroll(bool clockwise) +- void encoder_toggle_alttabscroll(void); ENABLE FEATURES your keymap rules.mk --------------------------------------- @@ -89,6 +92,12 @@ EMOTICON_ENABLE INVERT_NUMLOCK_INDICATOR - inverts the Num lock indicator, LED is on when num lock is off +ALTTAB_SCROLL_ENABLE +- When ENCODER_DEFAULTACTIONS_ENABLE = yes, + Enables Alt-Tab scrolling functions in default encoder, + bind KS_TSTOG to a key to enable/disable Alt-Tab vs Volume control +- When defining your own encoder functions use encoder_action_alttabscroll(bool clockwise) to assign the encodr action + FUNCTIONS ------------------------ diff --git a/users/jonavin/rules.mk b/users/jonavin/rules.mk index 646002124713..4f65db27b9ef 100644 --- a/users/jonavin/rules.mk +++ b/users/jonavin/rules.mk @@ -1,6 +1,13 @@ SRC += jonavin.c -ifeq ($(strip $(ENCODER_DEFAULTACTIONS_ENABLE)), yes) - OPT_DEFS += -DENCODER_DEFAULTACTIONS_ENABLE +ifdef ENCODER_ENABLE + # include encoder related code when enabled + ifeq ($(strip $(ENCODER_DEFAULTACTIONS_ENABLE)), yes) + OPT_DEFS += -DENCODER_DEFAULTACTIONS_ENABLE + endif + ifeq ($(strip $(ALTTAB_SCROLL_ENABLE)), yes) + OPT_DEFS += -DALTTAB_SCROLL_ENABLE + endif + SRC += jonavin_encoder.c endif ifeq ($(strip $(TD_LSFT_CAPSLOCK_ENABLE)), yes) OPT_DEFS += -DTD_LSFT_CAPSLOCK_ENABLE From 32d18f28570eb030331cd0f6e83ea2ab822cd9e5 Mon Sep 17 00:00:00 2001 From: Albert Y <76888457+filterpaper@users.noreply.github.com> Date: Sun, 31 Oct 2021 02:54:36 +0800 Subject: [PATCH 0066/1136] [Keymap] Improved settings for Cradio default keymap (#14971) Co-authored-by: filterpaper --- keyboards/cradio/keymaps/default/config.h | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 keyboards/cradio/keymaps/default/config.h diff --git a/keyboards/cradio/keymaps/default/config.h b/keyboards/cradio/keymaps/default/config.h new file mode 100644 index 000000000000..dd469ca5533e --- /dev/null +++ b/keyboards/cradio/keymaps/default/config.h @@ -0,0 +1,39 @@ +/* Copyright 2018-2021 + * ENDO Katsuhiro + * David Philip Barr <@davidphilipbarr> + * Pierre Chevalier + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +// Defaults for usable home row mods +#define TAPPING_TERM 230 +#define IGNORE_MOD_TAP_INTERRUPT + +// Improved mouse key defaults +// Delay between pressing a key and cursor movement +#define MOUSEKEY_DELAY 16 +// Time between cursor movements in milliseconds +#define MOUSEKEY_INTERVAL 16 +// Step size for acceleration +#define MOUSEKEY_MOVE_DELTA 9 +#define MOUSEKEY_MAX_SPEED 12 +#define MOUSEKEY_TIME_TO_MAX 70 +#define MOUSEKEY_WHEEL_DELAY 16 +#define MOUSEKEY_WHEEL_INTERVAL 30 +#define MOUSEKEY_WHEEL_MAX_SPEED 10 +#define MOUSEKEY_WHEEL_TIME_TO_MAX 95 + From 1351dfff08e0ba6b8cac2399a51c9f066979caf9 Mon Sep 17 00:00:00 2001 From: MechMerlin <30334081+mechmerlin@users.noreply.github.com> Date: Sat, 30 Oct 2021 21:17:42 -0700 Subject: [PATCH 0067/1136] [Keymap] Disable in-switch RGB when computer goes to bed (#14993) --- users/mechmerlin/changelog.md | 4 ++++ users/mechmerlin/config.h | 4 ++++ users/mechmerlin/readme.md | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/users/mechmerlin/changelog.md b/users/mechmerlin/changelog.md index dc98e2af0107..733c65a97938 100644 --- a/users/mechmerlin/changelog.md +++ b/users/mechmerlin/changelog.md @@ -1,6 +1,10 @@ # Changelog All notable changes to my userspace will be documented in this file. +## [0.4.1] - 2021-10-30 + +### Added +- `RGB_DISABLE_WHEN_USB_SUSPENDED` added in `config.h`. Couple of my boards now have per key RGB and have been staying on when my computer sleeps. ## [0.4.0] - 2021-10-05 ### Added diff --git a/users/mechmerlin/config.h b/users/mechmerlin/config.h index 698e237b01f3..459c181673f7 100644 --- a/users/mechmerlin/config.h +++ b/users/mechmerlin/config.h @@ -5,6 +5,10 @@ #define RGBLIGHT_ANIMATIONS #endif // RGBLIGHT_ENABLE +#ifdef RGB_MATRIX_ENABLE + #define RGB_DISABLE_WHEN_USB_SUSPENDED +#endif + #ifdef AUDIO_CLICKY #define AUDIO_CLICKY_ON #define AUDIO_CLICKY_FREQ_DEFAULT 261.63f diff --git a/users/mechmerlin/readme.md b/users/mechmerlin/readme.md index c0b1c54c559d..1070953111fa 100644 --- a/users/mechmerlin/readme.md +++ b/users/mechmerlin/readme.md @@ -39,9 +39,9 @@ Output the version of QMK Firmware on device. ## QMK Features ---- -### RGBLIGHT_SLEEP +### RGBLIGHT_SLEEP and RGB_DISABLE_WHEN_USB_SUSPENDED -Ensures that when my computer is in sleep mode, the keyboard underglow lights will also be off. +Ensures that when my computer is in sleep mode, the keyboard underglow and inswitch RGB lights will also be off. ### Audio Clicky From ba69c47bb896a7354d1c6f58b4e43626fb329b72 Mon Sep 17 00:00:00 2001 From: MechMerlin <30334081+mechmerlin@users.noreply.github.com> Date: Sun, 31 Oct 2021 01:17:23 -0700 Subject: [PATCH 0068/1136] Add new default community layout for no f-row TKLs (#14812) Co-authored-by: Ryan --- .../default_tkl_nofrow_ansi/keymap.c | 24 +++++ layouts/default/tkl_nofrow_ansi/info.json | 90 +++++++++++++++++++ layouts/default/tkl_nofrow_ansi/layout.json | 6 ++ layouts/default/tkl_nofrow_ansi/readme.md | 3 + 4 files changed, 123 insertions(+) create mode 100644 layouts/default/tkl_nofrow_ansi/default_tkl_nofrow_ansi/keymap.c create mode 100644 layouts/default/tkl_nofrow_ansi/info.json create mode 100644 layouts/default/tkl_nofrow_ansi/layout.json create mode 100644 layouts/default/tkl_nofrow_ansi/readme.md diff --git a/layouts/default/tkl_nofrow_ansi/default_tkl_nofrow_ansi/keymap.c b/layouts/default/tkl_nofrow_ansi/default_tkl_nofrow_ansi/keymap.c new file mode 100644 index 000000000000..c2b7ecfeaf4c --- /dev/null +++ b/layouts/default/tkl_nofrow_ansi/default_tkl_nofrow_ansi/keymap.c @@ -0,0 +1,24 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* + * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ + * │Esc│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ Backsp│ │Ins│Hom│PgU│ + * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ + * │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ \ │ │Del│End│PgD│ + * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ + * │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ Enter │ + * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───┐ + * │ Shift │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ Shift │ │ ↑ │ + * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ + * │Ctrl│GUI │Alt │ │ Alt│ GUI│Menu│Ctrl│ │ ← │ ↓ │ → │ + * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ + */ + [0] = LAYOUT_tkl_nofrow_ansi( + KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_INS, KC_HOME, KC_PGUP, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, + KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ) +}; diff --git a/layouts/default/tkl_nofrow_ansi/info.json b/layouts/default/tkl_nofrow_ansi/info.json new file mode 100644 index 000000000000..dfb0fc92b4eb --- /dev/null +++ b/layouts/default/tkl_nofrow_ansi/info.json @@ -0,0 +1,90 @@ +{ + "keyboard_name": "Tenkeyless No F-Row ANSI Layout", + "url": "", + "maintainer": "qmk", + "layouts": { + "LAYOUT": { + "layout": [ + {"x":0, "y":0}, + {"x":1, "y":0}, + {"x":2, "y":0}, + {"x":3, "y":0}, + {"x":4, "y":0}, + {"x":5, "y":0}, + {"x":6, "y":0}, + {"x":7, "y":0}, + {"x":8, "y":0}, + {"x":9, "y":0}, + {"x":10, "y":0}, + {"x":11, "y":0}, + {"x":12, "y":0}, + {"x":13, "y":0, "w":2}, + + {"x":15.25, "y":0}, + {"x":16.25, "y":0}, + {"x":17.25, "y":0}, + + {"x":0, "y":1, "w":1.5}, + {"x":1.5, "y":1}, + {"x":2.5, "y":1}, + {"x":3.5, "y":1}, + {"x":4.5, "y":1}, + {"x":5.5, "y":1}, + {"x":6.5, "y":1}, + {"x":7.5, "y":1}, + {"x":8.5, "y":1}, + {"x":9.5, "y":1}, + {"x":10.5, "y":1}, + {"x":11.5, "y":1}, + {"x":12.5, "y":1}, + {"x":13.5, "y":1, "w":1.5}, + + {"x":15.25, "y":1}, + {"x":16.25, "y":1}, + {"x":17.25, "y":1}, + + {"x":0, "y":2, "w":1.75}, + {"x":1.75, "y":2}, + {"x":2.75, "y":2}, + {"x":3.75, "y":2}, + {"x":4.75, "y":2}, + {"x":5.75, "y":2}, + {"x":6.75, "y":2}, + {"x":7.75, "y":2}, + {"x":8.75, "y":2}, + {"x":9.75, "y":2}, + {"x":10.75, "y":2}, + {"x":11.75, "y":2}, + {"x":12.75, "y":2, "w":2.25}, + + {"x":0, "y":3, "w":2.25}, + {"x":2.25, "y":3}, + {"x":3.25, "y":3}, + {"x":4.25, "y":3}, + {"x":5.25, "y":3}, + {"x":6.25, "y":3}, + {"x":7.25, "y":3}, + {"x":8.25, "y":3}, + {"x":9.25, "y":3}, + {"x":10.25, "y":3}, + {"x":11.25, "y":3}, + {"x":12.25, "y":3, "w":2.75}, + + {"x":16.25, "y":3}, + + {"x":0, "y":4, "w":1.25}, + {"x":1.25, "y":4, "w":1.25}, + {"x":2.5, "y":4, "w":1.25}, + {"x":3.75, "y":4, "w":6.25}, + {"x":10, "y":4, "w":1.25}, + {"x":11.25, "y":4, "w":1.25}, + {"x":12.5, "y":4, "w":1.25}, + {"x":13.75, "y":4, "w":1.25}, + + {"x":15.25, "y":4}, + {"x":16.25, "y":4}, + {"x":17.25, "y":4} + ] + } + } +} \ No newline at end of file diff --git a/layouts/default/tkl_nofrow_ansi/layout.json b/layouts/default/tkl_nofrow_ansi/layout.json new file mode 100644 index 000000000000..b8f86b4ac22b --- /dev/null +++ b/layouts/default/tkl_nofrow_ansi/layout.json @@ -0,0 +1,6 @@ +[{a:7},"","","","","","","","","","","","","",{w:2},"",{x:0.25},"","",""], +[{w:1.5},"","","","","","","","","","","","","",{w:1.5},"",{x:0.25},"","",""], +[{w:1.75},"","","","","","","","","","","","",{w:2.25},""], +[{w:2.25},"","","","","","","","","","","",{w:2.75},"",{x:1.25},""], +[{w:1.25},"",{w:1.25},"",{w:1.25},"",{w:6.25},"",{w:1.25},"",{w:1.25},"",{w:1.25},"",{w:1.25},"",{x:0.25},"","",""] + diff --git a/layouts/default/tkl_nofrow_ansi/readme.md b/layouts/default/tkl_nofrow_ansi/readme.md new file mode 100644 index 000000000000..693b1245e626 --- /dev/null +++ b/layouts/default/tkl_nofrow_ansi/readme.md @@ -0,0 +1,3 @@ +# tkl_nofrow_ansi + + LAYOUT_tkl_nofrow_ansi From 53d614955db8b1cc57aeac9b036ca2816c54d486 Mon Sep 17 00:00:00 2001 From: takashicompany Date: Sun, 31 Oct 2021 17:17:38 +0900 Subject: [PATCH 0069/1136] [Keyboard] Add new keyboard "QooLee" (#14977) Co-authored-by: Ryan --- keyboards/takashicompany/qoolee/config.h | 153 +++++++++++++++++ keyboards/takashicompany/qoolee/info.json | 156 ++++++++++++++++++ .../qoolee/keymaps/default/keymap.c | 79 +++++++++ .../qoolee/keymaps/via/config.h | 20 +++ .../qoolee/keymaps/via/keymap.c | 79 +++++++++ .../qoolee/keymaps/via/rules.mk | 1 + keyboards/takashicompany/qoolee/qoolee.c | 17 ++ keyboards/takashicompany/qoolee/qoolee.h | 37 +++++ keyboards/takashicompany/qoolee/readme.md | 30 ++++ keyboards/takashicompany/qoolee/rules.mk | 23 +++ 10 files changed, 595 insertions(+) create mode 100644 keyboards/takashicompany/qoolee/config.h create mode 100644 keyboards/takashicompany/qoolee/info.json create mode 100644 keyboards/takashicompany/qoolee/keymaps/default/keymap.c create mode 100644 keyboards/takashicompany/qoolee/keymaps/via/config.h create mode 100644 keyboards/takashicompany/qoolee/keymaps/via/keymap.c create mode 100644 keyboards/takashicompany/qoolee/keymaps/via/rules.mk create mode 100644 keyboards/takashicompany/qoolee/qoolee.c create mode 100644 keyboards/takashicompany/qoolee/qoolee.h create mode 100644 keyboards/takashicompany/qoolee/readme.md create mode 100644 keyboards/takashicompany/qoolee/rules.mk diff --git a/keyboards/takashicompany/qoolee/config.h b/keyboards/takashicompany/qoolee/config.h new file mode 100644 index 000000000000..99c8ce01428e --- /dev/null +++ b/keyboards/takashicompany/qoolee/config.h @@ -0,0 +1,153 @@ +/* +Copyright 2021 takashicompany + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0x7463 // tc = takashicompany +#define PRODUCT_ID 0x0013 +#define DEVICE_VER 0x0001 +#define MANUFACTURER takashicompany +#define PRODUCT QooLee + +/* key matrix size */ +#define MATRIX_ROWS 3 +#define MATRIX_COLS 12 + +/* + * Keyboard Matrix Assignments + * + * Change this to how you wired your keyboard + * COLS: AVR pins used for columns, left to right + * ROWS: AVR pins used for rows, top to bottom + * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) + * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) + * + */ +#define MATRIX_ROW_PINS { E6, B4, B5 } +#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2, B6, D0, D4, C6, D7} +#define UNUSED_PINS + +/* COL2ROW, ROW2COL */ +#define DIODE_DIRECTION COL2ROW + +#define ENCODER_RESOLUTION 1 +#define ENCODERS_PAD_A { D2 } +#define ENCODERS_PAD_B { D1 } + +/* + * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN. + */ +#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 + +//#define LED_NUM_LOCK_PIN B0 +//#define LED_CAPS_LOCK_PIN B1 +//#define LED_SCROLL_LOCK_PIN B2 +//#define LED_COMPOSE_PIN B3 +//#define LED_KANA_PIN B4 + +//#define BACKLIGHT_PIN B7 +//#define BACKLIGHT_LEVELS 3 +//#define BACKLIGHT_BREATHING + +#define RGB_DI_PIN D3 +#ifdef RGB_DI_PIN +# define RGBLED_NUM 16 +# define RGBLIGHT_HUE_STEP 8 +# define RGBLIGHT_SAT_STEP 8 +# define RGBLIGHT_VAL_STEP 8 +# define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */ +# define RGBLIGHT_SLEEP /* If defined, the RGB lighting will be switched off when the host goes to sleep */ +# define RGBLIGHT_EFFECT_BREATHING +# define RGBLIGHT_EFFECT_RAINBOW_MOOD +# define RGBLIGHT_EFFECT_RAINBOW_SWIRL +# define RGBLIGHT_EFFECT_SNAKE +# define RGBLIGHT_EFFECT_KNIGHT +# define RGBLIGHT_EFFECT_CHRISTMAS +# define RGBLIGHT_EFFECT_STATIC_GRADIENT +# define RGBLIGHT_EFFECT_RGB_TEST +# define RGBLIGHT_EFFECT_ALTERNATING +/*== customize breathing effect ==*/ +/*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/ +//# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256(default) or 128 or 64 +/*==== use exp() and sin() ====*/ +//# define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7 +//# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255 +#endif + +/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ +#define DEBOUNCE 5 + +/* define if matrix has ghost (lacks anti-ghosting diodes) */ +//#define MATRIX_HAS_GHOST + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* If defined, GRAVE_ESC will always act as ESC when CTRL is held. + * This is useful for the Windows task manager shortcut (ctrl+shift+esc). + */ +//#define GRAVE_ESC_CTRL_OVERRIDE + +/* + * Force NKRO + * + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the + * makefile for this to work.) + * + * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) + * until the next keyboard reset. + * + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * fully operational during normal computer usage. + * + * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) + * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by + * bootmagic, NKRO mode will always be enabled until it is toggled again during a + * power-up. + * + */ +//#define FORCE_NKRO + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT + +/* disable these deprecated features by default */ +#define NO_ACTION_MACRO +#define NO_ACTION_FUNCTION + +/* Bootmagic Lite key configuration */ +//#define BOOTMAGIC_LITE_ROW 0 +//#define BOOTMAGIC_LITE_COLUMN 0 \ No newline at end of file diff --git a/keyboards/takashicompany/qoolee/info.json b/keyboards/takashicompany/qoolee/info.json new file mode 100644 index 000000000000..b2245a91c719 --- /dev/null +++ b/keyboards/takashicompany/qoolee/info.json @@ -0,0 +1,156 @@ +{ + "keyboard_name": "QooLee", + "url": "https://github.com/takashicompany/qoolee", + "maintainer": "takachicompany", + "layouts": { + "LAYOUT": { + "layout": [ + { + "x": 0, + "y": 0, + "w": 1.5 + }, + { + "x": 1.5, + "y": 0 + }, + { + "x": 2.5, + "y": 0 + }, + { + "x": 3.5, + "y": 0 + }, + { + "x": 4.5, + "y": 0 + }, + { + "x": 5.5, + "y": 0 + }, + { + "x": 6.5, + "y": 0 + }, + { + "x": 7.5, + "y": 0 + }, + { + "x": 8.5, + "y": 0 + }, + { + "x": 9.5, + "y": 0 + }, + { + "x": 10.5, + "y": 0 + }, + { + "x": 11.75, + "y": 0, + "w": 1.25, + "h": 2 + }, + { + "x": 0, + "y": 1, + "w": 1.75 + }, + { + "x": 1.75, + "y": 1 + }, + { + "x": 2.75, + "y": 1 + }, + { + "x": 3.75, + "y": 1 + }, + { + "x": 4.75, + "y": 1 + }, + { + "x": 5.75, + "y": 1 + }, + { + "x": 6.75, + "y": 1 + }, + { + "x": 7.75, + "y": 1 + }, + { + "x": 8.75, + "y": 1 + }, + { + "x": 9.75, + "y": 1 + }, + { + "x": 10.75, + "y": 1 + }, + { + "x": 0, + "y": 2, + "w": 2 + }, + { + "x": 2, + "y": 2 + }, + { + "x": 3, + "y": 2 + }, + { + "x": 4, + "y": 2 + }, + { + "x": 5, + "y": 2 + }, + { + "x": 6, + "y": 2 + }, + { + "x": 7, + "y": 2 + }, + { + "x": 8, + "y": 2 + }, + { + "x": 9, + "y": 2 + }, + { + "x": 10, + "y": 2 + }, + { + "x": 11, + "y": 2 + }, + { + "x": 12, + "y": 2 + } + ] + } + } +} \ No newline at end of file diff --git a/keyboards/takashicompany/qoolee/keymaps/default/keymap.c b/keyboards/takashicompany/qoolee/keymaps/default/keymap.c new file mode 100644 index 000000000000..64d6ff7aea58 --- /dev/null +++ b/keyboards/takashicompany/qoolee/keymaps/default/keymap.c @@ -0,0 +1,79 @@ +/* Copyright 2021 takashicompany + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + LAYOUT( + KC_TAB, LT(2, KC_Q), KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, GUI_T(KC_O), ALT_T(KC_P), + KC_LCTL, KC_A, KC_S, LT(2, KC_D), KC_F, KC_G, KC_H, KC_J, LT(2, KC_K), KC_L, KC_SCLN, KC_ENT, + KC_LSFT, KC_Z, GUI_T(KC_X), ALT_T(KC_C), LT(1, KC_V), KC_B, KC_N, LT(1, KC_M), KC_COMM, CTL_T(KC_DOT), KC_SLSH, KC_BSPC + ), + + LAYOUT( + KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_TRNS, KC_EQL, KC_LBRC, KC_SLSH, KC_MINS, KC_RO, KC_SCLN, KC_QUOT, KC_RBRC, KC_NUHS, KC_JYEN, KC_TRNS, + KC_TRNS, KC_LSFT, KC_LGUI, KC_LALT, KC_LANG2, KC_LSFT, KC_SPC, KC_LANG1, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_ESC, KC_TAB, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_UP, KC_NO, KC_NO, + KC_TRNS, KC_LCTL, LALT(KC_C), KC_QUES, KC_EXLM, KC_NO, KC_NO, KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_TRNS, + KC_TRNS, KC_LSFT, KC_LGUI, KC_LALT, KC_LANG2, KC_TRNS, KC_TRNS, KC_LANG1, KC_NO, MO(3), KC_DEL, KC_TRNS + ), + + LAYOUT( + KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, + KC_TRNS, RGB_M_P, RGB_M_B, RGB_M_R, RGB_M_SW, RGB_M_SN, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS, + KC_TRNS, RGB_M_K, RGB_M_X, RGB_M_G, RGB_M_T, RGB_M_T, KC_F11, KC_F12, KC_CAPS, KC_NO, KC_NO, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; + +bool encoder_update_user(uint8_t index, bool clockwise) { + + if (clockwise) { + tap_code(KC_MS_WH_UP); + } else { + tap_code(KC_MS_WH_DOWN); + } + + return true; +} + diff --git a/keyboards/takashicompany/qoolee/keymaps/via/config.h b/keyboards/takashicompany/qoolee/keymaps/via/config.h new file mode 100644 index 000000000000..ed834d1aefbb --- /dev/null +++ b/keyboards/takashicompany/qoolee/keymaps/via/config.h @@ -0,0 +1,20 @@ +/* +Copyright 2021 takashicompany + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once + +#define DYNAMIC_KEYMAP_LAYER_COUNT 8 \ No newline at end of file diff --git a/keyboards/takashicompany/qoolee/keymaps/via/keymap.c b/keyboards/takashicompany/qoolee/keymaps/via/keymap.c new file mode 100644 index 000000000000..64d6ff7aea58 --- /dev/null +++ b/keyboards/takashicompany/qoolee/keymaps/via/keymap.c @@ -0,0 +1,79 @@ +/* Copyright 2021 takashicompany + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + LAYOUT( + KC_TAB, LT(2, KC_Q), KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, GUI_T(KC_O), ALT_T(KC_P), + KC_LCTL, KC_A, KC_S, LT(2, KC_D), KC_F, KC_G, KC_H, KC_J, LT(2, KC_K), KC_L, KC_SCLN, KC_ENT, + KC_LSFT, KC_Z, GUI_T(KC_X), ALT_T(KC_C), LT(1, KC_V), KC_B, KC_N, LT(1, KC_M), KC_COMM, CTL_T(KC_DOT), KC_SLSH, KC_BSPC + ), + + LAYOUT( + KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_TRNS, KC_EQL, KC_LBRC, KC_SLSH, KC_MINS, KC_RO, KC_SCLN, KC_QUOT, KC_RBRC, KC_NUHS, KC_JYEN, KC_TRNS, + KC_TRNS, KC_LSFT, KC_LGUI, KC_LALT, KC_LANG2, KC_LSFT, KC_SPC, KC_LANG1, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_ESC, KC_TAB, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_UP, KC_NO, KC_NO, + KC_TRNS, KC_LCTL, LALT(KC_C), KC_QUES, KC_EXLM, KC_NO, KC_NO, KC_LEFT, KC_DOWN, KC_RGHT, KC_NO, KC_TRNS, + KC_TRNS, KC_LSFT, KC_LGUI, KC_LALT, KC_LANG2, KC_TRNS, KC_TRNS, KC_LANG1, KC_NO, MO(3), KC_DEL, KC_TRNS + ), + + LAYOUT( + KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, + KC_TRNS, RGB_M_P, RGB_M_B, RGB_M_R, RGB_M_SW, RGB_M_SN, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS, + KC_TRNS, RGB_M_K, RGB_M_X, RGB_M_G, RGB_M_T, RGB_M_T, KC_F11, KC_F12, KC_CAPS, KC_NO, KC_NO, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + + LAYOUT( + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; + +bool encoder_update_user(uint8_t index, bool clockwise) { + + if (clockwise) { + tap_code(KC_MS_WH_UP); + } else { + tap_code(KC_MS_WH_DOWN); + } + + return true; +} + diff --git a/keyboards/takashicompany/qoolee/keymaps/via/rules.mk b/keyboards/takashicompany/qoolee/keymaps/via/rules.mk new file mode 100644 index 000000000000..036bd6d1c3ec --- /dev/null +++ b/keyboards/takashicompany/qoolee/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes \ No newline at end of file diff --git a/keyboards/takashicompany/qoolee/qoolee.c b/keyboards/takashicompany/qoolee/qoolee.c new file mode 100644 index 000000000000..5a86c3c5bfab --- /dev/null +++ b/keyboards/takashicompany/qoolee/qoolee.c @@ -0,0 +1,17 @@ +/* Copyright 2021 takashicompany + * + * 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 . + */ + +#include "qoolee.h" diff --git a/keyboards/takashicompany/qoolee/qoolee.h b/keyboards/takashicompany/qoolee/qoolee.h new file mode 100644 index 000000000000..986e7e3ec390 --- /dev/null +++ b/keyboards/takashicompany/qoolee/qoolee.h @@ -0,0 +1,37 @@ +/* Copyright 2021 takashicompany + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "quantum.h" + +/* This is a shortcut to help you visually see your layout. + * + * The first section contains all of the arguments representing the physical + * layout of the board and position of the keys. + * + * The second converts the arguments into a two-dimensional array which + * represents the switch matrix. + */ +#define LAYOUT( \ + k00, k01, k02, k03, k04, k05, k07, k08, k09, k0a, k0b, \ + k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ + k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b \ +) { \ + { k00, k01, k02, k03, k04, k05, k07, k08, k09, k0a, k0b, KC_NO }, \ + { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b }, \ + { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b } \ +} diff --git a/keyboards/takashicompany/qoolee/readme.md b/keyboards/takashicompany/qoolee/readme.md new file mode 100644 index 000000000000..35ee431c1cad --- /dev/null +++ b/keyboards/takashicompany/qoolee/readme.md @@ -0,0 +1,30 @@ +# qoolee + +![qoolee](https://github.com/takashicompany/qoolee/raw/master/images/qmk.jpg?raw=true) + +QooLee is a keyboard with a 30% layout with ISO Enter. +It can also be equipped with a rotary encoder. +It supports hot-swapping of keyswitches with MX sockets and mounting of LEDs. +VIA (Remap) firmware is also available. + +* Keyboard Maintainer: [takashicompany](https://github.com/takashicompany) +* Hardware Supported: PCB, Pro Micro +* Hardware Availability: https://github.com/takashicompany/qoolee + +Make example for this keyboard (after setting up your build environment): + + make takashicomoany/qoolee:default + +Flashing example for this keyboard: + + make takashicompany/qoolee:default:flash + +See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). + +## Bootloader + +Enter the bootloader in 3 ways: + +* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (usually the top left key or Escape) and plug in the keyboard +* **Physical reset button**: Briefly press the button on the back of the PCB - some may have pads you must short instead +* **Keycode in layout**: Press the key mapped to `RESET` if it is available diff --git a/keyboards/takashicompany/qoolee/rules.mk b/keyboards/takashicompany/qoolee/rules.mk new file mode 100644 index 000000000000..314fa981186d --- /dev/null +++ b/keyboards/takashicompany/qoolee/rules.mk @@ -0,0 +1,23 @@ +# MCU name +MCU = atmega32u4 + +# Bootloader selection +BOOTLOADER = caterina + +# Build Options +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow +AUDIO_ENABLE = no # Audio output + +ENCODER_ENABLE = yes \ No newline at end of file From fe0acdd2cba8ddd1dfd441f461c80e87a0e5a62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=BB?= Date: Sun, 31 Oct 2021 09:21:20 +0100 Subject: [PATCH 0070/1136] [CLI] Fix broken layout rendering in `qmk info` by '\n' (#14970) --- lib/python/qmk/info.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 350e5e2178f9..85131b9299d4 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -99,6 +99,12 @@ def info_json(keyboard): # Check that the reported matrix size is consistent with the actual matrix size _check_matrix(info_data) + # Remove newline characters from layout labels + for layout_name, layout_json in layouts.items(): + for key in layout_json['layout']: + if '\n' in key['label']: + key['label'] = key['label'].split('\n')[0] + return info_data From 928d9f90ec169f49f50c1566132b06adcaf662d7 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 1 Nov 2021 09:27:54 +1100 Subject: [PATCH 0071/1136] Remove complex `fn_actions` macros (#14662) * Remove complex `fn_actions` macros * Remove additional `KC_FN*` instances --- .../40percentclub/ut47/keymaps/rgb/keymap.c | 4 +- keyboards/hotdox/keymaps/default/keymap.c | 2 +- keyboards/hotdox/keymaps/via/keymap.c | 2 +- keyboards/kinesis/keymaps/default/keymap.c | 2 +- .../kinesis/keymaps/default_pretty/keymap.c | 2 +- keyboards/kinesis/keymaps/dvorak/keymap.c | 2 +- keyboards/kinesis/keymaps/stapelberg/keymap.c | 2 +- keyboards/kinesis/keymaps/tw1t611/keymap.c | 2 +- .../ud_40_ortho/keymaps/via/keymap.c | 2 +- keyboards/planck/keymaps/yale/keymap.c | 4 +- layouts/community/ergodox/algernon/COPYING | 674 ---------- layouts/community/ergodox/algernon/NEWS.md | 229 ---- layouts/community/ergodox/algernon/config.h | 22 - .../ergodox/algernon/images/adore-layer.png | Bin 105611 -> 0 bytes .../ergodox/algernon/images/base-layer.png | Bin 106956 -> 0 bytes .../ergodox/algernon/images/heatmap.png | Bin 139351 -> 0 bytes .../ergodox/algernon/images/steno-layer.png | Bin 64086 -> 0 bytes layouts/community/ergodox/algernon/keymap.c | 1194 ----------------- layouts/community/ergodox/algernon/readme.md | 152 --- layouts/community/ergodox/algernon/rules.mk | 43 - .../algernon/tools/heatmap-layout.ADORE.json | 486 ------- .../algernon/tools/heatmap-layout.Dvorak.json | 477 ------- .../ergodox/algernon/tools/hid-commands | 113 -- .../ergodox/algernon/tools/log-to-heatmap.py | 342 ----- .../ergodox/algernon/tools/text-to-log.py | 106 -- layouts/community/ergodox/dragon788/keymap.c | 2 +- .../community/ergodox/dvorak_plover/keymap.c | 2 +- layouts/community/ergodox/haegin/keymap.c | 2 +- layouts/community/ergodox/kines-ish/keymap.c | 2 +- layouts/community/ergodox/mpiechotka/keymap.c | 127 +- layouts/community/ergodox/ordinary/keymap.c | 288 +--- .../community/ergodox/ordinary_osx/keymap.c | 288 +--- .../keymap.c | 89 +- layouts/community/ergodox/plover/keymap.c | 2 +- layouts/community/ergodox/plums/keymap.c | 84 +- layouts/community/ergodox/teckinesis/keymap.c | 277 +--- .../ergodox/workman_osx_mdw/keymap.c | 390 +++--- 37 files changed, 379 insertions(+), 5036 deletions(-) delete mode 100644 layouts/community/ergodox/algernon/COPYING delete mode 100644 layouts/community/ergodox/algernon/NEWS.md delete mode 100644 layouts/community/ergodox/algernon/config.h delete mode 100644 layouts/community/ergodox/algernon/images/adore-layer.png delete mode 100644 layouts/community/ergodox/algernon/images/base-layer.png delete mode 100644 layouts/community/ergodox/algernon/images/heatmap.png delete mode 100644 layouts/community/ergodox/algernon/images/steno-layer.png delete mode 100644 layouts/community/ergodox/algernon/keymap.c delete mode 100644 layouts/community/ergodox/algernon/readme.md delete mode 100644 layouts/community/ergodox/algernon/rules.mk delete mode 100644 layouts/community/ergodox/algernon/tools/heatmap-layout.ADORE.json delete mode 100644 layouts/community/ergodox/algernon/tools/heatmap-layout.Dvorak.json delete mode 100755 layouts/community/ergodox/algernon/tools/hid-commands delete mode 100755 layouts/community/ergodox/algernon/tools/log-to-heatmap.py delete mode 100755 layouts/community/ergodox/algernon/tools/text-to-log.py diff --git a/keyboards/40percentclub/ut47/keymaps/rgb/keymap.c b/keyboards/40percentclub/ut47/keymaps/rgb/keymap.c index 77fa5b4017f1..ae8ad3e378ec 100644 --- a/keyboards/40percentclub/ut47/keymaps/rgb/keymap.c +++ b/keyboards/40percentclub/ut47/keymaps/rgb/keymap.c @@ -43,8 +43,8 @@ LAYOUT( ), LAYOUT( - KC_FN6, KC_FN7, KC_FN8, KC_FN9, KC_FN10, KC_FN11, KC_FN12, KC_FN13, KC_FN14, KC_FN15, KC_FN16, KC_DELETE, - _______, _______, _______, _______, _______, _______, _______, KC_FN17, KC_FN18, KC_FN19, KC_FN20, KC_FN21, + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_DELETE, + _______, _______, _______, _______, _______, _______, _______, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______, _______, _______, _______, KC_CAPS, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END ), diff --git a/keyboards/hotdox/keymaps/default/keymap.c b/keyboards/hotdox/keymaps/default/keymap.c index 3d6f040f34de..fe07e6f91d04 100644 --- a/keyboards/hotdox/keymaps/default/keymap.c +++ b/keyboards/hotdox/keymaps/default/keymap.c @@ -49,7 +49,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS, KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),GUI_T(KC_QUOT), MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT, - KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_FN1, + KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_NO, KC_LALT, CTL_T(KC_ESC), KC_PGUP, KC_PGDN,KC_TAB,KC_ENT diff --git a/keyboards/hotdox/keymaps/via/keymap.c b/keyboards/hotdox/keymaps/via/keymap.c index 5cfad55ddd2b..df951542a6b3 100644 --- a/keyboards/hotdox/keymaps/via/keymap.c +++ b/keyboards/hotdox/keymaps/via/keymap.c @@ -50,7 +50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS, KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),GUI_T(KC_QUOT), MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT, - KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_FN1, + KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, KC_NO, KC_LALT, CTL_T(KC_ESC), KC_PGUP, KC_PGDN,KC_TAB,KC_ENT diff --git a/keyboards/kinesis/keymaps/default/keymap.c b/keyboards/kinesis/keymaps/default/keymap.c index 2d43aad077a2..d46a07cacf91 100644 --- a/keyboards/kinesis/keymaps/default/keymap.c +++ b/keyboards/kinesis/keymaps/default/keymap.c @@ -40,7 +40,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_LCTL,KC_LALT, KC_HOME, KC_BSPC,KC_DEL ,KC_END , - KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_PSCR ,KC_SLCK ,KC_PAUS, KC_FN0, RESET, + KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_PSCR ,KC_SLCK ,KC_PAUS, KC_NO, RESET, KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_MINS, KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_BSLS, KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN,KC_QUOT, diff --git a/keyboards/kinesis/keymaps/default_pretty/keymap.c b/keyboards/kinesis/keymaps/default_pretty/keymap.c index 9c01b222a7ee..94102a806764 100644 --- a/keyboards/kinesis/keymaps/default_pretty/keymap.c +++ b/keyboards/kinesis/keymaps/default_pretty/keymap.c @@ -32,7 +32,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [QWERTY] = LAYOUT_pretty( - KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, KC_FN0, RESET, + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, KC_NO, RESET, KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, diff --git a/keyboards/kinesis/keymaps/dvorak/keymap.c b/keyboards/kinesis/keymaps/dvorak/keymap.c index 3c532628ef1a..6f4d63a7d4f2 100644 --- a/keyboards/kinesis/keymaps/dvorak/keymap.c +++ b/keyboards/kinesis/keymaps/dvorak/keymap.c @@ -17,7 +17,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_HOME, KC_BSPC, KC_DEL, KC_END, // right hand - KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, KC_FN0, RESET, + KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_SLCK, KC_PAUS, KC_NO, RESET, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH, KC_D, KC_H, KC_T, KC_N, KC_S, KC_BSLS, diff --git a/keyboards/kinesis/keymaps/stapelberg/keymap.c b/keyboards/kinesis/keymaps/stapelberg/keymap.c index c62ffbbccf20..d7a0a5e5c237 100644 --- a/keyboards/kinesis/keymaps/stapelberg/keymap.c +++ b/keyboards/kinesis/keymaps/stapelberg/keymap.c @@ -56,7 +56,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_LCTL,KC_LALT, KC_LGUI, KC_BSPC,KC_ESC ,KC_END , - KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_PSCR ,KC_SLCK ,KC_PAUS, KC_FN0, RESET, + KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_PSCR ,KC_SLCK ,KC_PAUS, KC_NO, RESET, KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,KC_MINS, KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,KC_BSLS, KC_H ,KC_J ,KC_K ,KC_L ,KC_SCLN,KC_QUOT, diff --git a/keyboards/kinesis/keymaps/tw1t611/keymap.c b/keyboards/kinesis/keymaps/tw1t611/keymap.c index c94f06bbb966..e7a6ffd6e902 100644 --- a/keyboards/kinesis/keymaps/tw1t611/keymap.c +++ b/keyboards/kinesis/keymaps/tw1t611/keymap.c @@ -15,7 +15,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_RCTL,KC_LALT, KC_HOME, KC_SPC ,KC_LSFT,KC_BSPC , - KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_PSCR,KC_SLCK,KC_PAUS,KC_FN0 ,RESET, + KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_PSCR,KC_SLCK,KC_PAUS,KC_NO ,RESET, KC_6 ,KC_7 ,KC_8 ,KC_9 ,KC_0 ,DE_SS , KC_Y ,KC_U ,KC_I ,KC_O ,KC_P ,DE_ADIA, KC_H ,KC_J ,KC_K ,KC_L ,DE_SLSH,DE_ODIA, diff --git a/keyboards/mechstudio/ud_40_ortho/keymaps/via/keymap.c b/keyboards/mechstudio/ud_40_ortho/keymaps/via/keymap.c index c61bec5a0537..affc42c7bb3f 100644 --- a/keyboards/mechstudio/ud_40_ortho/keymaps/via/keymap.c +++ b/keyboards/mechstudio/ud_40_ortho/keymaps/via/keymap.c @@ -20,7 +20,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT, - _______, KC_LCTRL, KC_LALT, KC_LGUI, KC_FN13, KC_SPC, KC_SPC, KC_FN23, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT), + _______, KC_LCTRL, KC_LALT, KC_LGUI, KC_NO, KC_SPC, KC_SPC, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT), [1] = LAYOUT_ortho_4x12( KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, diff --git a/keyboards/planck/keymaps/yale/keymap.c b/keyboards/planck/keymaps/yale/keymap.c index 60bbc758d78e..0baa24bdb7be 100644 --- a/keyboards/planck/keymaps/yale/keymap.c +++ b/keyboards/planck/keymaps/yale/keymap.c @@ -68,9 +68,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [_NAV] = LAYOUT_planck_grid( - KC_MS_ACCEL2, KC_FN1, KC_FN2, KC_FN3, KC_FN4, XXXXXXX, XXXXXXX, KC_WH_D, KC_WH_U, XXXXXXX, XXXXXXX, XXXXXXX, + KC_MS_ACCEL2, KC_NO, KC_NO, KC_NO, KC_NO, XXXXXXX, XXXXXXX, KC_WH_D, KC_WH_U, XXXXXXX, XXXXXXX, XXXXXXX, KC_MS_ACCEL1, KC_MS_BTN4, KC_MS_BTN3, KC_MS_BTN2, KC_MS_BTN1, XXXXXXX, KC_MS_LEFT, KC_MS_DOWN, KC_MS_UP, KC_MS_RIGHT, XXXXXXX, XXXXXXX, - KC_MS_ACCEL0, KC_FN9, KC_FN10, KC_FN11, KC_FN12, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + KC_MS_ACCEL0, KC_NO, KC_NO, KC_NO, KC_NO, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX ), diff --git a/layouts/community/ergodox/algernon/COPYING b/layouts/community/ergodox/algernon/COPYING deleted file mode 100644 index 94a9ed024d38..000000000000 --- a/layouts/community/ergodox/algernon/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 3 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/layouts/community/ergodox/algernon/NEWS.md b/layouts/community/ergodox/algernon/NEWS.md deleted file mode 100644 index a6ce9813baf7..000000000000 --- a/layouts/community/ergodox/algernon/NEWS.md +++ /dev/null @@ -1,229 +0,0 @@ - - -## v1.12 - -*2018-11-22* - -### Overall changes - -* Updated to work with QMK master. - -### Miscellaneous - -* The `😂` symbol can be entered with UCIS. -* `LEAD r` now inputs `Right Alt`. - -## v1.11 - -*2017-10-01* - -### Overall changes - -* Updated to work with QMK master. -* The `$` and `^` symbols on the number row were swapped on both the base and the ADORE layers. -* The bracket tap-dance keys can now be used to input Japanese brackets, `「` and `」` with a third tap. -* The second column of the top row on the right side will act as a "Social" application selector on the `AppSel` layer. -* The third key on the same column will select a password manager. -* The `GUI` key will now launch `rofi` when triple-tapped. - -### Miscellaneous - -* The `👶` symbol can be entered with UCIS. -* The `👪` symbol can be entered with UCIS. - -### Tools - -* `tools/hid-commands` can now find the `Mstdn`, not just `Slack`, as the "Slack"/chat app. -* `tools/hid-commands` can now find the Plex web app as a music/media player. -* `tools/hid-commands` now understands the "Social" application selector. It raises the `Mstdn` and `Tweetdeck` windows, but keeps focus on the previous window. -* `tools/hid-commands` now understands the "Social2" application selector, which raises `Signal` and `Viber`, but keeps focus on the previous window. -* `tools/hid-commands` is now able to select a password manager (KeePass*). -* `tools/hid-commands` can now run `rofi` when receiving an `appsel_helper` command (triggered by a triple-tapped `GUI` key). - -## v1.10 - -*2016-12-28* - -### Miscellaneous - -* `µ` can now be entered with UCIS. -* `™` can now be entered with UCIS. - -### Tools - -* `tools/hid-commands` can now find Banshee, and prefers it over Kodi. -* `tools/hid-commands` can now find Chrome too, not juts Chromium. - -## v1.9 - -*2016-10-16* - -### Overall changes - -* `F12` was replaced by an `Fx` key, that activate the **Media** layer as a one-shot layer, and also `Alt` as a one-shot modifier. - -### Base layer changes - -* The `Media Stop` key is now a tap-dance key, and resets the device for programming on the fourth tap. - -### Miscellaneous - -* `π` can now be entered with UCIS. -* `🐁` can now be entered with UCIS. - -### Tools - -* The `tools/layer-notify` tool was removed, it was an example, which I don't use. - -#### `tools/hid-commands` - -* Now looks at the `DISABLE_APPSEL_START` environment value, and does not display an AppSel notification if it is non-empty. -* Will attempt to re-program the keyboard when receiving a `reflash` command. -* No longer tries to select Emacs 24 on `APPSEL_EMACS`, rather, it goes for any Emacs. -* The `APPSEL_MUSIC` command now includes Kodi in the list too, as the last choice. - -## v1.8 - -*2016-10-03* - -### ADORE - -* Major rearrangements were made, to reduce pinky use, and to balance out the hand usage. - -### Tools - -* The `hid-commands` tool will now display a notification when the **AppSel** layer is triggered. -* The `log-to-heatmap.py` tool now treats the innermost keys on the bottom row as thumb keys, as far as statistics are concerned. - -### Miscellaneous - -* Fixed the **Steno** toggle key. - -## v1.7 - -*2016-09-18* - -### Overall changes - -* The number row has been completely rearranged on both the **Base** and the **ADORE** layers. -* The number/function key behavior was changed: function keys are now on the **Media**. -* The `:`/`;` and `-`/`_` keys were put back to their thumb position on the bottom row, on both the **Base** and **ADORE** layers. -* The bottom large keys on the inner side of each half now function as [tmux](http://tmux.github.io/) keys: the left to send the prefix, the right to send the `display-panes` key. The left also doubles as a GNU screen prefix key, and sends `C-a` when double tapped. -* A number of functions, such as the **AppSel** layer, now require the `hid-commands` tool to be running, with the output of `hid_listen` being piped to it. - -### ADORE - -* `Y` and `X` have been swapped again. - -### Media/Navigation layer - -* The function keys are now on this layer. -* Mouse keys have been removed. -* Media start/stop/prev/next have been removed. -* `Print screen` has been removed. -* There is only one screen lock key now. - -### Heatmap - -* Fixed a few issues in the finger-stats calculation. -* The tool now also timestamps and saves all input lines to a logfile, which it loads on start, allowing one to continue the collection after upgrading the tool. -* The heatmap tool will now colorize the stats by default. -* The periodic stats are now printed in a more compact format. - -### Tools - -* Added a new tool, `tools/layer-notify` that listens to layer change events on the HID console, and pops up a notification on layer changes. -* Another new tool, `tools/text-to-log.py` has been added that converts arbitrary text to a keylogger output, which can be fed to the heatmap generator. -* A number of features have been moved to the `tools/hid-commands` utility. These generally are OS dependent, and are easier to implement on the software side. - -## v1.6 - -*2016-08-24* - -### Base layer changes - -* The parentheses & bracket keys have been merged: tapping them results in `[` or `{` (if it was shifted), double tapping leads to `(`. -* The `:;` and `-_` keys are now available on the base layer, on their **ADORE** location, too, just below `[{(`/`]})`. -* The `Apps` key has been replaced by `F12`. -* The `-`/`_` is no longer a tap-dance key. - -### ADORE layer changes - -* Adjustments were made to the **ADORE** layer, to separate some inconvenient combinations. - -### Miscellaneous changes - -* `LEAD u` now starts the symbolic unicode input system, instead of the OS-one. -* The mouse acceleration keys on the **Navigation/Media** layer have been turned into toggles: tap them once to turn them on, until tapped again. Tapping an accelerator button will turn all the others off. -* When the **ARROW** layer is on, the *red* and *blue* LEDs light up now. - -### Heatmap - -* The built-in keylogger has been greatly enhanced, it now outputs the pressed state, and the layer (Dvorak or ADORE). As such, the `ADORE_AUTOLOG` option has been removed, instead there is `AUTOLOG_ENABLE` now, which when enabled, makes the keylogger start when the keyboard boots. It defaults to off. -* The heatmap generator received a lot of updates. - -## v1.5 - -*2016-08-12* - -* The **1HAND** layer has been removed. -* A `Delete` key is now available on the right thumb cluster. -* The **ADORE** layer received a major update, see the layout image above. -* It is now possible to enable automatic logging for the **ADORE** layer, by setting the `ADORE_AUTOLOG` makefile variable to `yes` when compiling the keymap. It is off by default. -* The `~` key and the `Media Next/Prev` key have been swapped on the **Base** layer. -* On the **ARROW** layer, `Backspace` has been replaced by `Enter`. -* There is some experimental support for entering Unicode symbols. - -## v1.4 - -*2016-07-29* - -* When toggling the key logging on or off, the LEDs will do a little dance. -* The keylogger is now optional, but enabled by default. Use `KEYLOGGER_ENABLE=no` on the `make` command line to disable it. -* The `TAB`/`ARRW` key was turned into a tap-dance key, allowing one to toggle the **ARROW** layer on by double-tapping, and as such, avoid the need to hold the key. -* The `-`/`_` key was turned into a tap-dance key too. -* There is now a way to travel time with the keyboard, toggle the feature on by hitting `LEAD t`. - -## v1.3 - -*2016-07-06* - -* Added support for logging keys, by pressing `LEAD d`. Also included is a tool to generate a *heatmap* out of the logs. -* The arrow and navigation keys were rearranged again, and now require an additional key being held to activate. See the **Base** layer for an image that shows where arrows are. -* The **experimental** layer has been redone, and is now called **ADORE**, and as such, can be enabled by `LEAD a` now. -* Switching between Dvorak and ADORE is now persisted into EEPROM, and survives a reboot. - -## v1.2 - -*2016-06-22* - -* The forced NKRO mode can be easily toggled off at compile-time, to make the firmware compatible with certain operating systems. -* The `:;` key has changed behaviour: to access the `;` symbol, the key needs to be double-tapped, instead of shifted. -* The `=` and `\` keys were swapped, `=` moved to the home row, on both the **Base** and the **experimental** layers. -* The arrow and navigation keys were redone, they are now more accessible, but the navigation keys require an extra tap to access. -* The **Emacs** layer is gone, replaced by a simplified **navigation and media** layer. -* `LEAD v` types the firmware version, and the keymap version. -* On the **experimental** layer, the `L` and `Q`, and the `K` and `G` keys were swapped. -* The **Steno** layer gained a few more `#` and `*` keys, to make it easier on my fingers. - -## v1.1 - -*2016-06-14* - -* The keyboard starts in NKRO mode, bootmagic and other things are disabled. -* A **Steno** layer was added, to be used with Plover. -* An **experimental** layer was added, something halfway between Dvorak and Capewell-Dvorak. A work in progress. -* `LEAD y` types `\o/`. -* Some keys on the **Base** layer have been moved around: - - `?` moved to the left pinky, left of `Q`. - - `=` shifted one row down, but `F11` stayed where it was. - - `-` on the left half was replaced by `Tab`. - - `Tab`'s original position is taken by a `Media Next`/`Media Prev` key. - - `:` now inputs `;` when shifted. -* `ESC` cancels the **Hungarian** layer too, not just modifiers. - -## v1.0 - -*2016-05-26* - -Initial version. diff --git a/layouts/community/ergodox/algernon/config.h b/layouts/community/ergodox/algernon/config.h deleted file mode 100644 index 583c3911f18f..000000000000 --- a/layouts/community/ergodox/algernon/config.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#undef MOUSEKEY_TIME_TO_MAX -#undef MOUSEKEY_MAX_SPEED - -#define MOUSEKEY_TIME_TO_MAX 1 -#define MOUSEKEY_MAX_SPEED 2 - -#undef MOUSEKEY_DELAY -#define MOUSEKEY_DELAY 0 - -#undef MOUSEKEY_WHEEL_DELAY -#define MOUSEKEY_WHEEL_DELAY 0 - -#define ONESHOT_TAP_TOGGLE 2 -#define ONESHOT_TIMEOUT 3000 - -#undef LOCKING_SUPPORT_ENABLE -#undef LOCKING_RESYNC_ENABLE - -#undef LEADER_TIMEOUT -#define LEADER_TIMEOUT 1000 diff --git a/layouts/community/ergodox/algernon/images/adore-layer.png b/layouts/community/ergodox/algernon/images/adore-layer.png deleted file mode 100644 index 75d2ca4f08b23b8233b298b0a30cb62b4072f0a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105611 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

p<8JqN28pH2mC;gjx$8M zZi|5G+`q0+LWmj;)F`1+3>fay9;H0zLERZS~ zy=jY;!TI1*BVJ!L9IF{NS50onZ&5k&Z|V61D2s~5orsEPqg%hkP+kAl9oevkp?(g# z#Rbw&;8Br*{%_5P6oNh$usqdW#N@K@@0b{v$oR~%$V<;ToZ1)~v*~bk^@j+K^5pK2 zq0mlE$k+vi84#_1QSKojLEz?7hJUh6QbKh5|N7;OQozO_MncO-OU3a(b*!lTa}OWM zC0lqdZW0W!Koc}6k_P+l>p$)Y?d|RF^={YyifK!cv+uy?;^Laj$eAFm2{)iGf1$pC zq}lZz+yiuZ0#t6KeeKX_pIRhOUOfm>{{PQ!ZYA=99*hkc$4KYmNT{y=l>7+VCG^o5 zaC)$#UwyRvurcl?h@3W}7L|8>Z7ydDrS>UNC!x^SOa-vjM3mhgH+cgs@E(*Ij?~ZK zf;W`*&5BWRu@5eags8xh|2%o{5&s>bMoVT4Y^eW5x20xSMJm_a&X&ZmdHewtpB|b7 z>?ypqw>EosRtKXwSZzp)zEUrHbiZRtkKXN4&1X`-{R=(yzlDb*Y$a@1zbmNY4kDr; z$t{|p{4=G7tM7Z3jAB;Y9m?~*FVl<%5PU^LfiiUe#qY@yGb7NYTGYdPWEuDIV<=3l zCh5RpioLB#|T6$o`JS`@(23!2DIu13CuNr&FC zcdt!Y-&CCR;-8$Is)<=yQ%JyUX)}Qr(**q!Fd9(w4DwN|>zUk*eM+P9hKrjRemeU| zlUG>wEm5bm{$h)h>b2GkvS6t1;`{1M?9}N)5kdLN$I4c0snNm~H z+~ku;2zNV^J0pv9=yO0pdl4wDN1QHdjIdaTw>1=^@P^zdP&I zW)9~3ZVjaM1Hr`O#cv8w3nI_~qyo zoay8jTWLKF;#ERaROoDU#mUc~JS^0wV)Sb^tP$NE%?W#KG_cL0lF)eF2z840k0xK# z#k~4uP1iyGN)#IVhn0)*ao%v6NX0#2Vl(C$k5cJIFdl~25z+JTkd>+1gwMHiXTqlR zryK-l*fj8Q$i{Ddp+eZ-=g{u zY8T;^>hK1pq)@&uS-2NJe9Kten@|r!d!`K@UU~bHD#v-9g;)$B!TP4)uvDNnmonsZ2Up!s260v@AF*N(#vFHO4J-;BD^;`p1AtfrlqN5H~a%>`;b!PqR zj||_&L<=jOR3K$xp%!0g`V#iZtFUkev=z^s0rcYi94m+ssN z@grG=ZbL+hAjVf#6L;G?YRQ%}I@$O#Z^f1mKJ6oQ_d{fIOBVu4P8f(xlXNt$V39s13)cA(x)FNqGYS$@6@&CV6Jm zLPHTzET|!Z4a{886e?$5jj-FJJts~`O!OHXl!xHFc1qr^FnNrlDwckC__WgPLdtsX zjC){m@BHNABA~I+)y}^JFdesF--4uic+~#KpO;Dkj^grw4NRdOCNPHS z{o>8V(7iB}){}2zl5VmQP`L{$Q34(rbS5kqK{|J6<5ASB1t?2DpOx(05#HJ?D#bjE zjE^BAM(cfCRY4)s(sqG!3tQrsfl;)TyB7h7BVjH5#Qtk%f0m?B4NYca$Xs6T*_MLdRL!A8t#Y!(f&c(l~J^iVz_}T#F(@;8ZLj z04ROKXT1@v5Z^An=RQ(|4MEwdvc?@j2-|Y;BuDdLn)n;Pag+#54i>&z-=P-^0wblF z7#anZeG2uyi>&dHA=+uy6;pPLxShBgDN)4v^#iK zhT1maKdr`H5BxHKN;WWGY5CUIHB76vi{bil;$ySLwFfD;d!e1yX3udT9Lz+9@d|H8 zl^E%ulm~-^-@@9ehSIuN?=EH2nEoB9Y=}Nv!^@pEYe+a1ssrEdK9}F^R%xZ%iZrZT z5}3X~-7hRD1vG4@!ipbCKTTn)pcMWr(9zk64y=cyu}UQ}K|(#2$8mbuS6-`AzIH}K z^pPP9q6y@};SBx+N-t5Tzd|he`_wV(GCXXJRTCswp@>G%btylqf8q3INOHV}qE~hV zG2!c;sadprRoc0bKU2YGopMXo@EYU2TPC}8+Utmv!RHQ%!YKI1jO&4lrgY4#6afd8 zO}qvW)Gt?hf3PjA7@*bURWgKzT6EAB9f9aKfgSsMtm+&aB`xAgMJArb8aG^Tzro)m zw%OIY{@|0ui%>~H@Vfkc5@)3yoHG#*KQ4X|zqus=IAT;H3>Y-@ALJ|-8gZ|~54uwF z8zf){LM#;14KkOJT%G~~JtOzet$UMRVH_Rf_-ncTj^iL@f^H8c`U1YjoMp^API`{a zOfZc8N^Hb$ydVcF=TItBwFqdq=FSq!H*5{s3j89C!_N=e>-#D9kTKMYjD5rRLa_XT zlInn^PRrFkxP%poH>`>8>N}yG94jSK(gWT3W7{m+Hyf{RH6DcxR|(aS zr*$v{OvAVvWJ2G_nPBg9{@UZhYQ4R9`T6cA>-*C1{iiPaG*X7Jts2TBoo&{^SY zOT+oT?X~+a*sl4cPicb(rZws8+e#DMfY4+=B2}?eYkryW5(?=Sx5qzcouUjnwVn87 z2I8z%O=cF@^|rL{NktqYl%G?^E($@41dRK zOxTdPm0l4E-7;1b&R{jYa?LIuhu!dhd$Qh%GJ85k)`9ZF&FRYBy43baHNtqJv6lk1&Eb2|`eeh$#fIRjl#q>bTB{fAx7U-XT57+l@=G{ccWj?IeMfI)JJFYM&} z9pN24bUH&p!ktp6k|y%li|*>&H)1)?h#w9`()?`}x^A+sJ9^fM`3+UMo|<#bydyF~ zmhFu}wM>JF-p?Ktrr%lI=)@s*Cku$lxy-%A?a z*2l)~d>ujytfjl%e}m}iN^FM3E-gl;T@WPh?RAK%n7e6k?(H4o(ya6h2!{Qs`0?GT zSR2*L%j>=MGQsC1>eR@!1I6(GNOnpi-C`4rebwmNl4e;^a_)uk8q4~9YsORk8G@HY zoy_Ur3W8joG7V7sHP6Kl`%%Og;JNrwLn~ zJ7d7Vm5o3IEmMWvNL?BnUAe0LdeDFkY^{YmBw(`<8B0X7J}*ONJee1N4N#XjS;{%3 z@_s@EJZ}WqJJNKI53Uy*JCyU-ookTI?+v1N5-)f44$SI~2OreCUOyE2#)kp?fTYaK zo~luY`MX0`P~S|byi;oO!#AJC@z0CTd+s*-?A1$p;+=6#^| z{DFnfHA!zr;>O%M6ih!?h14(vJWGjEd;rXTwh6}r3BFQ;?j+#6M3#Pxl*qT{`Bn;D z7-K|sP~tnwFqG%i2ai?Ig%uKfuTSqD%v1~WSL2JNnGZ5TJ+SOg%83i9>bw_=UQ0LbvTbGUVETk^c=kS06$#|lF?{#V87+FM}5Sq)^T%v z$!T=bgI=4ZvEYo|Gb=!3IE#>8L-l7r+!P#K(d4gA`tc#eS8xlCD903p?^hOibB! z9CM8{f~#Ujp`U3AqV5dB5anZh;nzX%7DfAT_iv~av;4*se1NwOq z$+kx_IR3P8#jiK!2sOh{s;R3!vUP7qLJrKQzNsBZCaM@SxMOA$NPy(=^k4Fbk{dPe zA)T0;RS~LXj?|Ia55?za{X+G*uU4x(?%CZkfxNf2+tEUDqNV#VUYX2|Fv4|UC9^kmohe!nh+jAL7^tQ>xF zc1lgvsb%z;GuZFCrgHM~2)_r!oS-xUYP$^CN3ON8(tAaJD@%2ozp$#8>i@ku?QqQ2 zWQLwy7uhKhJVRHH#Mb<QU7(;-X;k}Y52$&Ys zBoM#0C}kcAGSn?hXo|{ZQuc^p%{q~5>3 zHg20;tWPDXgbaK``q_1Sk|_q4m)mh>FQ<7OylRTdALb8ykpWnrOkB&h>oLmy=kHH! z_+@5S3$9ET7b>loKQ+essWu1D3kgyG3_pHRu_xLgSRHD{7y_ayn5#Wwkinx(*S%j2 zaCS`00lvJahsql%<8?NA3jb0O7)2%1LsJBqp9Le78g*pDrJ9;l28SY|zCr@D(T*5} zz1usf+!Q$&p-QS+uM;1Snwrw5yU6S=%B$yq5Iq^10cj-XGWYAHH6$Q^pXaTJ6JW`} zEbJW^$Sfe(th!Y;IOt$xY@BH%<5mCYY-Wqq%kW739U%opkqnXV@1oAxj9x2<%BbEP zMz*kYKwcoGfWYK0c2i^HCofsCLD`~UeP+x5C@}Tg5Ly*$RRX41;N{nxvc2(_V@7QZ ze{1cC&i5Xhoz6r4{yyxfjD*CSmWU2j#`;-lf^WL6LL>`DQAAJDRf)2I!DHnx3z3LT zEY?O!$1vLj3@3f--%#o`NILeJnbJ613&v9-FjE6?I$#U|V{w$eD6cWD%Q&iuDFRhz zew>eL&8ipzQ2J#6?2xbim;+*mgMOm;*46vr)&Tvh?4-`Wu!6OLPh_7qwiRNY>Q;(W z1b!@VDR?KhW}~T{)O!%jN8?+(_~qEbP36V2n1Y~m{oBW{!)E|s+o4y5=EwT?L z1t~llc?#JWuZMYqkQL8384fU>jgion&_XtJMD$Inepn8a>I~bXC^78DZf|mnq9BTO zF{bFg@2Q3C9E5}8p^T|#dK5kLNiR*q-|79Lc>FjKGck_%e!(B~K7d4{^w6$8G>n0xHKvAZA_3pE?}*LsG9D$L{2URUNQ4NK?>Yl;+V&}`CL^?3 zAkPenksb@dqrw>E9==w}pGuK_=fpBsavQHM+mg!g{5eh)X1J(J&Ue|QEO;%9Mq7Mk z&+xuhwO__qX*9EdmA+}1bxE)^4+8mKO>t-duwAJ^Wu3f4|zrO z=78Iuhgyca@;HpmVpfD;+{lH6jPGa2*X9z`zO5{+C-U`l7>B*huF+P!UB0VFH`MJ@ zYdfVbD%GF@oi^UlQUn^!&`w{@3N|f)kR#_GJQwUwpFSmZjGB>YwJ5SeC#Mcwi8D#j z5>{9B9X@bASmt{6$X4>L3F$aZ_7l!>N-!o<-O3*v#95T7$ECR=8f_pGP~tj`@H**C z*z2eVz*ym;WIwpFQA7wC3(Z{Lj=^x+zGtfm3w(rjhX)6b8~uB@zP{lE^-8oqt`VvX z7{t@f?#@OGIr<-46<3enr7*8-c`3@viMHl^%X;5sr_tn6;T=fI`P`BWTfdsO&D>RN z()^y`aB1LWv=V(aDe6GXyRC#6+Z|GNM5=FuS9{Ut#L9y!*Zr$_HNGF57n zLbZ9RrYNT0`IkuHQ;PMqsW5%V`8f90u?Y4a1p;tqURqQz+*RhdlvtdzcQIBHK8L*4 z;8N2h&q|2WOnnEEDL|%@)a8^A07j@a772MBsb(k0=pNPJkvP*b#UKfT(ai?q)Hc0l zcnYCa{o-O(e{{^pgZS%#75dRA;W15K&uFMlsXT1c$TaH%oM`mNFD6gVwNf3kvx6!; zS4{0sjFQSI%>3om#sl28_Cd^7VcV#@=4;cBKv$oj{zw0JALO&|!#Ds3ik26!h_#7g z1<^ti%tN~0ihdFn&SQpFbLQ1QgP$%BaBR$=Vfyhfg8M{84r=dO@02=5MrdsaIZP(j z1H~l44rhi@_3j<2oUuKn)7vi42UOMjmBudy;yIk>e_*?&OaFG?8BT34l|8?_%31K|h@W+0tRj|s9!Ezl{Q|UsSsfGqAnP)UXp0Mc_#`kHUY|9owmTjgjeFH>m z#|KUys)#na%%?a#f!~PPvUc!H8~fuXkPv`d&Y5hAlD=CBHsYC*-4@msA-W!(ksRLxb(EX`eP+h77_;93lf?a%AT9nEX zErS#7K&+ceLQYK`E^gl<)v2QDQn`0|M{B#ktm+U-9ts9A2Ck86oP##%W@h;VX>fzZ zw_>c&7}qTwE>1u@NW6Vh0yez&FD!6%iJ*zyjO|oIlr&C*dz|ALTO@?}ZOSOv^Euih zd^QW}d|tYbiHJHLnE=LOoSWZ_MX-UQ(+k3sv_zlkK^%x3?xJLkrpQjNZ$uthlVG#F ze9Fy$8Y1Pl&Q)WT!PD;260N%L0`Rpx)zM>1i@w^Irj*l5u5!dR-w(x#oCx7-b-+m*NMt|0V7BW9K_cy>9v$jx?BMW9 zov{eC)1~4E>d6G_>b2ghlcBG&>Btzx#M0I0e)((PXL$ZKIuX8E&l_Vqfo&vt%Y4xq zf<<$)`yFE1sT8UsBO}AE2pg5fd7#IHovHo*zcy;H-leMIXd5^J;0hB)Z#P35(j0Yb z%Bn#DSYom!s0M_jQTk2{DsS3@n8ZR(T z^s=c2Jc!r-S%PJ-1fVXqE?pA@mduQkxb)V2nbwZ?MguMjFZs{Z?J_CO!1?aoXi4zQsWxsr5B14UuTu750ig~TW z-@c{pmeoQefGrz}F^K`5YW53AceUwEHdO9AvZM>=9E7O&93uj6JZ0lVG_H5Xehxf1 zVLxImLwO^;GuIU|2V$v_scDu|=ZoD5iznTm1sF#L1+Sf86LH5CCq+|ur(_)6-0=q% zw9IyDjWGudac2O4k2#lUsdWJZ6(`Fy9T3~#-y*t^b0p(&?N{cLBtTz*h~W_G`i*_3 z|Dzjnbw%=S(V__@j)#_92B%rqCi6P|)5fURd9gd`57> z%JIMnEAEtok2k&ccm5m`iAZo<HlXfy+ml=NuU_VV)XVJS0*E;71r?t{CIjkleaN1O+aalT|4QLvR^U?ZV+`cYb zH#P_dUoUQ+d_?wbRNzcV2j;ww0{A5x1IEPR>iF^LK!DZNZeWc{fq5)tnhqE*t8qQI zH_#pI4yl-v4GmBz(mzP(n{9T+jANe%eP*c8#+C&5UkjI3Jp&`n&$DXxNr3g=!y7u| z9<^v!@P=py7pWBGtI3J8HHQiC4^`W5ySwD>){Eu_9`Phfhh|25YQi(Loj1`CjMc@OQ;d#?myV(D6kSV%yxOe!e6`IuVwbtlnm5pj}nE?|J?y`kIz8Z?n#J;FuWzC*&Bqsz+-b=hXHT%iI0k?@uKrc(#H&?peo#I`tXD~L|U01H7 z``XqPTPv-aq7|st83DHj8{Urd`{Od*-zGaW zrkgYRMF+kvs|~=k={6+VSnGUWZ8h_LR;?1m_u%VbuHKM}5}6AsmW#X&My#_%?*j6(t44@K!B){!-3QKkVl2A;+AWs5&+W7 zridKFSF*MflIC zuB6I%s*=qHMqU4l)AUA{l!AN>ol~GOB@%&!hu7`Bx3Nm5J%)jpRA;pU7HhNL6DKJmh^I_fb@-uIRhPE@_+TRe=zo; z`3hI3kB;6``+mK07sg)7mX_Yg)v}ZPH{IZLX~_DmrDG+bpfmMZr-@LN^?f(EBVZ~A z@)3El2{-L1a_AGTOw1%-o`{fEkndQ1_^W*N&&Ml_s|CLz!PtXT*29ll!{7hAnoiS3 z-{Og17wOowH2NF!qr)T9BE$WQ$kq>jSIwSuy0r&bAL@xOkvl^3XP&sYy0O3$5B`%I z$M^3Q0fHK!L)~W1&fY_^v|`G86Rr1lVA49uX_G2P7Aq{Oc7)Ghj|U z25#mMSXx7$G+XH>+?Sc&{!N3oHrZ~7g!KR3#Nr}kzeJ-=H_Z@TN1=wpY==U{!T%?n-R(Q zJC)Pv4vsCQWY&o&9ZMU1OUvheWvRVyrub@c(w?VI)0j4ISp!_aM$_nDY)L947a zH87WvXrs|FWHkRRB#Fy%o8X*7r@=2yC#_>><)O7JG%r*I@ajJH3`3X+SZQz|J|?)y z{P!sgvzo}%{)d>Szdbr^lJQCR9(^~vqz2-fKp0907#4`Rru_Xx)8cM=U-GV=npW|Z zZP15$x8)aP zl^^%&g8Fu2ZhHh~JtTrixLUNc ziD~sQQ8g*EKrtlHB!GTCI~{4xmb6+UV@NQc9Z3~5udW*0FfN3{t)tM9K%rVeQr#Ebv}LvG_eide+(*x;*|dFW9D1L~Kb((*mW9mb zvW=;&osU=E9L#B~tpGl%5?{K*vW?UoZ*cYbt1Hrh9PV>pQ4f__!D5$EyvADK+n2F8(?) zTP}F~dF3`xd<6d=`EPpBFTsHaMNw$tep(u}IVIWG|3kg(IZjX>qc-63yL%LUP&CG? zdoSxv<7^@%jGRks2E~)`PsclRhY+(=_G6)dr61fIJKwx=UqZp{Cg=}P9O>JJ5u@u6 z#%+0=8n^C8JF?r@CI6^`;7ct9I`owIB|{e7IW@U#(4C-uSv0zD8M@h}7FKsJRHa~( z?iuW*E8nfj*bj=~FB?bZ89V3uw`-%z(PWyNo6waznI!4*VFZ#*H$EaT%Rg=}lejIP z{k?#FBlAa-eOy8N2wt&sVqLt{LK>3CMrefh$KlDmf1OlMEmaAZLgm?iPE^AKC>s|# zumwmrDN%B{J^m45B(lH~Llb!u8FnF#BrTNyhQo2-+QEL>GdRKn((|>oqG&z%(j0s9a z!>~T__}l7W!^;lRDAqfjc5iAlzbW8KuFuNwg%ur}ujTgkhZ)TnwdeP9!dtdCJx7-Y zdIz_zb>$Cz1rJV?yM;;<8`YGx&v?4Q)gNgxps!?yEJC)n&R3ARoqq|{7#>GE?gPR>6| z)E90UXgOK0wBYKs5{)(rllO#S&EIl(XZf!MD_5GBoO3wj17JRDHX^DEYF-r5 zLm_R+PF9Gufiv z&K~hHhAeP=rDiq9`*Ccn;2tzt*?Lb3vJo9`o0cNWu=T)dGiJ-FEM%HWp+RwS@&lP_ z`*8`=wPuYRJi%%)xomCuFgfA7HGlB+@4i2%6#ppLO-6U~Ll(R@$9gUmj*Y0i&Qy!& zhn;$2cQbzmg1wYG4u^hGW>)u;s{$h*P8f4f8t+f$Zv5o0;AYMRnM{)~Bt4s|Rwt7a zKDOh_Ggho@-*mTqeRVl5yvtpmEK(}*M)CnG)Xl*I?VWH^@Bm;*?Uk~9g6+VY1T_J@ zmhlJKMlX%jS#1;q#YjsQ^6Bh|0*z`M_g{q->n?V_ScR#3eSzvGSh>$5;ub+&`9~eF zWGQmBFb5w;<1MI{okV$-V3=$Z`C&e|9DR`)TYS@{yY}A+E)4WgWFHC@vGOthPuEyp z8c{%t@s;1iFsNy+iMsN|%hRsz)O?lZT*oILKFm*nt3kYX>}{&s)rogDa)RRh*b1LZ zx!FtDSYBK6@6Qz5FlLUE01C5!og_J1idL|>430gxg9=J{7|_AcUB(=Ny#NEDPjS*+ zO#fbBIL((brokR>sEy&@@>7ilSH{`eXoH);NA4iy#5U_6_jE}2qPugUfJjJ7BOsyDDc#-O-BKbc zDcxO?0)jM1gCN~`Chq5b-nia#uJgtHW$*2p@toBV_%P-EYG z)B~K6Pp#E2{}M3ewP#VoWogbYpej>(X~bh;(#jRbvrY$0HbO}Ny_<}ehCF@)YXzbhsa zjWS+%!1cn(Uwl$5ztW0x&R=MZD12WBEE2!LwR8a0(ku6nxyO{O99XQJw)@WX$5O&K zoa%gG>8@85t&sp%|KuJZ)o^=3{8$`jfUnom@sh3;@3WRmxEV z?-0ljxEnNV6^9Tp{_Kmn20P`?pRy}Gox8CgXbRTRHnnuH*;$8 zp3Q|KM(aKhKdAXqebMwSvl&^6lI*`==Bd9h^LnYX%u*OT3fPhXvs`Dp%&B#@AN5B2 z54<9=mWlJ})Wd7@r=mxyhZbOlM7|FXiE{o~t=Tt&(&^6uc3#+mG0 z-v4Bpf13QmG$R0>S-T;;nDk<$B4;s9d$^5NWN~JyQg~_11HYyGM<^Z;NL)b7)^Yxm zU42aA2-L+wRQh35KGQHf9#PFsXW=473(ZcdTv0d>%F#Qdv-i>uIVHBk1rm|$`RzSD zz-drAtl?z99uz4$ht!R}nqI!A&A_sXBRPrpGBw_Ebtd5H2oF?vQ@P+^>NhBA%gXR@ zjt?C4SgBscP(<-qOdD)B$S~>fBY1CQSlr;fk9OUe?oJi3V+)p)GPpck(St2)%+LFr zp(jcG@bX@C6|WX1Go7H;k`)*)Sv3r31HPmYhv6#FcMS(5YL0}NO8v^{f)kVJmRkZy z3%}=>%opb4Tc{I8z$S*yMoLJ@8qi3AabVCfaD|7@u18loIAAn$6{{;Q9D z{@uu<7HU>^(i7u3c~}nJ^Jw#klsy3paH!BI-u$X7ENVi8dm1FCVp^P~^w9P@ymyRsfwUMx2EN=MGRH;?4F#s~k&Y@Q3 zAoHKDmn$3St4a+3)9Zze54f~PzcEUG^N?X#FNjvCJ;j;49p^W+7m~si2amc1=y{gc zJk+KW{|!c2*!RBgl1Hob8}><5psT>!6{jaFU`g`Flqe%NZB87BKQq_W6Bzi&1L3yDm3@Qi)bxi=rrw(B>bLQ*;k-;RhN`1L z*hh5(;L(qCY-3(ocCZEa-2JiQ&um50(a;qrjXwW1|J`F|{UuzvG{}W!&=7@nqC~2- zO8HvRGb^{DzZkiM==4UQW{x!**MHV#pfZSmrY$lVhn-@`iWRLanlq~RemD09ZnaVolTj{HW#XLZ)|)Nx-u-Y zP8RLg-yG+E`)`PKA{&YQ+jqrR^%R_XvsK1blzYr*dM1IJFX@WGvlmixC$K%35?||< zFOB{^WYIfPKfmKsB@a>g1_v~vweQ{Y-%k$#ezPZ;@*5A_ zw+ko@Bw;IikA}wUp|F4wJaU@X>3V|h5R*QN(H&z06_}p=@hS@Hn{3F-Z?FgQoPD9n zHUy|%nR6Iie@<-n?4o9y`XK4OmhZGP_rcM&Z;1x?uWCmlP1yJsRmNxLV+c59FTx}S z1`TAwzGd)YW+j+BF*Pt!B!iC;?f#{%o+ZwUMK%|HSwe(EL}Yp%uIB9U%6(4UsGtxH zS?0@*erH}`J)fti0@h38X{SG$jR^PmK)%uf48Vn6(2AG8V#cL46GvAW)yA>bfnGQb z#AZf;Lb`ID{M(ghc059RXedB(04FQ5W$k|Q1gP7N33tT6PBlqT<>UKcR|~0Di+G#> zqcB)|ha<0LtIIUE>t(8rh0XVL<4D*Vvg!dGL)~^ej9g&~ z-^j>e!OQ9@ZoSLpKaQL=e?l*iqw4y3Om;~OEeWgnEvjs6%3saP0J?_Gr*@C%gH3;( zF1#C^X4P&_7~W&!)3($qn2jN%fzKkNIjvk|(W2$)q^C;H0`7aGt7;rh&Ivq)ozNd$ zfXBvOmkN@gT^O_>&dJIth#uhz7rlLopQV#kwXI(=HXJFRA>cyHJYdEkfi(Y)`|#mi z=XOO~L;-c7Isg0g)t{>VJ!85}LF}}QTURAT^i@DVux@1B8Eg2U*1lA~pL6aX^<1D- zfE#{K;8wP9TKr%K^*m^BL7Wb$K3y615f0&kE3X4*HalQI^KW{FneF>v-kK3>KJ530 zKF|}k`N3{C+B3kF4B!!QFZ=_0u18i9Cl}sd!{agfgaV+e#{2w%%X3?E+wlc+Gvkx~ znQ~bJ=_kbrPe9cTt%<$jJ71+zHXp1UkQc4%XN-<|A^9%=Wd zPYh^e2|CSVcCk}f7<^BEmiG6Fzo_Yi5Ui{$WkmMU9gbcuEvs^jwlw&wd(Uy|;zV@DiEGslJ3s_QJf2nOzUBtk8+* zZn@I+FYEa*aVc}UH?AA%m+u}P4!S_aKGEMw5Pz&TZ5GoZIUv3t>_4ZgVwK4}(l?d- z+RZuZjCKwxFmwzHqPtt`{4wGz3z+)?NDm#{46BiVFubE@3|q-c^be*S?#f<{BCxf( z?6l0FJVKga8F2XtYMCmnICPJXsr5(u;>Oq{9qaq|f}qvPOn*EnpEZ?`5P1@-MsQ)_ zX^A?sNkX|#USZ+N{vyKV<>lu$%xNFQZT-D4Q^!dKu(!eDQ>PXC2mmjga}j1@hpU#%603Te&PwAcHhCz${ZM_IL^{===y9g#KoB* zIHZ~Jx}6`c%>*;aF}Mxbk@(ZInsgPW)_;{09hQxBLL;JC*;MfB(R+AlxcEXXb&wXC z+FsSVpzI_6(lwFEbu)wo9Xm%t-JV5J>20`*PVez8cp{+u!e;|?lE0p+YM^hx<4+as zm>(;R15_$Hzy-mjTSw?XV>)tX2~o5xr(vjAM{Rf9!Cm0cX-R!wYp$mAmOAI@^z442 zpl_QPVj@0uz`0{&OMGoonvpY87o_Igm1TVZ_iR{xoEiA z+Lq6O6hZa)2kJqN#WV***t22wDfGDd8rfw}WOcE*=tl$8*=8a1f>Hi;P$sDIZ&pxV z9P~OwFn*j$!r)+Oc0{zaC}^A)NQJ#wA_>{Aa3)ZPb^3>k8d!yoLH_cA%fMvGIbN#U z#e+kwJVStE2b^KP=~5OUY6<=`$IYIP@rojxLyb+Sg+MD^Ps@G;2a9 zoeuG}?7+8yVP9bZQrKQOu`QD(mR^t*;R&7{kZEYN5g2SABi`?oub8Vr!h<^Vm`|d_ ziT6=GD^i3VM-u0aPoV7R?#9c?`rR}apV^j?loS?Ef48FkO*f_DHmXrqK@w!lQ+mE4 z$rH3Df|Am$2G!do% zuiek1{Zy>=zivKeB}P6mW}#t9ZRd^%DI;sw4Qmf1bpcwlieIvY8SBsFEhb<=o99>a zbynl+Q$#p3Wl>}-pRQY+4%@tuiH&bp9RBc*#%zbx3{EWX#eda*Ir@j+pZ$Fu6%`dY ziQcxzh@pZf@{>n?jtN>Q?bi+=4%)*1ACu72LTNA*3L@zdj>>a6WkvMh@C1koq`;Wi z0A!i=+P^xG@83B*3EpFSV>wPDy22?#T_;Wa4|A%rx!;N)_~Uq%rrzpXaVpBnzo}FA zV3{5?;NbS0cNEjJ2nSy9`ru0ZMfJaer-v*_yZp4g z22Lgru!RZPg9e$$D;+S9dj2d1k8KH1Psc`x8zO%`+gkqGEM{CC5Bk#AhsTy#F(dSo zz3`pLhf|Pf1lXISoSQnA^a?A(+PCpLCY`=S$3Y(}GFCp*QL@6e-+bKM+*sV~j3_E+ zXz`DQx@hqZf#PB@A0;Sm(2!2LCIvs)$UGGqqSUjpMUP`LB9{Y!$BI z!*!V^)QvEHf2p1nExGg!I!52vYFevK z3fZD}u}-N~p8bBqe%{G*nkg*xT2T=lZ#1i;w%Y^ye3WV7=7RGU`rsfT{~pdI+n@@@ zux59CAOWBqgrQc1ETCLo4Sn_1;-?thQcF;M+dVFI6zN=PN-F_7BG-R|Z#|r93WU+_ z7lninCn^uS72`Q~cUUc>D$nF2+oNy80Vi4`ML%xrvUG*~qIJmtD9a_fWk9*3P_lyp zSG*j`Qe(}|_Piw^;>+KGf=GIyJm&)}IOcmH>0XZUPZ?Dv{a_LY&l2n82F@cPRRp#z z{l)V#ec)9a;Bm3m@#@6Qe&<3AB~XbxvJHMoOiL@H6jEhjai7YE^TGw|Qllau^2P-) zDxv|x;zmbd;~aIKx)Jbf@FQv(Kqh+8ZnYGa`IM+*dKv4_D|E4LA~K)0FnV0t=g%S9 zg!29_QL>2F9{-i>-I#x8JS3M4bl?K0^($+-a4#<0O>E9Q|KOR86!Knuwgu$&w@NNKf@;xIx&KM9obGmF+T%4wrlD`Yw7Xc^%R*S zHo1?9{X4Kbv270ij0m{#(D3khp8q**|33_|&7u3x|6l?B2Tu%korcSnLTC%jX2Z$ElmT}xf7%7wrz_@kk6FOb1m@r)Nm`2YjUERF79IJsi=a`mK59Gid3p=G9- zs?q$`sz>9;;Vo$ep-81tuI=R|VRd?so>=XR!b1a?T4%XOGZzrmMOMxx!?JHmyc;-6 zB!eH`7-~5$0~H=TyiSl8+8Ci0?L_&4+hft~Cr{fweED1`*aRe-#l036 zbZ}|!*NNFY9%#3P1P>>W18{z}mDx@ef|?tQ>KnbERmP;xbv#bCH~!&{LC$+|x5(=e z^b7O_jvsq3>`k*(wUTt*XoXEf+E zuD=qT z3c(JvoE*)Ed7C1w+G5}DXP2&y783}~oVvj_VYn(TlFG+`#Z;F;2ixh&L1-}LYO%e@ zGfm^izgcJuQa;+}4J1muclR$5R@XQUI_B?i@bGBaI1L~aA5Vlxl8aX-A(>4s1mw9$ zXwE^w!4qi^mJM>xM5cu;&-9rI|&m4$a&tODTVpbnMF<7-QTmI^UUxmb%h@Mnqk zr;**1HM_NAf=6wtnz^9t^Qf4k`s2=(%B1{!4(t!t?Si7`*L%`4P zLP^uFgm>nNI(aNsGh<#7-q*R#J=40s(Dke{3fmUubP@%JtR(IlNEv(_4vTE0*ckfR zN`G~-0pbyBV*okVP3FEmVH_`ek5#V6@*3L@gY@UGdR-r!dx%a2bFk3t0K(_fVe~v> zla5%6*94v~_{cp4TYvr8G5$Qgr&~v}IeY-@KUjfh#W6`oI=0(D+u-nkYDmi7$zFJj zP}BjEw{N^L+_?9p$fU(dDU1BZtRyS+%?g8xKN$Zo6&U}x%O0|;*JTIXgwIkFTEY!R z?_&V4m|g+4>t)Lq*BsLnxc1iBuRP%d7xcIR(&*K6eVjMv`oF*Ghu-gUu3T{F>tBBO z$@VP9b^*f@(DV^>QiY0{&(iQJg(a`5tW@)%y3x_mn@_$1=wj=I<@`PEU`j;?0k~*s zI_i>6e_wroi@r0*6T2NGWQzS57yM@ZvxGFtDN8dPH{(;h0XsXUl>(w~k+({FK14Xe zO`P%Z@!+6*TljcT8tEEuN=q3)5HpuNumw!nLv%PmTf<_IC~ z1FW;O!R6Hz0MrdKLywK;b?6P-hSjSNDZt9{%G`NyL^CFMbHe$(*F80ox<19EcT*Jos3$&zCX^?sB)gc|~i%%ytpaNT@wY?Al9G2EbefT;?hnOgF--xWW zEDxqgUj6DfjjWuPxxZVZ1Ho-$T{@q}CMZn#gkcXi9g@nbx!1tme7i`;zPpl-6#7a) zKlHIr0oVBpjU@0~tAx%cp%EPd2}-v@VfU@o{OkOWhTpH(dM$w>d3La((rb&sQmYzy z&&voa!a?U?7L&8~AX2#XiS?99mqsau&c9T1;KcYN1d3<#l?i1GagdHJ)t7zuso7j- z)ovdqiSdC#N+VO99`)i?y=yMkILdi3!pAguPdG0;4@l@&*}E{Qfq};XQzvQZ6TX7!zvL zAzacjQyBi)u0Yx`f+2VQCqYho+};gJ8q=ePJm>s-g2d|vU2Iyz{mCEe#Wu`{WY3^7 zQo}$3#%Nd9zb}x(@TPgNWI^|KPPl8Ez_ZJh8vQ*V1#oF|Iu`6fT6)+WgS)#y?;>4X zR#|Xpf&KXrRoQNX{n@v_htWsNfeN%o7SPFc3MoV2np7v!6Pdt5O(QDpucK5{39y9r z#bye8+zH=ffs^=il#k|H2D2Nj8hix6X=QY}ts5!W~>~K3jYc$PF)?*bQ zq`33jE%}><(qm4r7k^iSci)$;+JN!A2nKY6pH0f{k#5ZnCC+p=oC&5!F}wYMR+;nWLe5Zfr?$QekG&qZIgBIPXKniVbA)z-+)QAL@iuqHszN3r_R#e993U0q#Q zmRbc;k7or*UniG8;p{6&f=uX_5y(82dJ@VN4N7%R$i3&P;aQVYb<$7n=6XS|T~c+9 z+2V#R*MCg%U~(I1C3wF9ZJIeyBhd(;5YU2hZ|~!S=W_R31?0?LNm>CEduQbe@rF9QCdvhI>Tw zbsRJF{3%giIgEK}FjuS=zH9wObWYJgm`gP&;h4GmQ5*5PWJ{X!F}@4wk#6wDv*ER5 zCtD&`DKvrQvgy%&)Fc3JD%7MB4W66#SFtQbZ_bX0G4`&9XT)1M<}RU9>t&@V^b#Dk87_1*4}!#(eH38yJPe0=5@14s~}e8T?wa?H_6>iTZ#)L zE`EOv<7*45ov!0E@1x$D11zyp~2LSmF zJ_q>~kfY%0ysl<8{N&=&pNhpeu!&sh@Amk88^k$g+COfuX|TPxQohd1VBWW2Ihb-t z{dsqGM8%K#$jGY}K1iGfL%{xI+UH+_83G;CV#vG0XkU%ltV{Pg)jyiTZNfiQ;|IO( zS~`Z+0Wcnbe~OCsO4cAguYk|90I|SotwI>Y{VFryRk=0O^98# ze2}h;&+ONFx)~kZZfe^GfdU*S=S?S6_V6 zlN?dkweE`*o6YOCE(|d7eCu>T+9w3i`oN9`1L`$>lAnlW$;JM#I2+IfoLfil<glK9Uvq#sY|*?1<1wiHaB~-A8*LIChS1(-vvw zRCNpXkv@8Sg6kWM9+);*hJFeLsXyNUfZ@l;px3?ApN$d7x@9(NJCFDJ1lU8~GD8RIVx@87xz69667hbh+IP)d22Jwn8%{Gg8`=i|{ zblMdjC_gam^5%pcFqrfcfI(0U9Q6D@);y&Q_~*Inr$4J^s^V0tFq++R^FvggDa znXI)W)!^N+KHqHv98eFTRka8}y+*@m2>knu5T-H5A6;H!>Jnzg$WZYp0DrP!5)wM68?-uHIKj5S7sLx#xiUN18aH#K``9|yspD!@tOQnd=7T_(g0^(LtV$e&mNBNMDoQRc zAt3-jrJoHN!{fJ2OR#kmCF&Dq!r4Gk{?E*Sx++_kvZh}Ta+qt~{8P=t*=g6h+3KpD ze!O81eIPEPF4{Y2xl4Mda9;a(@(;GX{I}vT(x0xc9h@*yTT2kqY68#%3(DPgL0U=eBi%eHTm&7M9iW-0UO9csU<6e z!A*f~euM$o8_)JL56@O}*mJLT$}EZ)2I*HIE)|p#-m!+u@+?3V6cQraz>N4~Vq&y< zIgZElwzx*7@sav%H{+R|e%zu($7;0s0O0ba-?z2~Os}Lv{&f>yOa`OFy{XRy~n@cB#C6z(n&4UK5rSjakJEIA+Ig|nJfZ-BLRe|koKBMe0xz{rquxBjzp zNgQBLPS8_&*nHn4_HnvQ!6F=w9dexKk7~9oQ=foF9lxv8XB6 zOKIns=H-f=9ES>!VYTCWV>)4QGJc+yv2?)#pPwP)dj)Wx(sH_E>;{SNVgbh7ZT7TM zo$DZI>aQ?Fc~~P=f9j*b*zr}-nLL_BbA;u;B+GRilK$YJ=}-hy`4vxuxVZVZ)|bC_ z!Mq20-|e3EuO0wR=vCx~X1jwBVX2m{Zv8z=H>qK!H26U1f}LD9IYAimuP@|isi9M| z+6rT)&i6K^B8GD{Mk`L?WtQF&TFIlI0^Vl`uHk%5}u;ETn z^H4C$r4pd*!3wMT=|63IPoyK)CyiR3n!sS*xubL@`9t~4DFE4B+(By8i2CP(BoZJ(u04soaqNDjQ0YEII|EJ{ImuZ3dS%aWbfkfT_2K>fNX>|6#AlONp zg$zg}vz!)yI{Sa~E`76+6gkYM6&4XNs*R*F+Q6xe)uGMx<_%F29u;wA-ItBEtawLXg}# zTQHO2ze9XDxH+g6pI838?eskoE87$%ZC;Hs=*fvr`wKW;O}t$mnFpQink0(7DZMRcZ)eWevLA^v zP>#%1w0*=FO%P^WUs}#^IeJz?gIhNJf;;QuF2|5ha^>{*SG%9v{_+*Mp1lDv3a9_X zbbZjH&xyzoG@Tz;d=T>fH$@R1jv;8h#PfSD_SK_gc)J+UmZmE*v)%Hc073o_Y5=UD`_!`?WCLmcGCa#1a+=1zr&Itp;Jz=)@Tx3Z=ni-TOG0 z_sVp^nTtL8Q@|qBj6S$q>(kuh{gPt=4wCQ8{K(GTwtLv0eu!#RP@i(T)GARG*2VSc z_0Di>ol9Q)>I|r=V@|QH>#+x(R&FvGB?%C5|86d$k@}+9sz$BY_v|S|w!p~i3G+=? z#?2w6JmrUvpEfv0;%mbk9z-P4>*6_b>gNW4J6J3+?Ap&__?ruZg)s(`f!13V^i&F8 zUwe$etC1`a0(p!j6mr-oj)SD_RBDtoy4w=o`+Q&!QAg8X0Zhv&X?x|sIti@*?>3xQ zvUO;+z!c3Re0G}M)N_Vt`&RcepwV9EV!6Qr$8W^ezWCa&U!|Vc=eB(fT7Q^r#yl)4 zwz^XqFp5u0l(ET!%?aTMl~q2SgArBc{OlX94GTMNfw&j$dlwFQEn0CYB3Yp$`7x9U zj`|rY9W`}peVTkhn@uKH0yn)WgKCVa59M<6_r2<&cQ+ZcH_H}x?X{ozAk?@|QeUQt zZS#4%;h$_S_MRADuF7@9449#%x^h-k{dAEn`-~*ehO8~{>4IkMdhOe&@Eol-Iz^A| zoRhW3*XCvX@&Jg|eDx7k@VpK|A<3pFdf{;2Z)%DjJ!6LN>Z_vYTYs#cd*cT$pNj}S z;1u927Mx+9lf$e??$a*pB`O}zZfUlyy5;4cNqKtupWq#JB^Vp$GckSZuKq3<6omHB zwnMkpryX6lR(e1{>w9 zNQq>q7RnciZUu|W>gyS7oxi6_h~Zwh9TFazqG2B(O3oQ$%J&o_`bkF@8y4jL zgp5sE!ob1ljhRzn;ffMYo>Mro+4%fGo4tXKCx?*?F zRwQ_2t%;&v%p|?r0RNc%xs%+8ZV(t0w36$jOG6{rXLd8=F=o5Ubb8}V`)dhNp63ta zE)@wEq)VBoIsavuVpQ5g%M(&w%MO1;v`VM>dKAMGa9^Bxt0Mn>F{#HCu>&hBrECj2%p8ko;;B}~tQ zG)YjLtZ09a62bxnmN5-N==>+P)gjH}-*1^{)*xKn1na@pP?}{X8(308DwX%Etwklw z{kt(|otJ*}R_!q_Xi1XXMQDOPD{<%HAGV>z)M1xmJ}spU`FrZ$NfeEwfW+s< z98(2jy+|IS>Wia&#pU$-P0RH}b7+K&bHv%1hfBv-8@@<5Sc&de;*Mu;>Q7a5-Ubrs zc*6nzOVdOwOiF&twBcihS@z84MrB#{wCDO{^7kK`_X)Ot7%nc9c%&0;Xz0zy6OG(g z5ztuBz11lrMDqHc=e_1aCgH1s=(hyp^ajGx7qdN%5JZC`fs2Yj)Ii$AYl7ADsR;>w zL~eS`?d$`tIz@q77(ATi=+Im2fUZrKhZgde<@t0Oqxmw%zEC*@!1?|y(^3CnP`xkbJ3VkYqoZ!ox@emx;}_WRmY~1>f)UHuOZ|)= zQ;bw)a*FYU`a|)nZ$Y)ocF`K_*m|o3s;QIsuOis7yO-OQpLx4H6g)TI-Tz&ErLb~L z;XCBP>#|?j{9dE{+GARX7t5ewuxi09{zEH!&Zqi>=yNf}0e8OoOR@R}NF?XW0P@CX--&r^b79pD@ z!8|(2U)_b>BfGk}JfCx9u9etKVZ;)S9Uq{`SRoSEIlv~7Gg<3$GDxO!h!c9Hfk2s-%d*}Wm0=uZn@<9yIq&I=KR_=}nh~xUK+5wB}H=lL8fz#sv&G-y42&g7NKNbP#!L ziK0`UKA9FpZ=&Z3YGPnyq@}0tMQ+vekPZq8Vq#%25HnL)S=U1Pfxw6HA1na$#Z`$0 zP5d1jZf;Q?oaB}q+ihusOB1a;h*R-`3_c06*qMf z$5eLUJ{Ki{WLR0cfLA`g1oSMm3*AdbhGrc3yJSKAAXxq& zu)C34f3Sx_y=lbX?L-7gmlk_3hRoQ?p-Oj7$}>ERdk%$z&v(5IGrd(G2*4NA@is$* zgQu4dhXd<*oYFHEnx9)jja9QwblB@O<0L;)2G`=u^;Y!!zXsJNtdM@oaN3OdBdI?%Kp33Bc0h@TWja+bWp>zh*~Z)p$Geno&Jlv4D>4?< zdqWhV%F_!d%ASH^Kg#eXD)+jqrbtfE^q4rs8-`Wj;ziJ#fb7bFQCRCCY`*W;K=47^ zuJdpzG(g{XYc3@8C-v3t7G+!K4PVVWo)Sfyz=}?io_AD)wRS{~>=#}Hp`uqAbUGg z)JIQlQ4R_=fzLJIwxi)o^lIWk(d{%Oq*_9|9zjh&JG#yt|0e&%=(<3fR)rjAz&O&V zm`-9d9;!yhkNBmn7k$Rb^7L~fyQ_7tTqGG^x)`&D)~(d|!s1nWS6^Luso}Lk&ZOW! z7tPvlig^+c4Vluon>IQ-+itiNHP^Xf=L(>?tsH=JBVgQju0RR`*MlwNDaWE*VHPA^ z7$8RRB&UO0B~T<1fa9w>h1uP)!z(&pOLv5uw9%FL9u`K>VS{DEt>2eujHNwPE{(~ltHG2C~5?08^M6-`uw+YUK~#ej-H0wB|cu% zI1kDsU85`uq2)x;_UqwZ8~m%j%y#B1osoiN{8jd~)xVcc`F>>?IB~rhRz)MTyg-zh zYkKZ5^aISQYKVKh+_O`8xQVF%BGj69e*9Rc{YvvLo zEeq@p+b2JLsMyQIEF7QvhqKykj?a(9ue%$k{AL%3yZKQuQ)fl`6zk(O{j_dS+jO+c zP>bNycG|i{`PyyMz3>mZ6vU^$3xWq3kwF7Qm9>M z>Cf@Bgmo5@-PEGoa^uY(oe*JnZi}yR5z9ZidRMqdxlUX%N%;y*!T1V{K%wVhLp z6-LjmuC!1KQ)JV2flJ6!XiRbOi&2rAie#~etKOfB#_hF_#96q@P?L*BE-W05 z_k%YwO&39=nD0(O`&!Ec@~ODIfA)wRT^HxedrK&%hjZThu`s-T!+vBh54taNs=9G( z#$Mj2?@G+64?0pr;}cn{eOr-_(*l-2qQiZT;Nf<;2M%Zjj1s>V=m^182o>?3=+xAZ zjFmp4;(7sxVp-x8d`<4oyYy0NZcXy?RhVU<4zPYkqpOS5BKJFdCB2ZW=xvFE9R zcbEq`3w`c2Lv1<C`Mp9AoJj`O8Ls4L4EA{0#2Gg(S)bBGjK4zuvw( zdEf{VAsaj#IrJnR)x0=3LT_!)TQ#2KS^eUHHyr<^$74KiLYygqnvH&(dSEi^UG$_| zqGWF?4_5%*CM{5!wPSztUbweN=M}z4$C+=1XW0SlBC0 zNV%3IGoPT%><)cIDOkZ9uci9Fd+0N>qW zMN%(teI?*&18#nD)_x%?dy1Z4+i9UMIR!3+Q%8p^&rhzduCUiPHi&<`mG;0S<&9K* zfL~1y{R{Ic+cHWnXn98rwK|u`0l9O z;d&Z&?+mxeNh5s}4o2KP7u9YBBn@73@O~jgKnl&VES6N3p{JqAO$~s)-|61p+llaD z*UH^TO2P1l5v)Lh0`VRZUrjxP-`Ui7fkA-i|1a7BLIixw=b5J39bucP?3^d);2`@1?895gy z*b7RjBcP#q5uK23p<*d5C)ce+86|2WYh36gUW`Hag@n%}^gG$DJbYgIUQ@NCuha;W z5JD*8aCRuC;XsLLPUw0;yVkjZLlHIJrKW~z^fcwJ;b!aDZ}5sGm(F{ADsyg57sum( zN2PIp15J-Fc}lqy;_nYP%6yc1tM*0iBX_Jugc`m6_cX2L{9pXZI79hbJI3VR{Jo7hUO{>aKR_e!9MpV6$BRXleb!PS*o zoHdY!kBmhQ8;&pSNjcgc)Xq53Q2NuGzlG|X`z^w1zHT+DkTFd)2gQ^2P%M{7WSnup zqJ_xPQro2fd#>0#Fho6JEV>k*%eXr zha)-=`N|UiTK)UY+b~+ z#j!@;-2RD*2mMV-R3O~my|GQ98`u;N4Pyy$ko~WN%dkD44tle1yt`NvcK>{QZH(S` zogsa@6|$UWGYm393;OmkwKDZY-N6`=`}G0r-voCEo6BcI11r;XHZb)J!B_F&xdxoE z8G)EUUg~6t|5p%9(+;?=f5RDtQL?n`I(u>2tSHE_)?eTfFP}dd*JlE6ggTBQr*Ilk zD;Hn#q_Klc!Dy+u$UoNZ&d$h`^321UVy=6F?LbMzKuIy)lyp!0$qI<(fJ!4W>M#LmA~d>a@FfE z5gkvLzr5Dci6|{)YgfYo+u#Ma$L`^JDQ<*YLZ11D1N?8RxnA>rAMq_DZ7%#M&(Tye#qlBR-KI!8Bred*zE(oSqJG58_ICdX$r>%*tYRk^nSi z8}QqcH#U-`8ZixG#~Yj(xY-eWvWe_q7hTt)Vuu#9d45Gc^NJBcuWuuHlh!v784~I>9bmHK<6j%q8cG%zf109D?z{0B`=Vn%cc`n zh%auOXA^zWG@|~SKD50^0d*i-b}@|xVqQ$l{4?5kot(vT?iP{z>C-#27q^;anpD6t zt$w75I7Aq8|5PJhkw8jHbbR{zXLi`cJ3BJ&xIXze^L7Rxfp@EDpM;5rptHV}*~{vH zl;*~n`i8QWLM#X3hYNl8?mZ3@T=&Lgt>rfb$s}qL3BkRCpvRRC_-DVY{(k#?dWj?( z5z2Jz|2mCb*IH6Gd^ZuJWyQCvOK`aTMsbWG)A}u#fWhT078eAKtqoK~bQQ)OJjQN3 zzP#qWsWtl-s9v*mZ~| zdWP04!ZS@+5rjhKJh;Qgqqh3urx|R%ljN;qqHyX3=O|1@exrmLm_yK zJyl<dw1f9dT^+a4GdnRM3_ePN3Qe68wKFJHbejP*s~Iau2+it zLA&I~+P57s1Vjk7E%n5R5tZz6^Kp{a-coD-fs8P?r*|~E*Rbq~dp_03a%6=yxc@w< zjetH*p0@s}q#@K{^QF*zr|qkd_jR7Z0X}4UA2(N9+U~C{!0zeqvJ+3witKrATR_qO zoo{V_NSjEq7o6f^6NQ)wE5({}aE)^&Khq;U-MC^JAcw^c##Lv`rt^r zj$GnsKC2r?N3S=J`d~dp%OZ%s69zSTJ!6#q`gZ_1%hSp z{FuSDo+Cvx((Ffp-LZVnRCQK`GSwwps3?EPvgHG;o!!yWoqI!(i!5uJ*F3wtg;s`! zxHvpW`F$vBXeL(jhcqir>e*IcON7X3@v@iuLmZ#KdpM{+ynj|3RK^q~!IZ4`L3dta zaHLp$JtwsvuMcXxMpcMB7DcMAl!5ZpaLaGy8{?he5rNP-0k?(W>m zT6>@GT>A(0jH()=_txIlhuGVh77x!;Sr_x8t)@wYg*k2Mqm2=)F zeYHo$V-Ld7Cl8F8H!Nn6t8?O%_*X($<@?$$gsRi+gAy*QRISg8)Rpp)b8qT}K$s5c zZX;*Yvj?Uh^z4g;Nx46GAceY%GyMCzaPXaC0zzufzHsZY1MD2sI03N+4{;!TSQyl- zFelpOZ;6~{LBBE#xZGg}gRyFLRK0IjgwTACj{h8?B)|)(ujf$v=VLB@$!5m|zGj~U zSW^SK+mZf1=q!_8)afs3nnqnehS8X3ve#Zu#27ULr1 zEC-i1zKoO;vvaZ^L-*)Pv*4Ni7;R4S(8U3Hu^y`JPzy;p&614ObU%y=DS`xJLL%Zxpg2!HcorJS60tt57vG3ZCT(EA zMAjy{z*6Ep#7=c^U$vg^Jp=@Z_gCR;%7=|>+Ye<`zP8`CY9D_dXnc8 zA_g4i4b=GIkVPF)DJdwu#A2~Jg6tTis+20_jl@ujR&nfuKgdHnbpw&FgYUjZSQz;j z$`F^9XzswmSd`Gq8OnUsC+;vP?kju;t1&vb%Om>4h3`L3YBcm{Xr zOV5IK{uN7mqn_W9hy6=Yy@M;(N5Tp1{cv zt@0Lh86USjJEnO9HIltwIAx}Hy5_g5rWZ>Mj0iM*N-@{Z%>*?ya1))JgzVh`B%p;F zy_ZJ?r?*;yI$(?jzAoB8X=eRfMv@UA6=Cx&Ho7X*WE=_e zyk=H!p0S#J$kc_kzc#-X#@)uQ zNlr$71&!O*(!0IOg|#k(>IYYO-VP{OOas25V2BAmsxt7hi!r9G!XPwVzjqya{RTg$ z?a7~XOS8b6%Klv83o!@mP;0NGG{4420S1IyP4th4Y&P~zyhM#-RjV~oX-13pw3 z`b&D^j6~ssG0#Gw>wc$K_;QzR-Ly=T;Fd0Mj1C&C*NmSvbU6mg`|mXZ%68Zvhu@MY z84;JE4n{%dW1U7a@9a$iXd=)%MIg%5^Ap67;z5cFe(8DUlj<=C`q|QfsYu~}Kz5of zQh0#UEonY`c3kmMk0{1AKX9=)fKUeGuLWCASE&R>b4b1tf%2TmaT`i(eI!Tpxvf;u zSbp(;6AMEZ7Yd7zV-+c9n^;Y|MhB z_?JrIJunEF>VIQ0fYC-qvmzyWT!kBl4OFQMafnjVaARaJ5K#~i@v@2qRRRd18uniP zRFFQ`h+Qxw#mMF=%}3us`H>dbha$-BBkCg|z|ctI%@dcg%k@3les)`tHk6|h1iwG! zxaj!7LzK+HH(xnQrG)N#kd7_j3ns&gMhFjAs(v$L+1mQZ@p?&~rCp(GN;DNhpp61Y zO+@rfAgCx0^3UTP@=>yK)P^kBwL#-&p`4RKD&hH!Zi(3@dsUi3ZE;W>bwkv3MbJy0Y!WEB_ z*5s3yvT*8WEz@`tJ46oIZJjpJr!|*?ZC2_TFQtk^cmrWg8`2y@aKtDJrz5v6-d>p|K;)$&ohXHA54I!F{h?x|Sy^`4C0^MGiAlIuL8-55)F`{TT{sbX?foB{(qM5FX+i&LyR{yfZr<|S9Bh(XXG|6 z*LVRr^98WTSacE5E$VsF(6zTOk;lUb#OiwmP%Kc$#YoVfsb^IrmfXQKl|md{x{0n> z9ey)|nVJUr;~Z!3%D+B~s|FArHJ{j8Au@6e7>D=YB$BL#vND6%g!dZ=9o?gm2ISxH zL8bhggJXUw-G1miu``eR z%V{faG_P7b1neaSc0WRN;$>uUwg#vv@tRV$ ziO7sJf9{=A({aNqpx)9~3Zoj+ZfG?=uz9!=Od5xBJ9`!*5Zv|eyt|dXx05D=f)4iy z8sZon(U*(69%Q|RXwOoIx4hpUbNLg+@!Fjurg zgJxyy`6?>OFy%UB=WwJ$nIJ_ymSkBT zgAg|7pCRr#?LU~AtZNhF(DUYpTASOBt*a6m<|)2mH(<_9l@4BMw`sC$_J!q}x|sy(Y{!{-I+u>1XiwC^&r_?!nX8bX)( zC!P30tk{8t2pQD0Ok{HqM@(et@lB(3wJ;yq&aFK^?|r(=)!2KDUd)ht&ZBLr5BXZD zMUy48Tf`vZX4+wO7~I2du2rzuC5~6p`_<(|zuM1>MlSJC|1pcT<)?bOmf1CHQZa@FZ@E)}16mZJY4-&j=J@vqQfJTlB10;Bgx3T_Y1!R^Z9%*@6 zkpCfNyY&QnO^95vwchpdd2&} z3=iFYexBK-oG=?K9B8Vj*4l0uLEkR|AtYoJWcM>ohl`;2Z zl?l4P&<(Gst7`ZTDMdn{)CF^ak9xY;iL+?x-Hb3(LHJX7Hv9_((t+u}NRZKCoeTVq zJgx$2WN+-;cLx|#QSzTf$P|T==-9(&auw=#Yk$JxFJSlg)?d6ix%78h zTKSR7>hbSN|M_1lZDo?TJP(hjA4%yJiah`*i>U^QcCs*9*uOkBL_txV30C@y2Dw@) zz!7N}JJ;ZFWipZDO`mEphuw{`1<|${VgG>^WXvjUKN-Z7js~<)avnEjhPM{a)(t-F z3i_4*WdU{ygVb_1Dk0!*9N^g|&{mYlLf_2WI9YYL+}+GVYWWUv>sB8C!@{KB;mJ~@`E3bR?4Dw}bVdd+zUF-Zjv6XLFSa`A-|pDy;h1am&lD-#!3TqPntd{I zo~%HpBzb#)hk!B(^cm5|vluuZ_b0m1)I)nyBi_?$WavoZ(OA7|Qg+ATi=hpT7@}Q| znxdhP!jtQDd|bMEj#Bh?Rk9vww7MGsyT zrs4V^NuQH$rC7S$XrV)vETX^qhpbz@^$z;Vg|J~F1do?{^umo=$=CdVmEYfXz+@p#1X8w(jHUn+507pP)Fxw=pvNsLzcI>eIwt$!Rw;>Bi{J zU~}v%nhdP)ccJm)IF|#bb889zY5d_Lf&K9>^ zU9GEBkRq<&vl#eQ3mTs2n_=SVm+Mt61iLmgn zaJ~N@3kMiB_8-Kr6s|D-omTCf}q=mM9XmR?z%tXft%p$ zt|gqT1m;A(m<$h-(2Xs)Wi3yTTKOd)B^GIJFi~~}5z)#`ak>Rt3ml0haEw(4X z2GOgP1vqJY2J(vGKllK%6<`+X4l}6t)duzTOg#Vhi@gJKaSCv9(AoBv1~zGk`2;D_ zf{%!^Dp2NGY5shy6T^r(yCbvFQmIyKWHV~T7~6!^NhfNb%4`b-9Tv_a7wpfEZ<7!v zEcYBIZX@71RFmy1Xz?0hMz5698s>VdhM@t@J}F^jQ@iJWwdgw-FOYM&H2sA&OQ3v= zYmfknLF)V6i359Gli;B3;rIexzWX_5H>cmKf2%CiVj(PAbZH0AFYf?Ljm}ox!z>_jUmqK|j98gfl?t1S>|4M+nx<{YF&2 zr*0@$)bcvo>f1GPO|AJX?Oz2sz@^ohcQ!d3{I8B%+|-2YQ8^lbt;iMjRhN7)o7a)m z#q?wh{Oj;t6*rd|9F3ODwd!qKj)TxL?=CJC*94crCp0(lXRYX%OD(|A_jCire#8(C zfFMr2t3V5XOQosm)*mC0P-TP=4CmCll*1*;MpaRo0f<2VABp^AW!EezD!fV`3(3Uc z%VF^)ptibZDlo7ZWRaV`+4;x3}GHtT}Z`!`D#l1ciNL zc&I4ib^`2AV4`Zu6ZIVP*C8D}s&LYq+%};C+U>sSn`9TUXD|4{z`+%HTafJZOKLov_vu&h}o{lc2+m%-rj%beojHHeEa@+wd8l4jB?v4oZ}68d~Wm%T5dL0OY#600nY} zGnudmnW(*lu3>9Z`m^VQm7G*2YLBA&$lUy1w0vl9Y*-{3^~s~}GX1oZV~P(u4{K6y zR9c0A%y-s5>i)l4YW5~msw8DDe?HWUtC+?evYS|H#j3fIN1gwkn$?3@Uf?DEt9{UG zRYWl~{|hRN>X#(weI1)aPvNi|ylLIb^PdQAE}fA1PMy+Afuf}Dk?FrWSNm6nc+Bol;AA?$0m>8R0t)8*+ z*S{86K3Z<`Zs#K%?W>TkMc>@pZM5e#v9D~ohC_@@;lM>gb;GDiLt4(Ui~CHUX(gXT z4X#8U#)qT*uu$Uw z&<2~5kP6ZG=4*3POuRqJsuWFfFT$elKHh7WK+25@omUFXk;y)&9raMzmgV*I0xVz}L&k1j}ainC|Lu8c3Jkn4%%4ss_@C@xeE zShX@OrtH_KRmyMd_{fAu`q*%=9n;p8V0odUCV5lduO#Kfa5q5~bb2$vYyr88-@xzc zb2%2gIgm+b_FZ-_mk3cY1?!^xFFHi)6V4vyQaK(h9>KtDmFMZxVR7m@ahA!dxR5P( zw$VCIa(JaYV*pw?D9feM*R_H4N8jN#g6kg4lr{Q2J~l<;Co zMwiJH%Y>R3ghga%^5v1HCD_vq6>8}U5mm`q%xH9j*WDUmKikI4L=$rlGSAAvI4$6( z8OR(8IHYZY?GnG(P55K>;PrsAp zg2~6Z%uh*!=u(TfET6I%j7nx;WRwhWLNGDK`J=537oVIa3ZTN8SmD>9vt;R3H3A+; z7OJs;`k!#vDX?Lq#7_Yk;BM@SLW{MraoH(nV9+WS8u6wwp3b$Q`bTnU@w=ew$0 zp=RF_l$fh918$yyWev-tJVC*W&H9mCZ|18$xtX#@IJQvc7ZMW3W-axgwtxAR5)bUG zR7>x4&U^L>H)Xv>RLH{S!`f3n*04ZB?{pTJXHfu_)zJDP|=zB z*>56bjDbO99uEm3sCI@<0U5*7;{?CbQde&;SXNt+xbxLj@5s(Oad+% zY(YW6&p~T;osS{kKT?O(jO~%P;xThKQwtdMB?Y$|rYr!Q5vjT2uHq_|Ymf)p-V`py z-3p+zyBzSK0>s5uYoSy5UV|SXyLmS+O9g)1y#|1rzj)4jgeKa;ql8ecLxfO#!xk6m zU1wzBa}xr>IkjZT=@5L*LL_g`jbc9Zd|_u@4_-Dlyzx`Qke{hBERU7oo46e?>kW}S zy&4HeVi$3o^9HF5aNR-z>3AQ&;cSDKZ|#s%NW0EzHr(b_x!uq2OdB5flr@&fak8C$ zMvNvT<_W@wlPlH&@R>&QAz{A`lMECqGLB$-XZ0e`*<^m6J&HfKg|F-AErdL$h=AS& z5^3;pfBt}qRw4=-PCWC2 z=rz&Z>kZ{wa-bGB)4Av1m4R>L{2EKBxDaVut|$5hE6djB%@ammUSO?9n4IUrn&&^j zUvpSlH2e1C%@aW$Hr1P_w|;kkpmdag(|2c}@cL0HhibQ=pe^GYfA=w>P$(ElGWvz0 zzL3{oel>(Uy%Zuj-~(eO&z{7?%2M3U;aNVNK7@}$Jfvz3RV((f!zjDtJ4M)!G;Y~< zAIoHsXk2UGU;(~p1V{(DO~)y7e043==W5#ip?WCm;fr9B&)uFG?Q_~qD#(?pApy~p2m#-(6w(!%xI?B5M)Cn4I=l^55 zb-l2tz7<2aiz+T8zs$cROr&OHcg-9etvi0CqQXjzq&IUJ7VKb7O;gExPz!%Ql&+wl zAYm;_xG0(*eF3ekU$@^wRD2$2Z_0A`MjXW+Hj0Vb55d6YM=9{V$qZ6DN?+UQoz~4B zw3nSrHGs~u{1HiKg|mYap|1S?%ZHCCJB{%hDk?&1%eVv3y{alJB`p!mL^o>{Hr9cS9Rha#z5^j>%rN3a%s8v5?N${8`C-5I1j}@ao!(KyL?`C#v}FhK@(4#bmn`!2`yKHZ2oTFX7yRqQ0I@vp zB=;a|{B=tZXdMv#SL@JbKGqaWa0Q7kzykw(&}gV}*4Duq^jX5*Y(?Q9KoT4r%*P>) zF8QpG!F`+SfXj=@z)(}KK~so{g+KguBA(d(i|F|da-7%>Ts#jg2c$v~%-RRbG_I_P z)hVdBkU${NekxfcdOnh@N18Q^vaWJ~rT{{I9`VPf;-KEpLz4pEUnbe* zflJ999Kjdgzew&@AZ<0z5XWOkKs3ZpggS0GTZK#!kK8o=9xia7x#MJ|#A`^-OC7Nm zemgx(-f{3%tywsuh7k!8~zUL>zx{$Z-!aR#aw zaDh({`)}FbGsc_E9JcIt-%9u4AL*5&CQ%eVa9WC>u z!%T{yDlXX1+42@+7x#hkNG_W%%%tKfV`CW@OQkm!%MXQyFFJU%KEWjT5oQu;7KWEK z7HG6io&&c4lC2QE7R9RVUNU;A<9$C9yeaoh2cJ54z%q&~n7N28+hKOK4a}8Rm8L_h z%P!bNxK-xRQcDcAK{S;vp>F`IpOo~lr&8!yi7$>Qy}0)@$!G>ZQ~Y5VX-GwL1O?m> zlA)n9cAhZ$R5A|HR>yVf12L-dv#UQoy@@WubD7(o63p{^_`F&5&^$bE%XAx$E!1^C z5|zwtodDJK`YpuM>w_qtzu|+F>VG`OZ4c-}G(kK1-^~<3m`!zybEIiGEAq>7T0@IY|H7*$mkpj41&qGc$bJA!)pykSOir? zHztw%AH+=P`Hf7K?RQpCyJC5$g&HBbU|VxEF%JJ$X|hA(pFrGE=E!vpM;s%9X$xB>0vJ3YKmVHRYP5R~5aE`M*( zt@reAIn~fsbC7r5Rw(@L{kZmC{I10n-Ox+mO7)Pi_j2?;nuXS7rbChFI- z5=}_mvqmIXh_*zF5k?Nx#4vmPprD*D>U^}%v7y0?;S&@!nn@R0*Z@-v8-Go$Y6>nE zW3dHRMSb3>#ff=}cDkKm^}0o3R=J#+2E(hn{Wp+>maaQ7Mu_{RHnfSM7nI>^o$9O< z6Ru=n=!3Y32t<_$X}FVR(6Y6;xyTVvasep7G17@HFjHB4-qtDs>KZ)GXR1 zM8jS$Q{RFz&&?xVbB^$-TWqeMk96Sm5)l<$-Tcr=u$4-o-p`W&S#s>H%T_J zUrCYhr{ld~UHK2T5iV~oTM(L~un7B51X%3-6*=f(iyc+Siml(z^kcC+9~KY2FgRxk z0x7W!9{X{(XPS5lxAsu&Y8d4PD~>48(4-e$-@-IVdNF)3pUD|kE-+~} z8=^?ONULfAx9+>RVMGN2>|ao>YzJ(i;nyP5L?@-AY78y4Bc;GD!{0z;7OAweLF?*p zVfz6Rm=dd@WAL%u26d?Q9I6Ztd+i4p{vYm*nrZd+j4EfJwOB6tuFOk~u`sAz&Q(wd z-F1;3Vh?CHJ5s7jcDEGAwrX$dVJ+^T{t4ItC-$!4WVb6@e)M0YN9cc8kzjN3;Ai)M z*N49YDPT*=%BaP}`rxalf)LWA8eKO`M4l#6_3F(a@mLK8SF=~3IG0uI>TQAs`bIB=T$~F47Y~fIR)HRx4i@MO7B|ed!DYW)^`YPq=HWa>zFphe-_`}iH>!ldGVRQIjoj+2jb z!wFy5zKvr_p3S5XKbn0h;tu7z(XA`F7Jf@Jnq;n&F_wnj(V4S1xo5>A92n{NLwdN# zh|lEai{85+N(_{1#%t>}BRAa1-Zd+2chAoO2$z?aaR&$8vOGX^u=|_JapIq|^ZuZl z1>L{;{O$42ZSjNy4lSgH66xk>jks}Q0#|{ke=SdEWiHk^Mo&NLY+kwhs*=Oad031- zKcqxJa2_5~)JcasO!K=|O=$5qTv;&nJRf7Pl<^9r#!km1n8_fM3?TeVU-$T z3Ish9=!lA9>L%1kss*xSH({xq-QYXkaZ?^CiT*Pv!cTJXkA@ul!#~M(R`g4DCp8#F za11Q#y}Pq8d}QT&C`A-W%BZR1aX*n}Cb7nSb*pRCK52B%X~YJ%i~RfF1KjtPZ@dH| z46Bvh2XZ~ncb338;DKbx;kynw4u|`kZ5s2!B9XQX`0#wIrS_peZHLxR%xSVVJ|V)PqbZ<4h{j3{ngSkx^4!tvwoY z7TZ~YJV3Ue$f)A>Gk5pXI!*GsEz>^IXC`SW@8PhgWahQhVszXcTQ7F-BP{{B(bd0G zZ1~r4MxLI9zeJO?#Q5g{yTje`f#0=1!R=rH~jFe*R$?@7B%?$MiMHJt@V z9bY6GB$&=ah0A;lx;UW-<4)zVGt_LmaU zX*n3u5fDF^aHadO=e-q>+{6pnh+?x(hNTuy9=HKX;4^(U4GOKTqFg!}x&(y%CL4*y z;tQKVhY)SNn2WF?fx8!$+G&QgNT+bAJd|y|o9ihgjo1=e+~^ zwg4bS!433gK5ky`ea!*r79KwZxqXYDgNsia6HV>$ioPQ2pXTFSnnw+ScOKV8Cn?Q^?|_@G>eyuUrq#s7X4kU(Tb>` zg=NjPb-)c5sR1m;t7U2C90bXxGr$mQX${jl$$-nZ%`(EVd#eFjH1Dwxe!;e=gnEFD zLc%>|D^bA~*v!ADo>8KS1w%q(X<^{eymue~&v7$6URu*Ve!ORms=$_mzILFM(Gr|` zexe*yYbPyy8RpuFqbVfvelQxH_s=Mj4ihys4o%sGqnPnH{%c{jk(pL&7)->E+8^b3 z&K#|T@V5OmLo1P-;-ot9r(H2DM%H_hGBP5H`rqsMY;zdl<^-FoLMp|R$wdLkX7sYc zI1d5e%jZLk(6d?YJtq$tmNmD2;K&zDahAw7RjU0JV^uubn6u72GMp%W5wpY81Mg-9 z>)*o$yr2zuC;8q#U&;Q#9-fiMfw;0pyvZ^UAPD&S0zWu3^wb;WCkB(Q6djE{+!o$h zyH|YVi;RQReKH#wmCSS9$w_WkC`%GOHofOFWC~<#d&RLP2faxrH>Xp;Y4gU0rmi5Z zbdPprVw9xVCLilY+CJ*!%Q0&Yxu#y+aH+4cRSvB8T>BLDe^gM!-WcJ#o~|WL)(Iy% zd|N@K7`kx-K$LrR_0y^=ykU~>oaEPkQ+a&8d?bV;xNpm$O|Ef=X+)R1E9IPCN>p0! zep%-;&VQWRf`6;-i*GsZd#{c@l>6Racnh@95qi;$3hNKxrHKLc|3YPPj1el5QuIu4qS4&(X_}||PGQ3pB=lx_7JCZ4{J!LtSYq6pv74##q=w^EFUjq>klMU02yky_# z)?=&L6AHY~x<`fm@mfr>qO$^-0foG_6JK!_6Rk91nRxr4pNoe%2N1H^RxlH6j3Kc4 zKk*5Mw=%RT4Gx{X*1^bJ9vt+aL5etEZf%iu6c&c2YOd}$iwSkvI_6Ez1J)ri zb6W*k=4=~~!ufB6$=HhZjPI-UxUE3y6F$SYtk^#h#4f!RIEZB<`M(FRo6}MIe@2)k zK8@#0T<{bmu6Y({WuGD$x za7mu?fJ&QTZmY&yeR~!bnj*DHUisU%eM}r0z(pY)Y1sDiIXmIhU}z_K?I4t~)D#3l z?0<11=#qM&x#BZ?MU6b}(FXb{q>!1pPdEVeiEHe`eLQgi2qTmk;heu^C&^c4-5kh2 zg>oUtSVRj5jy`BPSLz_FdXxuX8YF3k zh6v61-Y;)cohXBEJ!>#c<$yUeJVdMmudY;6)FFRLox?HU6biK}F@WhOOZc+-=Q;xO zZz~(u{UfHhA8A1ETlAT@HH2cmQ%F9`hUMC?A97!enQkqK>Qal=upWM-V&e zv$3oG#k{qJaYiBJbP1FwXcjPCPr7FFt2?4cn3iHCy1^Sa;lj<1AJ!H^6fs}9i zy)LOg@I*Bit$~x2bhJ~XR&C9@gJ+Pdf1K~WIbPx~0rS5iw=4#sYM|JrV%6!*AA+t9 zX#QcI5WWo1?7Z?I}wO(dqXEiz|Nr&aJv|Wc;E=ipa3dX{9d{ z>=C?*3*^jm_3pYk*}a)}BR|u$yX=x|f7B9e%{D4U!N`q5$?jHQ0tjnf6TWnW6%`Ob zov$N~*Cp4`AJuI%&cKOKPXPn&L!${%1fch`NK|F}Eh&IMIQg8{yIvgSRbk*Ql7Td} z!2Or$BW@?Wh^?pDG7;xjy=M!0uK{Reh9VfLb#5Zz<)pjoRN>8CjbBBwQ4sd}V4k9@Ns z_va^A=@teqTvZ_v&Iq&Ji+2TJE~xK1qW?njeiQzEAB=*(jJ7bhWoKtc2&SgEfvRa+ z*E90=@>8l{erqo*{8E{YRUEg%nGw;y7Y(7WS-a|PZ5`R2_7gS5&vWSWT)ff_c6!{T z=3Lerll5vPi8hzo+rN#II%X{YNsg?TG`IO9m7i+;8}=FdUbSnA_KUrK#AMj>c@QJp zIK8(^+LWmEQIe!p9{*bhR!o$_Dktac6lHOyq3ipOshIvBvEQpSP2Nq*B*2(PkpbM~ zjbQTq^Aj{h(P**!*NcgML?5@9?Ut4Q16~3UVm#$$6w$uH`R+P=&`8(SlLa7;tIe}9 zyY_8TH!ZhSkqG5t0!c&n`S>w~D0G`59umfEI@*7=OeGQuZ*eaYPvrf0S1MWIWFRRe z5>vdzR?td12C|+-j98LlNT)t%hbKJ$7=juqfuL%M8)tyJMK?XrHaRU>ULD4u5pnN$ zdPGxm7=@Z!>Hj|fg1HuF#0_%404*pD?SP_-#toEKP_hL7g3+AQgLB`Qfp@m-l4j-;tk zry@)!DVNzE7<&C-ZUcs69$xIL2ch>ahIMNuI=%vCB|0)cI*UKZ<-`7pk`e>3XF&N1ZVOaAluR8bn=_o#$!A|)7@TwASb&z%f7swWM zpJP|OPbD9}WM_6YEaGWns zLdFUQ3;r^R$)I|RMoIR;C9;Wr0B~Jv9XujDkEd@{~HheVCt2k()Ite zz;5r-1pJ5={1Cz|tY}7jd9=R&>OFCnnekUjsY;c%On#COT{#pvR&dx4D%b~Ovx;S)_$_-jL#3)0Vjoj1f#6+L>XN9_m=sK@EqBZ4v9|=4k-NID`5CY_CU?7{4 zvNAA^FWY9OgiC@tiQyS*Y^^HvOePRn!493U0*lsg3YL-h){0&%66R z^L>BiPm)+neb~cvk$yOcR#yi`h6Zf1o_p6r1TS8Zvp@awf1LmRdvu7{IdwCyL%GyL zVAj2C1dBCft4RW9Z`K#Y`O{jS=KcDEOs!)P%~(^l1xYGAv;JNLBQXK2R5)1N+uH zAuN`ROo_pgm*(K3IiwMBMHG@_U*j!QZ9AUTP$@!tJ6?5FftCym4i?2Xm^lUZdHVV3 zfF=JenEtFh#jN|hv&+Zsx8Nz?@s~W5E3vbyRdI$cD$vcn)5U)64^LfqmbKnP8CMDr zboQs597R$;>p@X~s`=r3LL6A(UXcyVFsqx`t91R6XUZzU4N{L-g!e#8x_nWeUFz??DM7B6Js*blFnEd zj+AYjQI!O8w^xzwq^kEiI-xM;8PmjnIIkR4g7~bq7=o?PA4K`PyUDpUVe;~G(Mx%- zScRCktddFE6FU;RVB-`8CqYYVgMRO4W0^RXaSJ5l&h^cS1`*6^_G3vy^j-pvBmx?q z^s#=uP-yptYrkBFYJQ3DWFBf`5FfAeh@lq)_l|UAUo0Wdx%X8F;Mjccw9%XJaVKXZ zA&s14B7N;`xi%ts|IoC2e9thCmwTltJrRKu>&r25dZYu3ITTwnuIcm zvw-d!9kqi2@vM0Zv?f-_nJ@+KunGK7x4QmUr%N_6@gNfMw`cB^vp7O-4HJ_Dm{J_{ zSH+*epX%t-L$`!!*w=Q;tA*H{a$)e z7H5#}`t^|)8L6R4Ds1SCbf_T$ZS^hFY1Q8zk4E%dnc`bW%r7~Hwcotz^5CGaAsv)0 z%eih6Aq}ubma;u`izEEWZ90oBAE)1YDqGSkES4`Go2lMRvE)+_?}4V{E}5g;9a8%x zT+Jx7hb6M|qY-9%eewO_WNZ`NsltwjNOm{SNroe(%ggnppnP`+U%r z%va2_b$x?r%Rq{PoQ^K6?KFGECMx^I6QMwUh6B2pJ zP`+|nqc2=gWEc>!29b-R}HMV_N<*)dUuQHbYR;ElW#_R_~0uu_`UW2V(TrV;%tI$QQX~~ z!7ahvU4pxW0KqM|ySqbhceg-rcPF^JI|R4fhxeTCTv>Pi^{n|b-CeSG?W(5E;^W|P zbKkXR=i=CI>)O9Vba0-s|E%}gjxj_KmCCOhu6cko)cWJ@aqCdh+TD=fY#C({|LT@z z=(?w)v%{EwyYk!ceAU+`WH`n2_h-WVHxwV}BRwXs1vk*eojJ86X{Qi7W&!Fz@i%2? z(NZv;yY_bJh{(id!Y2bo$SDtVn&e4>UKmoZZ~eFw-tQXsQh!q`RcR{wzZxy$s=Mv3 z>O>J@MDKGUpWe6BxOiv5BxkXEh?iraqQy%`#kWA7?yW9njvN|qoD*;qnx!HL-aGPM z_+GKdrL&h+;5#4)+Fnd7bqKCkJ(bkF6GdTqP(Tur=MKvtx9Eq|yidJmg488YF#Bzg zun|ogzu%=hgV^KzJ$|e;qd%;*!8tF!1@eivVLJ$}k!!v<2!7_pK2fWx#TX1xB1%G) zVy_H)zandIa*=PkTdFgHeZStBb$f1awNWMajkQN8+FUm9E(@*cL{VSpvF5aYCmC@B z{Ib7k&l5r9sUwED&sm=Xk?n~=SBWFWfL84Z^WeUu(RR)+mJ@&C$NPADyqrbi_?L@V z=OquV;D-wru^FBMM}2KO{Uic9hxtwDf`{ND2=*{^!7<4|Jn%|v_qs6#OD%5JRFLm3(-1EOCpE*DXNOnpSsXMFlB zcl>WBoy9=HL(KNHkV4k8=dA5hiuxJ+rY36k{yk^FcPf1R8gEtP`aJim2;K26T1e&i zwJk)8?hLW_*QtRm_#$alIPMIpo63zd;eZ)m)HwfJJ@Z>hqUy@Pwp-@_m-ffe3}sc- zKwvoArqZBvZdkm5uQt_S3~{8iFDv83u2tGa ztwIO7g%BbZv1L>XNy|PsoUKZDSn1u8)pwq(6p7QT`AAKBxSpv(%W)qWamdeD>$9#m z)W7BB;e;acM}DHp`Q7=JKKl{8f9>(ZT4Bdm?+8=Iv=O>@t^-Hj+ofRZr@=$zE%&vM zKWexP0`c}5wueZY4CdQTdyRsp!cH6^_$vR3Q0_DMP1a4PjCfu$? zkVUGeypn` z{)$>r_ZEhLwA(+rDwQW=G^k3NV_?;+_z(T!q^~hv^HI3m<1ZL|(~9Tfn!tP>CTg5x z^2NZsrhasUk;$W*J3Z^}{FzZY3d_bC-Wa*2j8a8I0~F#vUVK@z#TOmUrX0-l=s)A# z#?X5fGGQa~h~-(rB;?ZSR*q~~4%P8n2~C(iiAazlaG_%oXh~Fe1lCh6nS92P=oa;O zC=QKW2QKv;`0_gHG^`vdL4MH|KBRLE#iYtN129;)xOs(zP>z#nVSg(KL97JJd=26D zZpC7O0llJLUG9!u?!Y^OA%*g|4(jxK_OI@`BIDrqAGG zcJ#u~%iznDD2~y-VcXE>CMaOtb9*g7Agbcp5sHk6!*ZmTR@bN)+Mp-i*^mE3{`J$X zd=`(Y7>3dUA@cfo$hU{gG~$J?&$BLN5N~f&G?!n{6J5lTl|*P)ZK@!YIm(@0_cj-S z@Se0?WqhYn8>^t7YV8=t^i$r0i8by~O=`K{cM%GyY4Y;&zzbMeS*Ff}i?Ly0T)3X3-&lL;&ww?S6YEbMzLOxqw0uEIu+>(E zxuLnf`Y8rNN0`p#+&$Zr714WYC1BvnG5%+I@vcg3(*}Y>54i9Z>RedNnfeA!WIL>m zv4jx%iO%;x_A(D4v%1@09TR!M9l5Z{RT!3KI2H?|$n(5$aS3a5yt2~2Fl(yrs=M$0 zeD$gyQ_-n!9{A}KR?vnpHXH?X`-j666re*n4!0LbM;EyxF5_}z_n*x;dps^B5K1mv z%7q?j2hsQ}W@ZFfP$Z?Y%Z1~?yC&Xuw-zk9Xa(zMXZcBsJWTv-ita6GY`sXxM%yhp6`eA+J?TEdIR z|Iq?Kjab7qMHf!nkI$O3dViupt6bnYAoh9clb@^a<%y6BB=L z$s=D;G3O4);O*~MUe0ch`TnRlC@uJt=hYdF$}Y30)$d==ktTf}ao1c#c!7hve1E^i zHuzzJLF>?1!i4MXBTUb%^&lSTtOt2aMKCQAH5<&Em?#)0e#?oY&v*%Zzg;irl&J>p ziV)W|#>2H46njV`)_Z#75;?IQG%_d!l2%uwzbv2LO7~4NnEHzupC4xUr_7VV`7y6D z3t0!PT|bH&V%BG>!CdL<)xZYMna5ys-u7h{TK{HC>_smPD%Ngq?}Z4?qU6T6(cg$= z^oe72))&%PU)s!Y(b%RYlg^Q7_Y!J7?c0m2g>C~eJibEJt3bJ#$vnvCS>@wYBvxU8 zXzE@!cSZY={+4Mr)xRU{6*_I)VO|f*>%{ut3pJT+^^)2Q$}hu$wpboJd2kQ==Z)U_ z74v>aav(CNGp@$ksxm-IA`PActtyd7wRYy0RmW5 zqV5FvMCJ=69zLIhrENRj<$uI7dfZ%#ZSKeB{+Kt?e0t4(FP#Z0TrFxL0hLL@g+yo% zt#K9EU)GZ=d7uLIE*mq8-L#7J!7~p9`TQyFBss&Z8@Oxll=wJF&83_x!tYv|FYB$n z8k?Y9J3R4TQnFx!8(ix>bbCF;s`WbZ;jI=sxN=8CAa|hi1L3ToVNSEnYbPtZ^ncgF z8{Rf4HTaf;sc*#=_;D3lmbmMgbKX#z+aEi6D(h7B?Tk4p&0F^lwPh?JMOsiuhf9Bw zG#&2#=gp=%Zz#IGLtN@*RQ~lDZngK8(T9KHD+fUHr2^qwT09Te$uN2Riy$r(!F$LC0?ld zu25*tp5OAIn3D#5KAYk?X_Q{H=O_qUiwwhIjJOxP?8ItvZ)jWI@xVj4dIe;^!otfo zrOBozWUJPcr?9?av>91;vQGPU*`=h$9)e8t&H0|Ex&3#`*hBA`v4I0G8Mw+Z7SYCM7v$spuDeI&I+YBP zp6`%i$a69}&^A#RM6P)qBv%*uD#sjBZlmg0REoQA7R;nF|6NRt^1;~i9tOtH0*Ns# zX=|bM*Eg$BcD4?NRN+^ul~}djYBq97M!%~E&T##~Dn%>1{8ngtd;4iiwe`441sc>? z;?$VMm@G(!S?#~Rm$mDuNlKBl*~F_lzm%(E2VgOUz~OD;9z+XV{kEmZecTk3q%~}% z=gl@1``&jU(1Prm^`S({!WD*o@BM92WjT%~%)!HQ_z6-~WMAz0G7~30lk3f-J3Pl- z1aW?TKKwJvTY1d}W`OSJ&o$Rd&)AU+DWt~n6@+l_+H?I+)hez_BCipzBGu_X zkQCVQMH4xXZangfr#Bu?$h6W6jSAjzJ)OU5!G%kUr@HHn^4A4x-S`*!S- zAhA0N=sV`;s6v;19HJ6%q#k1GE7aKDbvRqiX%!yV8u9xW)%wO><+r5pO4u)f|f01sCzz7e+@1!l} zjq;{WP)ipy6Osg|nLv?8jmEVKtk0zpNk<_o7FuRV#(q#pMQhO@o^{=}A`}8=zEL6B zEptgHPTnACe4&V!v@fCe1?pRDoXL;dtmBkE_)UzTgIPIAs;a7n$K(ggr3&KlH)WdL zTdfhY=`sR>N>PZO$1>dRj-ce^xWj$bGY33OUcGN!C?)Y*pMR}nPM;8mg(Z{QxK(dT zYXqqMSaJsYf{z-Hz8=Vxj)IP0N+j6~5Ut*6ZW7h3C~%)7qb5jBxc)oehB*;iPH^Rq z^MzyO`2NCYUR5CpjL}r9`r*cHtCeyIJyOWbjB*9#RX8w4hH2lW88hEV5dj`#mXwT^ zI2AnTLc6=mZ05nss8GH$T*%4G%+3aV9dX4bNuzD_nI1cTV6AI)@u8&PtPtHRbQ#ET zDKU(Ut8M#?T`zISq`uvp)wu1P@V}OYy>x7ydY_FPQu>Ltd#*uepc1e#|BGHPEiVrc z%{!9ey442!DR7kc2-6_RB_^`0|5o(SVexkEBQBo=n$l*CK^CI|_=*y$uq02pM4LZ< zZzmsHxZRfXFO1JR|9EYLmfhfsxLGWA8e4FCs<3Ro{(=0p&HFi=+1l{?w79UxZ=INwv)hg8tIE3kI4}3-efg`!TL4GRy@DQFwmCJBVdjfm z*BvA9!-7_gQ_Kk4=&LM_V8#s@xtp=)>f4MfGjkgLFq;Z!O8VwFC9k^Fzp8QKv&!9X zlP`N%au=rD#8I7)$M`o*FK-*Hul!z|u3A3in&FoNBlj9OX%WM;!bgPOX9|!zo-DsD zVDG)(^=J}OK&mvEp+cnP2DUUlxYRU#3Gx`&82v+T_o*zYRi!@`M7OC4cc*LlUn{B+ zCgkM#PLMZ z@z#qp?keVT66yLb?v1EMfV@X;19rHqpAe_dZ=&>eeji-ifC`+T!4;iwAYP!Y{BhKW znS!v6_$P>WT_|i_xxd%)E@SOy1H}jYg$LNx>*)|9kZE?TZdxQCC*0+hmj<_}L$@TMUSBRV_5&{gWRQEkcXiNy`XsKsEb__I ziI+2S(C|Dc`Z2!~?4Q+e;2?eP*;(Mya=JfmWY@!Edaa3oBy1%LNs>E$Tye7y6*U!; zd>bnHMs(WYeP3Dg^9AwuP_?_erd`o$>h))g(WmQmTN+aqVjV1#eNXY~-$!bt7FHpF zP>68O{efl0HTH6>MEyMv`V!x_X^HsV&~S0FcS9tdQ-HUFkAwb>Rt*U(w80d8G3)~!UkoF zneB`3PDZlDXQAnWjhUJGtZj)_j|TCh%rp)tj9Q@NHaH1MR6plYbp+E3W8<|0RyMfx z?JF-EaAqJd=<4>HFMD)VHe3);W$B6OL50n!U^-_{Rh+Pau0ExGjyc)FhH_YXsadg+ zL;Xghm~GmMQEiOJ{qO77HDa`UWkdHgQ`^=NUU@ISNi74HOZ#599LD56eUDP3A^{a) z&y&QLv!xIl3kY}W3-||0QuPFIMiY-5Vm*KB6j|sg=Mwd9$3Y21|1+cNgAZ$oQTIq% zWp2qKN{Qir*Z@og)}>WFH)kEQ6V3|KUzx4jUYkOrs(taYw|1c+9QRWSTFOf!>WVr@ zpg>!Z`*u)J!sT{NE_krv@Q_sxF!;^?%{@u44oZM<=K@ml(vpU-W}@Q zp2GkzP$%wzd<7_CtIwK~LXW)XN4`1bqRWm)_@zW>qDT@m#z-A&Sb@S5)1&34sbg-t z$bhL)=JCl)Qd)>7YDzr`I$;W$5aGk{e16`tkGuFIfvmpo1#%0orvPL;JAta?AZqF5 zxsv%Fa&Sj6KjF~4sMr0nS>92^ZxQTV1SRNR6>y-^G-gr|SPZO0%lr__o+lt|mi?&w zFguiDj&Faf!4PIY-9l-+DTPK#4v{g4L~(0Ve(=ZS+9d)lgc-@%(T;!H7G>Jv$}bde zlTv@x6DVBqldEg@_Dow3QwB!b3G)lPiPF`pQmm1yhvyYD)4@lO^~}$?Hk9X9bBDu~ z5dUHI(KI+7(`UQtc6^D;ObBUhyzN6l?MYK z_2wElMAyF`jkkxvq2$PTG0i-@!8%K!k_!kBM?2p&yDrg2@q1*R=U~A&Gb3d}kfnnuJP=y!2clX56DUVsX0-iwgz_;py)^A9NNOuEX8zKmj*+W;Igl zHjfXPW}r^0p4aeKnDv~^8Rb1oCQHSPk1dAj1ju8StHrRGIKUc?OrWLLp95rPn3eym z6U7R{vky*_seAH9_c_D7{^(;l<1Qb}!ZqFMNoz@MY!5=VtkhN-w#c5-sA$v~UQ2aP zSUG|D45=N2%%rzu!R!8PQp+3{dOSF^51wx)W=MA6##m_iq*;&~m)bg!foEYErBJAV zcRuUdyXujEfr+663PQ6l{58fDn3USy!h%yFL_ZKm=FV-O5AnD9v*{Zv76#+W!Xlqo zy=2sZLKjkqJvnOvY!QF{SVrF+Kg(bK!$ICky$FN^Y_LZLa zx`8oB!|}|R&zPTtd@a>$(xN;-j`1N(_xzRQ?-Ye$ZU^B;Tm`C6jlp$)8H-nwp5&gV z-2Wo~Ab;ox4(%ehw5lcsHg#4=$;gCHxf~&@fq#SsX8MoNV6T3h34{jlE^IfTUF3Qs z^b)9k-uLfsT#7*1Q7nggH`YMQ3Y7}~T7bYXUw+sTH|}>9+P(`>bN;dS#80xY5r2+e zwvs{u0+-(Ut6@ub1O)Aj>f!$N6vqjEcohy0>13%c_?)a9d&ujOX|;vEneu=$_AaCV zV{Z?RtKArf-@iL9jFCyca^r9*R3JAXc3sd&7I6Hq2T|b$zLCR?T1p;}v=9W0U~Wd9 z)M!%hu?61Y@VH8oR4=5p#+CI04-Cc(7b#1}#JiBGdag7|+KMKQZlSk4tI8&t#fC96 zB0IW^i%Vs(PC8pGAEVo&v8Ih1frS=*c?#D(KPCu%cDGfd3()O2Y0aoL|C6ueD!W<$ zT**=hNIk#{;9bdz!%72Q;Win9vGBw*a#B=5&8W#n3sV9yF#okuPXv&ID&PN;T}j^I9ZF=g-0{z(L%|4nDN zeLhs@e0nbwgb#xMB$vjEJ?^ZSN0QeUiLr^eF&VqXPN*e>O&1$VSg;FhP|1rPB`uXr ze3^i@)Qz=z0StdeV4yBl&N>QPq;7|$A&jYshC}NKlWk7+WE%hF*y>@5LzNUT3UJhq zl&n8BFN;KU+sT1IOqB>+YV5Uw5*d($KC?`ry^&<>0TsSW1Vff^h zC%6lI)ggQjeZXkN*Z|-oKf$BbRum&p_vYrqO4%M`BUa0k$-Mjsr&)NiL7^Up;10wi z%6*@^zY?je`LlL^oa1xV+XlISDNLs(*4F;dZp1+lG*<7&_1qvI><6I^=-}W2`>k$p zUH9c>HwzIdB`RvOnCq3HB3c619#Vuc>9~r`i>2swBiqyC1plO%D8Uo9(4kH~^yc^joCS-GoM6RG{quT|eplD}%8KMHU#S@) zH`7w)_+--l`-BE9CwXQD1Nmz<{1Hzk)|=_|TTUzI=TF4h@f8p) zM186fko4SR+*!@G=gJ?n_^Q+(v_$RQ0lG-QFUGwSDOXC-(aQ^G%!MB9Hb|-=OMVzT zMvuBoa?Q85-Mj~7;Kl?>ewY=ztPG7PU{+B1-M7cH_V0Gfxw384gikm>5&js0OQ8fD zP*^PThmKUiN^6yT`)a-9*?{qd%QRd4zM7K?~7r2=?tXIt|U~D z8uFgEqbt+(m{Q7OZ~1~KJc<8lK;c zwj6f%%1oQhm5=H>|0%URQ;7T!Ef!N+_BD}mS9<-A5D9uy=eLl5XV%8@VKv!tXH#lC z4{i*J6eQ>h{&*XsdkMRS@mU0HcSPZf;H@71-1o^&OlbmIG+uUwi5;`f2xB_Q-~lraF-J?Q=>p? z&(aqUhpY56?eprCb#C3>z+X`K4vdcX$m~A)wm-jkTm^3y3Qz!bh^t`Cp|~N&rQ0G8 z^S)c(%<*LVR6IQYu1CBg1R&Ds#ScWP&!F(~;ijLz`2#!yzps)1Q1t6C^XHPQ5OS|0 zSgPCKaIv(#JtyGx|2N3Yjw{z;BelRBx_$AKiK}c)hY2IkiVIf+4Ch(`CfmcA0Wgl` zgb?>d#eNDdi;ia#v_i|CsJ^B8V1CWHOUKh1@TBBq!Fazo@!_ zBLQ#w^EP92y3*=_BC!*w2ae-=_i+7?->oErAsYW*cC!{3>+>Re{g_|YY!&i?k+_;NBpS~h zLGTX#DZt?}+~W-I-PdN(t=xm_%fA;UEbM4-cn{tGMN8t77sPjL{zpvaC56WoCOMmo z-aa4}u%-W*E_RL7UFWoUBuBgl*pj$UpfcKn3{Wj4CKNo{wT5HGBVC6%8X#qn=TNqr!GNAsH! z;U{Y1`$}|2y^akaTe=mX@xecrqW`{#k4_;JY)l1MkziF%_z4cs{3TMMyuBY9d7bi$ zFAyK9r1dd}Q*H5BWV9FyK|(PU<9;f!%Tq;zJVH@qed)BVw&GALrod8LAd zW{L;R#+c)GF(7XJKTu9s7~CuH2AQ=h?l&iNYK6>UQ_^X$!7^-+KT<&6#|y`twj1L< zb{p=8J?8A9^D7~qq0zm=1w+gKd|~|j?fq!BC_d|L*mmN+w+m56691I9qzw?Rb}=!y ztCI?vh1Y$4wOz7TibTUh-Jd+)>ixfj;uxfg|K!SJ8DLkv1YL)<1$*XIUthBk%f49dl7bqqBQEY{ z`o~p`kdRg8EzN2Vn{mFPH0}SL)8)+|_(Meh7Q zFOQCmU%B2a;p6^x9EAeXS*DSm&z?-=ui;UKH8NrV`cL{xCLRE8%6e0M#KUAdH~8O| z#9Wx`PHrJ4(nXT8Gmq&Lr(P%;!-4^6m0Lx-u~BZaJxAFB{)tIKhr9W4@zkJry$(A= zYy>13*<1Z~k`0*vyc!?X=pn(%?xRmUJ{~ujxnG>x$uwOp9j;ifdo3(`U46&?hUtDL zNybm6&dFw8Ay$Bgb8tRg_~C2Llu6Q=e{282S|DKoB28v3N?vhbm3xSQR(P^6p`x4F z&moBTpxUC*I9fHbe)=+NU)X~*XlWPuK}87UVa=6|KN`ET{Z48$GHZb$#*tbSMOI9# zOC2gemh@_JBAR4Sy7xj?wCXv7F7p_L?B4>=MztfkbFcXoMPI0j0r0L`{UzKEHu_c$ zPLuon8~a?tz@OPgunp#fpV;e5QDZ31ruuPXG651%kS!x$!U~=*JG6AZ1zKV5ut=Wh zqXk1D#%5Vdv2U_Ds8c7p--UsExbsVg!LX1n7XCNjv=%57Rih+*&`S@7tr<4?cWJQTfpg?`AO zy02t74vTZaY8?gv7=R4J@%hK%3fY95l#{7Lw~?jQFN4cY7g{XQOb$*Qbo8Ddoe&p~ z53uR7F~TS8VtDQ+h1sb-dUwpELT|UKwG;2#*%|!qtT;_aZR335VEvGN=ybvgU+ngg z^DwTPM}o{07PdE^#I`S2CE_Y9zlDBHoT`yJ_@1MT+Szx8)3SoQ=}#YsJmsws?&`xm zVru@4g%N$~U0<*svssVB|7a;#_oox;Sv+U?C%WbjIg~*;*Pi8{=`%t2Ehttd-;29@ zVs6j>Th3HM=YjfP0EFX%Hbq9Kz7_c!6%bKjTc{)*+ZN29% zN*7WRv6d|w0#W9X-vTK_WIZ&8UPmh};B0B_$ZY*2oj4fK9=yt8BaQT1kVVjVcJU~h zTUR?&3;&@ZGgGvBT?IC}mDrQhSd@&#`E=3JkzA|rgwU3_uR!r^=<(NX_u*e9%|-td zeS%0?Mg`>MwRR5iVJhS{6p�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 Lf>^DHLD2sPg=7|Q diff --git a/layouts/community/ergodox/algernon/images/base-layer.png b/layouts/community/ergodox/algernon/images/base-layer.png deleted file mode 100644 index 2ca7a273bed32e630522ed70618a930037537029..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106956 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

xqo?w3DlN6!_qw#HiY181nm>q#U@mnY&IM#Z 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μ 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 b_teo#A$ozE$1_6VotDnm{r-UW|3c5md diff --git a/layouts/community/ergodox/algernon/images/heatmap.png b/layouts/community/ergodox/algernon/images/heatmap.png deleted file mode 100644 index 4f55c5adff5703a3b61ac5198694375ad49a405b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139351 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%0D`~mx$kQG~ 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 EiAZ?2R`sI*BO+iJbgi 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�pr5WIU2%(WKGeVW>J7>zynVXx|2nK#D$-5_K5Ln{BMMnr z*+bU&*jTXnVlF`=szygqtw?yw9}B;1(1^JwrEJY;!75XiV+|cKytPR(4k8LlwU@aI zK6i>iypWOdqt?1Hpc7S36%tk%M59~>Ykk-sM+=$Kf`|iR6?#&-PDHD{a(rw-WIe-L zLhsdt!_~NUWq@;8UY;To7nt+x*Y(%_0Vc2&-2^RU9QLmWi?qZ4)Tx4?8WRrrw80qu zSe>e8!p$Z6!%fuHnrLHZN9C#W=SoJwVbEQCrR_ZPy9O8+NGX|h=UC$wPqy8W;i@Ww zTD@r2v_n9dh<)u&1{ljjdZ&VS3k^Jkt0&Q!~QyJxE*lCP4 zM{8Wa)-yHRq;`(~5^8`5Rky(jSKt)39q~>u~Y!r?o81>vT>l*;$ z9kM_Ix|1kYz(PhmHbLL8NC)?RTNZI>DKWOM?&J66O~_z*!QO)%a!MIiW9H< zYSmApR64HxTAJ%NY^5e)2{l@VY);OnhO~}3^9gBpkl(+5&z)^vc3n-qwWXw{zGS!* z5w{9BOp{Yq4qtqXLq@K7_=)FW7kfuV<)(F)hjVgbIWtEjW$`D)+Ga@9V1;ACMmjfV z1N(PfGAZM+(0Bfa_X>)h$mQjo+%9$wWBt}KTm!?y>Uo(ntqu9h1D$^(jIR_xtcG1* zV1NcXlz|b1GoH`u!(J6AyI?Se$uxCMfwwsJ0f*rs2~})0e0eMF@*9v}jnL(Jsg)P3 zDZ$54=iub$kqGZG!e~W`T#WeHvfZjzDu)Au2#*8dZwwaED<*`{h&;k};Xu z&0eDHM#QpDFY3k^MmvQxzvztsb1O?s@&RaAAnN&j@QKzhDmYl1&1=Y*e^REduZ54r z?B(%hh&f4H24=g&H2ZHFbP38uFK@pyP=j(&Q5sTMKfcQ2#TwWwwmULUGr7Ig@Yjb= zslWH{=+(ttY1&@;Sy<^V>d*0of7B>>oigtb`9mua2{2m9ZVbXx2Rv_}5;+qf9cR0--G{dw}2+ zACU_QT}@6n0xLc(M|?>>N}oxXOxRo7j0I)b!qGF-f7r?wreL~3p;QQvA8oBXSH#-+ z)dz5tHB}PkD`2+2{C6sLz+17g-({BlJ(aweh#eMHDzMBfw2sY#0da2Rg{Aa3YD1R6 zaqGxxAk;eo1zyz2lp$6=$fLEaj2Thl6NYTWJ6_b|gh|UN# zIUX0)rU@C39`~F2dZkA3MV98MrGFwKd$TY)KmsCEA`S% zCn`cB?uMGjbJhp^vl_ks+FK-0JOrb8D+>zmC?`G#u7spOM(fDp@UDK_N_dk1ywv?? zW|5r{pG26?Sdop$@7Eh}J_PTXCVryq!aNoGc)NFwYK)X=ip99A<<{G?s9W@10Y;8R zys=;>U)<_kMKtLuvgFr0vy$}m^wJ)AT^SQrco`gZF)^`<s!0?vL?fFoyjEYb>G zppRjZ^v&cKsm9;%(O}pZUlmcK3tVIv^GhK%y~9 z6=%~gb^)?4ENSl%;SCTV@<_<2XwLXDHWmI$ofkB13t6t%(+J|SlD@XI;F{DDpkqEk z39NhwBnkQYbZ3Z)+s(_#Z2|OdLi+Yox}&%}UK5@Z31Vj%O|!W?^1IE-LEy4`05R*Z zLnZRxLj|@1mbNkl>j>l%fm8$z{9%d_me|P*kK;jjlaLejz*s2wK;F0mwRw(=_Z7$U zpv%HYX0X^c^}jBCWQtrNzd=2x6rymdZO2B{}CmB>=P}HJhAPZNrFet_BBS$ zBYNeng(8m$jA~``#o`JmW}8MEfsln9HpkN+E-}4RVL#*b2F}7!s6RYLd61&e#=Eh( z-1g&f+2o~r>)Y}nF~1ggLG_viydP=VLFK@QXc=KuRbW7yRak`c)fYe4R?b z@lv)83$Fii!k7080*o`uB;sTV*;rZMaOuDl5b(27D+w5eNCFY@`{a|PiM@fbo!*S!A)h7j{60R;tJlNeZKY}sShHq3lhzYx=95#ukaQR-llZJ4+w?R z6{Ji|zXA}=Z87#Kzz6Nl37?1{`lvh(L?Mu*K46!00EuE^5bvAiZlaLlJef^&7jk~f+vAIPMC3`WR+qxR%^lJNmp)Uzf@+im^ z1wuW7VqgEw4A@8_OoP+56qHgc$tFBQv#XC?|A$oH(S%~=rI^y`Cl$wI zLxY>hfE?a!bc#qwfyx)MJaI!FwtX>1oql&${!`< zXM+}WZzoA0;(z_NnJsXb z`0D*^jJe_OIvk+;<*m!iLF)aIW*`O29W)m1uU=sO*le@hYUJxN<8u68?YRa)M=!bk zb^i&U9Pms#M-HN*;C-V8MU1)yM5|2%{-%hV9R4uh&h!x5C(34%FyRdpj4uT))p*3p z?nKV>GbX20zJ8~8Lk(h+-#jG_E3W*q>i_F>R86zIy5}LgZ+CRh03XIR_c#jbm@@YJ z_o#%TLi)*3MEOt2WoBvVng$_-g$6r+90Gf%fF&ROn+JTq55o0q__d!@Isz8wg4Zs5~e*IkDooBv%pN^L(5A_cAciz-dCll8OJJ6xT_CzCp<* zQl6f?-znaOcaADUQxlZ3vk6(k_erkjG%=69A|yTdXn;`&Y%1-%^HW^>Ej9M6-QWYm z;D=mOCECb007|{IEK1V}UTT~NH{pgKyeKu!tU*bUnHxu^yQA+v z7H59?GkfFbZi~n1ry@s>6)Yc7gAmP%QFdk^yn%+eWRzq5(X{K9agYk6COYZp_#5Az z5vF6BaNhw!Gr8bcD!n;&I!6_pO}>kd>odo$*;i0}qT&g`3;R#TuRz)9UeMofHIczY zYenLd`Jyhqe=LnIz$Q65zu*kB82$>Qu1`U3wFcQ*#`Dehk#q}3Ab90R#fQh}al^`T zcO8Xahu_*8;&^TC+*nH^Q8s$CQ76>gWQ5TvJ~;zujC$e8??x1IPKg|Kf1p2x&My*W zHF7QVy`OJ|7AfMT@#hR5-sk6d6`gx(gi9@PA}`87nbpX+yPrt0!3Ox?q6Ie z{~90_W-^SC;l=?~0uS$JwxEqALm_k7{j`!0~Y(5VRDC)KfPqi4# z`A5Os`wJ$q@B>LG=xrxs&b9TqKA5M8K!0_Kb+ItYZ(&qrWo7J^RPJA84t=C7(X0QY zEH+Raa7d1DxD5Y(8#q9a*U@!Gg@!`SJP9n|_sBeLp)1IGBP@m+e_k%WfO};7(7pD6 zlXZ`0WWP-6O~gpaiUl9RENQc6MN2-U{!*&9nF6cRvA83@F|B91&6dKbNjT z14P0q>ttgwe_x{`EHHn5I9I++DH6J1-{LoyCK=0#BKAz|5!E*=^sAADI$coh`{6cJz$9n^&y6#oJsbdn7L6o@koP&E7sy zNEOp20h)if(NH1Sh_{Pe-fHJo)e9@T4^MT4Z>o(Ea*t zLA49hvi^$x-j|7F+v*Q7u6iq1X$Rdc7(rnjFr z=c(qci=OhX)#f(Ox!6qWb6+884%9yRAp>Fea4-SKDcqu>W<_NO1PDx;H0eicmCKty zQ}=qDw79je*1D^!>x$FUS)N5jpQi53Sl0(BGF*g#?NFC|dvSkolLr#8FcNk80umZ< zQsN@WCl_y@KMKul;A#t&89pciGsB0Q+UKT#?STxR!ALg~pu^q1d@KG4Nf0QcK@F(5 zsQK1qtO|}*xP>4_qoA(?t05OR_wD07lFZ`b(*=2(yVWt(0Rws#3$P^*9Li%}4(u1V z-@S9^8aoRM&)JzpVJOzY{Hi?5!PAp7Dk>_>l9To1u@B$Awe8;hyQA$8Htzu&x4KMU zzkZz%fAHWzKdlbn+R5ijuV!U$iPGJ(XHUh}l#I9H>EIb4G`p1h9I~^u&&{!9UVW8o z^UXK1a&mF2nVyuwX|5xNt}FR^vivhxOMNuU(rP8WM8lzIEEy Z|BMfpRh#Y%&J|?<0#8>zmvv4FO#mw&Ym)!~ diff --git a/layouts/community/ergodox/algernon/images/steno-layer.png b/layouts/community/ergodox/algernon/images/steno-layer.png deleted file mode 100644 index 9a2ba55effaa0b96f9bf9d31b81f3c2101c93ab9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64086 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