aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/bootmagic/bootmagic.h24
-rw-r--r--quantum/bootmagic/bootmagic_full.c147
-rw-r--r--quantum/bootmagic/bootmagic_full.h115
-rw-r--r--quantum/bootmagic/bootmagic_lite.c66
-rw-r--r--quantum/bootmagic/bootmagic_lite.h25
-rw-r--r--quantum/bootmagic/magic.c54
-rw-r--r--quantum/bootmagic/magic.h18
-rw-r--r--quantum/keycode_config.h1
-rw-r--r--quantum/led_matrix.c573
-rw-r--r--quantum/led_matrix.h127
-rw-r--r--quantum/led_matrix_drivers.c7
-rw-r--r--quantum/led_matrix_types.h38
-rw-r--r--quantum/matrix.h5
-rw-r--r--quantum/mcu_selection.mk92
-rw-r--r--quantum/process_keycode/process_auto_shift.c20
-rw-r--r--quantum/process_keycode/process_auto_shift.h1
-rw-r--r--quantum/process_keycode/process_backlight.c29
-rw-r--r--quantum/process_keycode/process_leader.c5
-rw-r--r--quantum/process_keycode/process_leader.h9
-rw-r--r--quantum/process_keycode/process_rgb.c5
-rw-r--r--quantum/quantum.c28
-rw-r--r--quantum/quantum.h55
-rw-r--r--quantum/quantum_keycodes.h913
-rw-r--r--quantum/rgb_matrix.c34
-rw-r--r--quantum/rgb_matrix_types.h9
-rw-r--r--quantum/split_common/matrix.c3
-rw-r--r--quantum/split_common/split_util.c70
-rw-r--r--quantum/split_common/transport.c88
-rw-r--r--quantum/wpm.c38
-rw-r--r--quantum/wpm.h11
30 files changed, 1749 insertions, 861 deletions
diff --git a/quantum/bootmagic/bootmagic.h b/quantum/bootmagic/bootmagic.h
new file mode 100644
index 000000000..959750178
--- /dev/null
+++ b/quantum/bootmagic/bootmagic.h
@@ -0,0 +1,24 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#if defined(BOOTMAGIC_ENABLE)
19# include "bootmagic_full.h"
20#elif defined(BOOTMAGIC_LITE)
21# include "bootmagic_lite.h"
22#endif
23
24void bootmagic(void);
diff --git a/quantum/bootmagic/bootmagic_full.c b/quantum/bootmagic/bootmagic_full.c
new file mode 100644
index 000000000..a7a0dcfcb
--- /dev/null
+++ b/quantum/bootmagic/bootmagic_full.c
@@ -0,0 +1,147 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <stdint.h>
17#include <stdbool.h>
18#include "wait.h"
19#include "matrix.h"
20#include "bootloader.h"
21#include "debug.h"
22#include "keymap.h"
23#include "host.h"
24#include "action_layer.h"
25#include "eeconfig.h"
26#include "bootmagic.h"
27
28/** \brief Scan Keycode
29 *
30 * FIXME: needs doc
31 */
32static bool scan_keycode(uint8_t keycode) {
33 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
34 matrix_row_t matrix_row = matrix_get_row(r);
35 for (uint8_t c = 0; c < MATRIX_COLS; c++) {
36 if (matrix_row & ((matrix_row_t)1 << c)) {
37 if (keycode == keymap_key_to_keycode(0, (keypos_t){.row = r, .col = c})) {
38 return true;
39 }
40 }
41 }
42 }
43 return false;
44}
45
46/** \brief Bootmagic Scan Keycode
47 *
48 * FIXME: needs doc
49 */
50static bool bootmagic_scan_keycode(uint8_t keycode) {
51 if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false;
52
53 return scan_keycode(keycode);
54}
55
56void bootmagic(void) {
57 /* do scans in case of bounce */
58 print("bootmagic scan: ... ");
59 uint8_t scan = 100;
60 while (scan--) {
61 matrix_scan();
62 wait_ms(10);
63 }
64 print("done.\n");
65
66 /* bootmagic skip */
67 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) {
68 return;
69 }
70
71 /* eeconfig clear */
72 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
73 eeconfig_init();
74 }
75
76 /* bootloader */
77 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) {
78 bootloader_jump();
79 }
80
81 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
82 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MATRIX)) {
83 debug_config.matrix = !debug_config.matrix;
84 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) {
85 debug_config.keyboard = !debug_config.keyboard;
86 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MOUSE)) {
87 debug_config.mouse = !debug_config.mouse;
88 } else {
89 debug_config.enable = !debug_config.enable;
90 }
91 }
92 eeconfig_update_debug(debug_config.raw);
93
94 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
95 keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
96 }
97 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
98 keymap_config.capslock_to_control = !keymap_config.capslock_to_control;
99 }
100 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) {
101 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
102 }
103 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) {
104 keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
105 }
106 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_NO_GUI)) {
107 keymap_config.no_gui = !keymap_config.no_gui;
108 }
109 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) {
110 keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc;
111 }
112 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) {
113 keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace;
114 }
115 if (bootmagic_scan_keycode(BOOTMAGIC_HOST_NKRO)) {
116 keymap_config.nkro = !keymap_config.nkro;
117 }
118 eeconfig_update_keymap(keymap_config.raw);
119
120 /* default layer */
121 uint8_t default_layer = 0;
122 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) {
123 default_layer |= (1 << 0);
124 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) {
125 default_layer |= (1 << 1);
126 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) {
127 default_layer |= (1 << 2);
128 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) {
129 default_layer |= (1 << 3);
130 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) {
131 default_layer |= (1 << 4);
132 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) {
133 default_layer |= (1 << 5);
134 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) {
135 default_layer |= (1 << 6);
136 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) {
137 default_layer |= (1 << 7);
138 }
139 eeconfig_update_default_layer(default_layer);
140
141 /* EE_HANDS handedness */
142 if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EE_HANDS_LEFT)) {
143 eeconfig_update_handedness(true);
144 } else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EE_HANDS_RIGHT)) {
145 eeconfig_update_handedness(false);
146 }
147}
diff --git a/quantum/bootmagic/bootmagic_full.h b/quantum/bootmagic/bootmagic_full.h
new file mode 100644
index 000000000..28f914c1b
--- /dev/null
+++ b/quantum/bootmagic/bootmagic_full.h
@@ -0,0 +1,115 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19/* FIXME: Add special doxygen comments for defines here. */
20
21/* bootmagic salt key */
22#ifndef BOOTMAGIC_KEY_SALT
23# define BOOTMAGIC_KEY_SALT KC_SPACE
24#endif
25
26/* skip bootmagic and eeconfig */
27#ifndef BOOTMAGIC_KEY_SKIP
28# define BOOTMAGIC_KEY_SKIP KC_ESC
29#endif
30
31/* eeprom clear */
32#ifndef BOOTMAGIC_KEY_EEPROM_CLEAR
33# define BOOTMAGIC_KEY_EEPROM_CLEAR KC_BSPACE
34#endif
35
36/* kick up bootloader */
37#ifndef BOOTMAGIC_KEY_BOOTLOADER
38# define BOOTMAGIC_KEY_BOOTLOADER KC_B
39#endif
40
41/* debug enable */
42#ifndef BOOTMAGIC_KEY_DEBUG_ENABLE
43# define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
44#endif
45#ifndef BOOTMAGIC_KEY_DEBUG_MATRIX
46# define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
47#endif
48#ifndef BOOTMAGIC_KEY_DEBUG_KEYBOARD
49# define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
50#endif
51#ifndef BOOTMAGIC_KEY_DEBUG_MOUSE
52# define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
53#endif
54#ifndef BOOTMAGIC_KEY_EE_HANDS_LEFT
55# define BOOTMAGIC_KEY_EE_HANDS_LEFT KC_L
56#endif
57#ifndef BOOTMAGIC_KEY_EE_HANDS_RIGHT
58# define BOOTMAGIC_KEY_EE_HANDS_RIGHT KC_R
59#endif
60
61/*
62 * keymap config
63 */
64#ifndef BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK
65# define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
66#endif
67#ifndef BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL
68# define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
69#endif
70#ifndef BOOTMAGIC_KEY_SWAP_LALT_LGUI
71# define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
72#endif
73#ifndef BOOTMAGIC_KEY_SWAP_RALT_RGUI
74# define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
75#endif
76#ifndef BOOTMAGIC_KEY_NO_GUI
77# define BOOTMAGIC_KEY_NO_GUI KC_LGUI
78#endif
79#ifndef BOOTMAGIC_KEY_SWAP_GRAVE_ESC
80# define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
81#endif
82#ifndef BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE
83# define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
84#endif
85#ifndef BOOTMAGIC_HOST_NKRO
86# define BOOTMAGIC_HOST_NKRO KC_N
87#endif
88
89/*
90 * change default layer
91 */
92#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_0
93# define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
94#endif
95#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_1
96# define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
97#endif
98#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_2
99# define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
100#endif
101#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_3
102# define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
103#endif
104#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_4
105# define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
106#endif
107#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_5
108# define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
109#endif
110#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_6
111# define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
112#endif
113#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_7
114# define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
115#endif \ No newline at end of file
diff --git a/quantum/bootmagic/bootmagic_lite.c b/quantum/bootmagic/bootmagic_lite.c
new file mode 100644
index 000000000..9cbdcb0bb
--- /dev/null
+++ b/quantum/bootmagic/bootmagic_lite.c
@@ -0,0 +1,66 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "quantum.h"
17
18/** \brief Reset eeprom
19 *
20 * ...just incase someone wants to only change the eeprom behaviour
21 */
22__attribute__((weak)) void bootmagic_lite_reset_eeprom(void) {
23#if defined(VIA_ENABLE)
24 via_eeprom_reset();
25#else
26 eeconfig_disable();
27#endif
28}
29
30/** \brief The lite version of TMK's bootmagic based on Wilba.
31 *
32 * 100% less potential for accidentally making the keyboard do stupid things.
33 */
34__attribute__((weak)) void bootmagic_lite(void) {
35 // We need multiple scans because debouncing can't be turned off.
36 matrix_scan();
37#if defined(DEBOUNCE) && DEBOUNCE > 0
38 wait_ms(DEBOUNCE * 2);
39#else
40 wait_ms(30);
41#endif
42 matrix_scan();
43
44 // If the configured key (commonly Esc) is held down on power up,
45 // reset the EEPROM valid state and jump to bootloader.
46 // This isn't very generalized, but we need something that doesn't
47 // rely on user's keymaps in firmware or EEPROM.
48 uint8_t row = BOOTMAGIC_LITE_ROW;
49 uint8_t col = BOOTMAGIC_LITE_COLUMN;
50
51#if defined(SPLIT_KEYBOARD) && defined(BOOTMAGIC_LITE_ROW_RIGHT) && defined(BOOTMAGIC_LITE_COLUMN_RIGHT)
52 if (!is_keyboard_left()) {
53 row = BOOTMAGIC_LITE_ROW_RIGHT;
54 col = BOOTMAGIC_LITE_COLUMN_RIGHT;
55 }
56#endif
57
58 if (matrix_get_row(row) & (1 << col)) {
59 bootmagic_lite_reset_eeprom();
60
61 // Jump to bootloader.
62 bootloader_jump();
63 }
64}
65
66void bootmagic(void) { bootmagic_lite(); }
diff --git a/quantum/bootmagic/bootmagic_lite.h b/quantum/bootmagic/bootmagic_lite.h
new file mode 100644
index 000000000..17777e6b4
--- /dev/null
+++ b/quantum/bootmagic/bootmagic_lite.h
@@ -0,0 +1,25 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#ifndef BOOTMAGIC_LITE_COLUMN
19# define BOOTMAGIC_LITE_COLUMN 0
20#endif
21#ifndef BOOTMAGIC_LITE_ROW
22# define BOOTMAGIC_LITE_ROW 0
23#endif
24
25void bootmagic_lite(void);
diff --git a/quantum/bootmagic/magic.c b/quantum/bootmagic/magic.c
new file mode 100644
index 000000000..f1cb11c39
--- /dev/null
+++ b/quantum/bootmagic/magic.c
@@ -0,0 +1,54 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include <stdint.h>
17#include <stdbool.h>
18#include "wait.h"
19#include "matrix.h"
20#include "bootloader.h"
21#include "debug.h"
22#include "keymap.h"
23#include "host.h"
24#include "action_layer.h"
25#include "eeconfig.h"
26#include "bootmagic.h"
27
28keymap_config_t keymap_config;
29
30__attribute__((weak)) void bootmagic(void) {}
31
32/** \brief Magic
33 *
34 * FIXME: Needs doc
35 */
36void magic(void) {
37 /* check signature */
38 if (!eeconfig_is_enabled()) {
39 eeconfig_init();
40 }
41
42 /* init globals */
43 debug_config.raw = eeconfig_read_debug();
44 keymap_config.raw = eeconfig_read_keymap();
45
46 bootmagic();
47
48 /* read here just incase bootmagic process changed its value */
49 layer_state_t default_layer = (layer_state_t)eeconfig_read_default_layer();
50 default_layer_set(default_layer);
51
52 /* Also initialize layer state to trigger callback functions for layer_state */
53 layer_state_set_kb((layer_state_t)layer_state);
54}
diff --git a/quantum/bootmagic/magic.h b/quantum/bootmagic/magic.h
new file mode 100644
index 000000000..2c3969b85
--- /dev/null
+++ b/quantum/bootmagic/magic.h
@@ -0,0 +1,18 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18void magic(void);
diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h
index f878168c5..d7e334fdc 100644
--- a/quantum/keycode_config.h
+++ b/quantum/keycode_config.h
@@ -37,6 +37,7 @@ typedef union {
37 bool nkro : 1; 37 bool nkro : 1;
38 bool swap_lctl_lgui : 1; 38 bool swap_lctl_lgui : 1;
39 bool swap_rctl_rgui : 1; 39 bool swap_rctl_rgui : 1;
40 bool oneshot_disable : 1;
40 }; 41 };
41} keymap_config_t; 42} keymap_config_t;
42 43
diff --git a/quantum/led_matrix.c b/quantum/led_matrix.c
index 4f1f06c7a..72eb5190b 100644
--- a/quantum/led_matrix.c
+++ b/quantum/led_matrix.c
@@ -17,79 +17,111 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20#include <stdint.h>
21#include <stdbool.h>
22#include "quantum.h"
23#include "led_matrix.h" 20#include "led_matrix.h"
24#include "progmem.h" 21#include "progmem.h"
25#include "config.h" 22#include "config.h"
26#include "eeprom.h" 23#include "eeprom.h"
27#include <string.h> 24#include <string.h>
28#include <math.h> 25#include <math.h>
26#include "led_tables.h"
29 27
30led_eeconfig_t led_matrix_eeconfig; 28#include <lib/lib8tion/lib8tion.h>
31 29
32#ifndef MAX 30#if defined(LED_DISABLE_AFTER_TIMEOUT) && !defined(LED_DISABLE_TIMEOUT)
33# define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 31# define LED_DISABLE_TIMEOUT (LED_DISABLE_AFTER_TIMEOUT * 1200UL)
34#endif 32#endif
35 33
36#ifndef MIN 34#ifndef LED_DISABLE_TIMEOUT
37# define MIN(a, b) ((a) < (b) ? (a) : (b)) 35# define LED_DISABLE_TIMEOUT 0
38#endif
39
40#ifndef LED_DISABLE_AFTER_TIMEOUT
41# define LED_DISABLE_AFTER_TIMEOUT 0
42#endif 36#endif
43 37
44#ifndef LED_DISABLE_WHEN_USB_SUSPENDED 38#ifndef LED_DISABLE_WHEN_USB_SUSPENDED
45# define LED_DISABLE_WHEN_USB_SUSPENDED false 39# define LED_DISABLE_WHEN_USB_SUSPENDED false
46#endif 40#endif
47 41
48#ifndef EECONFIG_LED_MATRIX 42#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX
49# define EECONFIG_LED_MATRIX EECONFIG_RGBLIGHT 43# undef LED_MATRIX_MAXIMUM_BRIGHTNESS
44# define LED_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX
50#endif 45#endif
51 46
52#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > 255 47#if !defined(LED_MATRIX_VAL_STEP)
53# define LED_MATRIX_MAXIMUM_BRIGHTNESS 255 48# define LED_MATRIX_VAL_STEP 8
54#endif 49#endif
55 50
56bool g_suspend_state = false; 51#if !defined(LED_MATRIX_SPD_STEP)
52# define LED_MATRIX_SPD_STEP 16
53#endif
57 54
58// Global tick at 20 Hz 55#if !defined(LED_MATRIX_STARTUP_MODE)
59uint32_t g_tick = 0; 56# define LED_MATRIX_STARTUP_MODE LED_MATRIX_UNIFORM_BRIGHTNESS
57#endif
60 58
61// Ticks since this key was last hit. 59#if !defined(LED_MATRIX_STARTUP_VAL)
62uint8_t g_key_hit[DRIVER_LED_TOTAL]; 60# define LED_MATRIX_STARTUP_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS
61#endif
63 62
64// Ticks since any key was last hit. 63#if !defined(LED_MATRIX_STARTUP_SPD)
65uint32_t g_any_key_hit = 0; 64# define LED_MATRIX_STARTUP_SPD UINT8_MAX / 2
65#endif
66 66
67uint32_t eeconfig_read_led_matrix(void) { return eeprom_read_dword(EECONFIG_LED_MATRIX); } 67// globals
68bool g_suspend_state = false;
69led_eeconfig_t led_matrix_eeconfig; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr
70uint32_t g_led_timer;
71#ifdef LED_MATRIX_FRAMEBUFFER_EFFECTS
72uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
73#endif // LED_MATRIX_FRAMEBUFFER_EFFECTS
74#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
75last_hit_t g_last_hit_tracker;
76#endif // LED_MATRIX_KEYREACTIVE_ENABLED
77
78// internals
79static uint8_t led_last_enable = UINT8_MAX;
80static uint8_t led_last_effect = UINT8_MAX;
81static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false};
82static led_task_states led_task_state = SYNCING;
83#if LED_DISABLE_TIMEOUT > 0
84static uint32_t led_anykey_timer;
85#endif // LED_DISABLE_TIMEOUT > 0
86
87// double buffers
88static uint32_t led_timer_buffer;
89#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
90static last_hit_t last_hit_buffer;
91#endif // LED_MATRIX_KEYREACTIVE_ENABLED
92
93// split led matrix
94#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
95const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;
96#endif
68 97
69void eeconfig_update_led_matrix(uint32_t config_value) { eeprom_update_dword(EECONFIG_LED_MATRIX, config_value); } 98void eeconfig_read_led_matrix(void) { eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }
99
100void eeconfig_update_led_matrix(void) { eeprom_update_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }
70 101
71void eeconfig_update_led_matrix_default(void) { 102void eeconfig_update_led_matrix_default(void) {
72 dprintf("eeconfig_update_led_matrix_default\n"); 103 dprintf("eeconfig_update_led_matrix_default\n");
73 led_matrix_eeconfig.enable = 1; 104 led_matrix_eeconfig.enable = 1;
74 led_matrix_eeconfig.mode = LED_MATRIX_UNIFORM_BRIGHTNESS; 105 led_matrix_eeconfig.mode = LED_MATRIX_STARTUP_MODE;
75 led_matrix_eeconfig.val = 128; 106 led_matrix_eeconfig.val = LED_MATRIX_STARTUP_VAL;
76 led_matrix_eeconfig.speed = 0; 107 led_matrix_eeconfig.speed = LED_MATRIX_STARTUP_SPD;
77 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 108 led_matrix_eeconfig.flags = LED_FLAG_ALL;
109 eeconfig_update_led_matrix();
78} 110}
79 111
80void eeconfig_debug_led_matrix(void) { 112void eeconfig_debug_led_matrix(void) {
81 dprintf("led_matrix_eeconfig eeprom\n"); 113 dprintf("led_matrix_eeconfig EEPROM\n");
82 dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable); 114 dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable);
83 dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode); 115 dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode);
84 dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val); 116 dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val);
85 dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed); 117 dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed);
118 dprintf("led_matrix_eeconfig.flags = %d\n", led_matrix_eeconfig.flags);
86} 119}
87 120
88uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255}; 121__attribute__((weak)) uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { return 0; }
89uint8_t g_last_led_count = 0;
90 122
91uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { 123uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
92 uint8_t led_count = 0; 124 uint8_t led_count = led_matrix_map_row_column_to_led_kb(row, column, led_i);
93 uint8_t led_index = g_led_config.matrix_co[row][column]; 125 uint8_t led_index = g_led_config.matrix_co[row][column];
94 if (led_index != NO_LED) { 126 if (led_index != NO_LED) {
95 led_i[led_count] = led_index; 127 led_i[led_count] = led_index;
@@ -100,88 +132,227 @@ uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
100 132
101void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); } 133void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); }
102 134
103void led_matrix_set_index_value(int index, uint8_t value) { led_matrix_driver.set_value(index, value); } 135void led_matrix_set_value(int index, uint8_t value) {
104 136#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
105void led_matrix_set_index_value_all(uint8_t value) { led_matrix_driver.set_value_all(value); } 137 if (!is_keyboard_left() && index >= k_led_matrix_split[0])
106 138# ifdef USE_CIE1931_CURVE
107bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { 139 led_matrix_driver.set_value(index - k_led_matrix_split[0], pgm_read_byte(&CIE1931_CURVE[value]));
108 if (record->event.pressed) { 140# else
109 uint8_t led[8]; 141 led_matrix_driver.set_value(index - k_led_matrix_split[0], value);
110 uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led); 142# endif
111 if (led_count > 0) { 143 else if (is_keyboard_left() && index < k_led_matrix_split[0])
112 for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) { 144#endif
113 g_last_led_hit[i - 1] = g_last_led_hit[i - 2]; 145#ifdef USE_CIE1931_CURVE
114 } 146 led_matrix_driver.set_value(index, pgm_read_byte(&CIE1931_CURVE[value]));
115 g_last_led_hit[0] = led[0]; 147#else
116 g_last_led_count = MIN(LED_HITS_TO_REMEMBER, g_last_led_count + 1); 148 led_matrix_driver.set_value(index, value);
117 } 149#endif
118 for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 0; 150}
119 g_any_key_hit = 0;
120 } else {
121#ifdef LED_MATRIX_KEYRELEASES
122 uint8_t led[8];
123 uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led);
124 for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 255;
125 151
126 g_any_key_hit = 255; 152void led_matrix_set_value_all(uint8_t value) {
153#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
154 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) led_matrix_set_value(i, value);
155#else
156# ifdef USE_CIE1931_CURVE
157 led_matrix_driver.set_value_all(pgm_read_byte(&CIE1931_CURVE[value]));
158# else
159 led_matrix_driver.set_value_all(value);
160# endif
127#endif 161#endif
128 }
129 return true;
130} 162}
131 163
132void led_matrix_set_suspend_state(bool state) { g_suspend_state = state; } 164void process_led_matrix(uint8_t row, uint8_t col, bool pressed) {
165#ifndef LED_MATRIX_SPLIT
166 if (!is_keyboard_master()) return;
167#endif
168#if LED_DISABLE_TIMEOUT > 0
169 led_anykey_timer = 0;
170#endif // LED_DISABLE_TIMEOUT > 0
133 171
134// All LEDs off 172#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
135void led_matrix_all_off(void) { led_matrix_set_index_value_all(0); } 173 uint8_t led[LED_HITS_TO_REMEMBER];
174 uint8_t led_count = 0;
136 175
137// Uniform brightness 176# if defined(LED_MATRIX_KEYRELEASES)
138void led_matrix_uniform_brightness(void) { led_matrix_set_index_value_all(LED_MATRIX_MAXIMUM_BRIGHTNESS / BACKLIGHT_LEVELS * led_matrix_eeconfig.val); } 177 if (!pressed)
178# elif defined(LED_MATRIX_KEYPRESSES)
179 if (pressed)
180# endif // defined(LED_MATRIX_KEYRELEASES)
181 {
182 led_count = led_matrix_map_row_column_to_led(row, col, led);
183 }
139 184
140void led_matrix_custom(void) {} 185 if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) {
186 memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count);
187 memcpy(&last_hit_buffer.y[0], &last_hit_buffer.y[led_count], LED_HITS_TO_REMEMBER - led_count);
188 memcpy(&last_hit_buffer.tick[0], &last_hit_buffer.tick[led_count], (LED_HITS_TO_REMEMBER - led_count) * 2); // 16 bit
189 memcpy(&last_hit_buffer.index[0], &last_hit_buffer.index[led_count], LED_HITS_TO_REMEMBER - led_count);
190 last_hit_buffer.count--;
191 }
141 192
142void led_matrix_task(void) { 193 for (uint8_t i = 0; i < led_count; i++) {
143 if (!led_matrix_eeconfig.enable) { 194 uint8_t index = last_hit_buffer.count;
144 led_matrix_all_off(); 195 last_hit_buffer.x[index] = g_led_config.point[led[i]].x;
145 led_matrix_indicators(); 196 last_hit_buffer.y[index] = g_led_config.point[led[i]].y;
146 return; 197 last_hit_buffer.index[index] = led[i];
198 last_hit_buffer.tick[index] = 0;
199 last_hit_buffer.count++;
147 } 200 }
201#endif // LED_MATRIX_KEYREACTIVE_ENABLED
148 202
149 g_tick++; 203#if defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_LED_MATRIX_TYPING_HEATMAP)
204 if (led_matrix_eeconfig.mode == LED_MATRIX_TYPING_HEATMAP) {
205 process_led_matrix_typing_heatmap(row, col);
206 }
207#endif // defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_LED_MATRIX_TYPING_HEATMAP)
208}
150 209
151 if (g_any_key_hit < 0xFFFFFFFF) { 210static bool led_matrix_none(effect_params_t *params) {
152 g_any_key_hit++; 211 if (!params->init) {
212 return false;
153 } 213 }
154 214
155 for (int led = 0; led < DRIVER_LED_TOTAL; led++) { 215 led_matrix_set_value_all(0);
156 if (g_key_hit[led] < 255) { 216 return false;
157 if (g_key_hit[led] == 254) g_last_led_count = MAX(g_last_led_count - 1, 0); 217}
158 g_key_hit[led]++; 218
219static bool led_matrix_uniform_brightness(effect_params_t *params) {
220 LED_MATRIX_USE_LIMITS(led_min, led_max);
221
222 uint8_t val = led_matrix_eeconfig.val;
223 for (uint8_t i = led_min; i < led_max; i++) {
224 LED_MATRIX_TEST_LED_FLAGS();
225 led_matrix_set_value(i, val);
226 }
227 return led_max < DRIVER_LED_TOTAL;
228}
229
230static void led_task_timers(void) {
231#if defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_DISABLE_TIMEOUT > 0
232 uint32_t deltaTime = sync_timer_elapsed32(led_timer_buffer);
233#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_DISABLE_TIMEOUT > 0
234 led_timer_buffer = sync_timer_read32();
235
236 // Update double buffer timers
237#if LED_DISABLE_TIMEOUT > 0
238 if (led_anykey_timer < UINT32_MAX) {
239 if (UINT32_MAX - deltaTime < led_anykey_timer) {
240 led_anykey_timer = UINT32_MAX;
241 } else {
242 led_anykey_timer += deltaTime;
243 }
244 }
245#endif // LED_DISABLE_TIMEOUT > 0
246
247 // Update double buffer last hit timers
248#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
249 uint8_t count = last_hit_buffer.count;
250 for (uint8_t i = 0; i < count; ++i) {
251 if (UINT16_MAX - deltaTime < last_hit_buffer.tick[i]) {
252 last_hit_buffer.count--;
253 continue;
159 } 254 }
255 last_hit_buffer.tick[i] += deltaTime;
160 } 256 }
257#endif // LED_MATRIX_KEYREACTIVE_ENABLED
258}
161 259
162 // Ideally we would also stop sending zeros to the LED driver PWM buffers 260static void led_task_sync(void) {
163 // while suspended and just do a software shutdown. This is a cheap hack for now. 261 // next task
164 bool suspend_backlight = ((g_suspend_state && LED_DISABLE_WHEN_USB_SUSPENDED) || (LED_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > LED_DISABLE_AFTER_TIMEOUT * 60 * 20)); 262 if (sync_timer_elapsed32(g_led_timer) >= LED_MATRIX_LED_FLUSH_LIMIT) led_task_state = STARTING;
165 uint8_t effect = suspend_backlight ? 0 : led_matrix_eeconfig.mode; 263}
264
265static void led_task_start(void) {
266 // reset iter
267 led_effect_params.iter = 0;
268
269 // update double buffers
270 g_led_timer = led_timer_buffer;
271#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
272 g_last_hit_tracker = last_hit_buffer;
273#endif // LED_MATRIX_KEYREACTIVE_ENABLED
274
275 // next task
276 led_task_state = RENDERING;
277}
278
279static void led_task_render(uint8_t effect) {
280 bool rendering = false;
281 led_effect_params.init = (effect != led_last_effect) || (led_matrix_eeconfig.enable != led_last_enable);
282 if (led_effect_params.flags != led_matrix_eeconfig.flags) {
283 led_effect_params.flags = led_matrix_eeconfig.flags;
284 led_matrix_set_value_all(0);
285 }
166 286
167 // this gets ticked at 20 Hz.
168 // each effect can opt to do calculations 287 // each effect can opt to do calculations
169 // and/or request PWM buffer updates. 288 // and/or request PWM buffer updates.
170 switch (effect) { 289 switch (effect) {
171 case LED_MATRIX_UNIFORM_BRIGHTNESS: 290 case LED_MATRIX_NONE:
172 led_matrix_uniform_brightness(); 291 rendering = led_matrix_none(&led_effect_params);
173 break; 292 break;
174 default: 293 case LED_MATRIX_UNIFORM_BRIGHTNESS:
175 led_matrix_custom(); 294 rendering = led_matrix_uniform_brightness(&led_effect_params);
176 break; 295 break;
177 } 296 }
178 297
179 if (!suspend_backlight) { 298 led_effect_params.iter++;
180 led_matrix_indicators(); 299
300 // next task
301 if (!rendering) {
302 led_task_state = FLUSHING;
303 if (!led_effect_params.init && effect == LED_MATRIX_NONE) {
304 // We only need to flush once if we are LED_MATRIX_NONE
305 led_task_state = SYNCING;
306 }
181 } 307 }
308}
182 309
183 // Tell the LED driver to update its state 310static void led_task_flush(uint8_t effect) {
184 led_matrix_driver.flush(); 311 // update last trackers after the first full render so we can init over several frames
312 led_last_effect = effect;
313 led_last_enable = led_matrix_eeconfig.enable;
314
315 // update pwm buffers
316 led_matrix_update_pwm_buffers();
317
318 // next task
319 led_task_state = SYNCING;
320}
321
322void led_matrix_task(void) {
323 led_task_timers();
324
325 // Ideally we would also stop sending zeros to the LED driver PWM buffers
326 // while suspended and just do a software shutdown. This is a cheap hack for now.
327 bool suspend_backlight =
328#if LED_DISABLE_WHEN_USB_SUSPENDED == true
329 g_suspend_state ||
330#endif // LED_DISABLE_WHEN_USB_SUSPENDED == true
331#if LED_DISABLE_TIMEOUT > 0
332 (led_anykey_timer > (uint32_t)LED_DISABLE_TIMEOUT) ||
333#endif // LED_DISABLE_TIMEOUT > 0
334 false;
335
336 uint8_t effect = suspend_backlight || !led_matrix_eeconfig.enable ? 0 : led_matrix_eeconfig.mode;
337
338 switch (led_task_state) {
339 case STARTING:
340 led_task_start();
341 break;
342 case RENDERING:
343 led_task_render(effect);
344 if (effect) {
345 led_matrix_indicators();
346 led_matrix_indicators_advanced(&led_effect_params);
347 }
348 break;
349 case FLUSHING:
350 led_task_flush(effect);
351 break;
352 case SYNCING:
353 led_task_sync();
354 break;
355 }
185} 356}
186 357
187void led_matrix_indicators(void) { 358void led_matrix_indicators(void) {
@@ -193,33 +364,42 @@ __attribute__((weak)) void led_matrix_indicators_kb(void) {}
193 364
194__attribute__((weak)) void led_matrix_indicators_user(void) {} 365__attribute__((weak)) void led_matrix_indicators_user(void) {}
195 366
196// void led_matrix_set_indicator_index(uint8_t *index, uint8_t row, uint8_t column) 367void led_matrix_indicators_advanced(effect_params_t *params) {
197// { 368 /* special handling is needed for "params->iter", since it's already been incremented.
198// if (row >= MATRIX_ROWS) 369 * Could move the invocations to led_task_render, but then it's missing a few checks
199// { 370 * and not sure which would be better. Otherwise, this should be called from
200// // Special value, 255=none, 254=all 371 * led_task_render, right before the iter++ line.
201// *index = row; 372 */
202// } 373#if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL
203// else 374 uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * (params->iter - 1);
204// { 375 uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT;
205// // This needs updated to something like 376 if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;
206// // uint8_t led[8]; 377#else
207// // uint8_t led_count = map_row_column_to_led(row, column, led); 378 uint8_t min = 0;
208// // for(uint8_t i = 0; i < led_count; i++) 379 uint8_t max = DRIVER_LED_TOTAL;
209// map_row_column_to_led(row, column, index); 380#endif
210// } 381 led_matrix_indicators_advanced_kb(min, max);
211// } 382 led_matrix_indicators_advanced_user(min, max);
383}
384
385__attribute__((weak)) void led_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) {}
386
387__attribute__((weak)) void led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {}
212 388
213void led_matrix_init(void) { 389void led_matrix_init(void) {
214 led_matrix_driver.init(); 390 led_matrix_driver.init();
215 391
216 // Wait half a second for the driver to finish initializing 392#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
217 wait_ms(500); 393 g_last_hit_tracker.count = 0;
394 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
395 g_last_hit_tracker.tick[i] = UINT16_MAX;
396 }
218 397
219 // clear the key hits 398 last_hit_buffer.count = 0;
220 for (int led = 0; led < DRIVER_LED_TOTAL; led++) { 399 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
221 g_key_hit[led] = 255; 400 last_hit_buffer.tick[i] = UINT16_MAX;
222 } 401 }
402#endif // LED_MATRIX_KEYREACTIVE_ENABLED
223 403
224 if (!eeconfig_is_enabled()) { 404 if (!eeconfig_is_enabled()) {
225 dprintf("led_matrix_init_drivers eeconfig is not enabled.\n"); 405 dprintf("led_matrix_init_drivers eeconfig is not enabled.\n");
@@ -227,122 +407,135 @@ void led_matrix_init(void) {
227 eeconfig_update_led_matrix_default(); 407 eeconfig_update_led_matrix_default();
228 } 408 }
229 409
230 led_matrix_eeconfig.raw = eeconfig_read_led_matrix(); 410 eeconfig_read_led_matrix();
231
232 if (!led_matrix_eeconfig.mode) { 411 if (!led_matrix_eeconfig.mode) {
233 dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n"); 412 dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");
234 eeconfig_update_led_matrix_default(); 413 eeconfig_update_led_matrix_default();
235 led_matrix_eeconfig.raw = eeconfig_read_led_matrix();
236 } 414 }
237
238 eeconfig_debug_led_matrix(); // display current eeprom values 415 eeconfig_debug_led_matrix(); // display current eeprom values
239} 416}
240 417
241// Deals with the messy details of incrementing an integer 418void led_matrix_set_suspend_state(bool state) {
242static uint8_t increment(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { 419 if (LED_DISABLE_WHEN_USB_SUSPENDED && state) {
243 int16_t new_value = value; 420 led_matrix_set_value_all(0); // turn off all LEDs when suspending
244 new_value += step; 421 }
245 return MIN(MAX(new_value, min), max); 422 g_suspend_state = state;
246} 423}
247 424
248static uint8_t decrement(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { 425bool led_matrix_get_suspend_state(void) { return g_suspend_state; }
249 int16_t new_value = value;
250 new_value -= step;
251 return MIN(MAX(new_value, min), max);
252}
253 426
254// void *backlight_get_custom_key_value_eeprom_address(uint8_t led) { 427void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) {
255// // 3 bytes per value
256// return EECONFIG_LED_MATRIX + (led * 3);
257// }
258
259// void backlight_get_key_value(uint8_t led, uint8_t *value) {
260// void *address = backlight_get_custom_key_value_eeprom_address(led);
261// value = eeprom_read_byte(address);
262// }
263
264// void backlight_set_key_value(uint8_t row, uint8_t column, uint8_t value) {
265// uint8_t led[8];
266// uint8_t led_count = map_row_column_to_led(row, column, led);
267// for(uint8_t i = 0; i < led_count; i++) {
268// if (led[i] < DRIVER_LED_TOTAL) {
269// void *address = backlight_get_custom_key_value_eeprom_address(led[i]);
270// eeprom_update_byte(address, value);
271// }
272// }
273// }
274
275uint32_t led_matrix_get_tick(void) { return g_tick; }
276
277void led_matrix_toggle(void) {
278 led_matrix_eeconfig.enable ^= 1; 428 led_matrix_eeconfig.enable ^= 1;
279 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 429 led_task_state = STARTING;
430 if (write_to_eeprom) {
431 eeconfig_update_led_matrix();
432 }
433 dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable);
280} 434}
435void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); }
436void led_matrix_toggle(void) { led_matrix_toggle_eeprom_helper(true); }
281 437
282void led_matrix_enable(void) { 438void led_matrix_enable(void) {
283 led_matrix_eeconfig.enable = 1; 439 led_matrix_enable_noeeprom();
284 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 440 eeconfig_update_led_matrix();
285} 441}
286 442
287void led_matrix_enable_noeeprom(void) { led_matrix_eeconfig.enable = 1; } 443void led_matrix_enable_noeeprom(void) {
444 if (!led_matrix_eeconfig.enable) led_task_state = STARTING;
445 led_matrix_eeconfig.enable = 1;
446}
288 447
289void led_matrix_disable(void) { 448void led_matrix_disable(void) {
449 led_matrix_disable_noeeprom();
450 eeconfig_update_led_matrix();
451}
452
453void led_matrix_disable_noeeprom(void) {
454 if (led_matrix_eeconfig.enable) led_task_state = STARTING;
290 led_matrix_eeconfig.enable = 0; 455 led_matrix_eeconfig.enable = 0;
291 eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
292} 456}
293 457
294void led_matrix_disable_noeeprom(void) { led_matrix_eeconfig.enable = 0; } 458uint8_t led_matrix_is_enabled(void) { return led_matrix_eeconfig.enable; }
295 459
296void led_matrix_step(void) { 460void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
297 led_matrix_eeconfig.mode++; 461 if (!led_matrix_eeconfig.enable) {
298 if (led_matrix_eeconfig.mode >= LED_MATRIX_EFFECT_MAX) { 462 return;
299 led_matrix_eeconfig.mode = 1;
300 } 463 }
301 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 464 if (mode < 1) {
302} 465 led_matrix_eeconfig.mode = 1;
303 466 } else if (mode >= LED_MATRIX_EFFECT_MAX) {
304void led_matrix_step_reverse(void) {
305 led_matrix_eeconfig.mode--;
306 if (led_matrix_eeconfig.mode < 1) {
307 led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1; 467 led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1;
468 } else {
469 led_matrix_eeconfig.mode = mode;
470 }
471 led_task_state = STARTING;
472 if (write_to_eeprom) {
473 eeconfig_update_led_matrix();
308 } 474 }
309 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 475 dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode);
310} 476}
477void led_matrix_mode_noeeprom(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, false); }
478void led_matrix_mode(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, true); }
311 479
312void led_matrix_increase_val(void) { 480uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; }
313 led_matrix_eeconfig.val = increment(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS);
314 eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
315}
316 481
317void led_matrix_decrease_val(void) { 482void led_matrix_step_helper(bool write_to_eeprom) {
318 led_matrix_eeconfig.val = decrement(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); 483 uint8_t mode = led_matrix_eeconfig.mode + 1;
319 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 484 led_matrix_mode_eeprom_helper((mode < LED_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom);
320} 485}
486void led_matrix_step_noeeprom(void) { led_matrix_step_helper(false); }
487void led_matrix_step(void) { led_matrix_step_helper(true); }
321 488
322void led_matrix_increase_speed(void) { 489void led_matrix_step_reverse_helper(bool write_to_eeprom) {
323 led_matrix_eeconfig.speed = increment(led_matrix_eeconfig.speed, 1, 0, 3); 490 uint8_t mode = led_matrix_eeconfig.mode - 1;
324 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this 491 led_matrix_mode_eeprom_helper((mode < 1) ? LED_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom);
325} 492}
493void led_matrix_step_reverse_noeeprom(void) { led_matrix_step_reverse_helper(false); }
494void led_matrix_step_reverse(void) { led_matrix_step_reverse_helper(true); }
326 495
327void led_matrix_decrease_speed(void) { 496void led_matrix_set_val_eeprom_helper(uint8_t val, bool write_to_eeprom) {
328 led_matrix_eeconfig.speed = decrement(led_matrix_eeconfig.speed, 1, 0, 3); 497 if (!led_matrix_eeconfig.enable) {
329 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this 498 return;
499 }
500 led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val;
501 if (write_to_eeprom) {
502 eeconfig_update_led_matrix();
503 }
504 dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val);
330} 505}
506void led_matrix_set_val_noeeprom(uint8_t val) { led_matrix_set_val_eeprom_helper(val, false); }
507void led_matrix_set_val(uint8_t val) { led_matrix_set_val_eeprom_helper(val, true); }
331 508
332void led_matrix_mode(uint8_t mode, bool eeprom_write) { 509uint8_t led_matrix_get_val(void) { return led_matrix_eeconfig.val; }
333 led_matrix_eeconfig.mode = mode; 510
334 if (eeprom_write) { 511void led_matrix_increase_val_helper(bool write_to_eeprom) { led_matrix_set_val_eeprom_helper(qadd8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); }
335 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 512void led_matrix_increase_val_noeeprom(void) { led_matrix_increase_val_helper(false); }
513void led_matrix_increase_val(void) { led_matrix_increase_val_helper(true); }
514
515void led_matrix_decrease_val_helper(bool write_to_eeprom) { led_matrix_set_val_eeprom_helper(qsub8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); }
516void led_matrix_decrease_val_noeeprom(void) { led_matrix_decrease_val_helper(false); }
517void led_matrix_decrease_val(void) { led_matrix_decrease_val_helper(true); }
518
519void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
520 led_matrix_eeconfig.speed = speed;
521 if (write_to_eeprom) {
522 eeconfig_update_led_matrix();
336 } 523 }
524 dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed);
337} 525}
526void led_matrix_set_speed_noeeprom(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, false); }
527void led_matrix_set_speed(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, true); }
338 528
339uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; } 529uint8_t led_matrix_get_speed(void) { return led_matrix_eeconfig.speed; }
340 530
341void led_matrix_set_value_noeeprom(uint8_t val) { led_matrix_eeconfig.val = val; } 531void led_matrix_increase_speed_helper(bool write_to_eeprom) { led_matrix_set_speed_eeprom_helper(qadd8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); }
532void led_matrix_increase_speed_noeeprom(void) { led_matrix_increase_speed_helper(false); }
533void led_matrix_increase_speed(void) { led_matrix_increase_speed_helper(true); }
342 534
343void led_matrix_set_value(uint8_t val) { 535void led_matrix_decrease_speed_helper(bool write_to_eeprom) { led_matrix_set_speed_eeprom_helper(qsub8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); }
344 led_matrix_set_value_noeeprom(val); 536void led_matrix_decrease_speed_noeeprom(void) { led_matrix_decrease_speed_helper(false); }
345 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 537void led_matrix_decrease_speed(void) { led_matrix_decrease_speed_helper(true); }
346} 538
539led_flags_t led_matrix_get_flags(void) { return led_matrix_eeconfig.flags; }
347 540
348void backlight_set(uint8_t val) { led_matrix_set_value(val); } 541void led_matrix_set_flags(led_flags_t flags) { led_matrix_eeconfig.flags = flags; }
diff --git a/quantum/led_matrix.h b/quantum/led_matrix.h
index 85bae43c1..f35bbe209 100644
--- a/quantum/led_matrix.h
+++ b/quantum/led_matrix.h
@@ -19,61 +19,104 @@
19 19
20#pragma once 20#pragma once
21 21
22#include <stdint.h>
23#include <stdbool.h>
22#include "led_matrix_types.h" 24#include "led_matrix_types.h"
25#include "quantum.h"
23 26
24#ifndef BACKLIGHT_ENABLE 27#ifdef IS31FL3731
25# error You must define BACKLIGHT_ENABLE with LED_MATRIX_ENABLE 28# include "is31fl3731-simple.h"
26#endif 29#endif
27 30
31#ifndef LED_MATRIX_LED_FLUSH_LIMIT
32# define LED_MATRIX_LED_FLUSH_LIMIT 16
33#endif
34
35#ifndef LED_MATRIX_LED_PROCESS_LIMIT
36# define LED_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5
37#endif
38
39#if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL
40# define LED_MATRIX_USE_LIMITS(min, max) \
41 uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter; \
42 uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT; \
43 if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;
44#else
45# define LED_MATRIX_USE_LIMITS(min, max) \
46 uint8_t min = 0; \
47 uint8_t max = DRIVER_LED_TOTAL;
48#endif
49
50#define LED_MATRIX_TEST_LED_FLAGS() \
51 if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) continue
52
28enum led_matrix_effects { 53enum led_matrix_effects {
29 LED_MATRIX_UNIFORM_BRIGHTNESS = 1, 54 LED_MATRIX_NONE = 0,
55
56 LED_MATRIX_UNIFORM_BRIGHTNESS,
30 // All new effects go above this line 57 // All new effects go above this line
58
31 LED_MATRIX_EFFECT_MAX 59 LED_MATRIX_EFFECT_MAX
32}; 60};
33 61
34void led_matrix_set_index_value(int index, uint8_t value); 62void eeconfig_update_led_matrix_default(void);
35void led_matrix_set_index_value_all(uint8_t value); 63void eeconfig_update_led_matrix(void);
64void eeconfig_debug_led_matrix(void);
65
66uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
67uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
68
69void led_matrix_set_value(int index, uint8_t value);
70void led_matrix_set_value_all(uint8_t value);
71
72void process_led_matrix(uint8_t row, uint8_t col, bool pressed);
73
74void led_matrix_task(void);
36 75
37// This runs after another backlight effect and replaces 76// This runs after another backlight effect and replaces
38// colors already set 77// values already set
39void led_matrix_indicators(void); 78void led_matrix_indicators(void);
40void led_matrix_indicators_kb(void); 79void led_matrix_indicators_kb(void);
41void led_matrix_indicators_user(void); 80void led_matrix_indicators_user(void);
42 81
43void led_matrix_init(void); 82void led_matrix_indicators_advanced(effect_params_t *params);
44void led_matrix_setup_drivers(void); 83void led_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max);
45 84void led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max);
46void led_matrix_set_suspend_state(bool state);
47void led_matrix_set_indicator_state(uint8_t state);
48 85
49void led_matrix_task(void); 86void led_matrix_init(void);
50 87
51// This should not be called from an interrupt 88void led_matrix_set_suspend_state(bool state);
52// (eg. from a timer interrupt). 89bool led_matrix_get_suspend_state(void);
53// Call this while idle (in between matrix scans). 90void led_matrix_toggle(void);
54// If the buffer is dirty, it will update the driver with the buffer. 91void led_matrix_toggle_noeeprom(void);
55void led_matrix_update_pwm_buffers(void); 92void led_matrix_enable(void);
56 93void led_matrix_enable_noeeprom(void);
57bool process_led_matrix(uint16_t keycode, keyrecord_t *record); 94void led_matrix_disable(void);
58 95void led_matrix_disable_noeeprom(void);
59uint32_t led_matrix_get_tick(void); 96uint8_t led_matrix_is_enabled(void);
60 97void led_matrix_mode(uint8_t mode);
61void led_matrix_toggle(void); 98void led_matrix_mode_noeeprom(uint8_t mode);
62void led_matrix_enable(void); 99uint8_t led_matrix_get_mode(void);
63void led_matrix_enable_noeeprom(void); 100void led_matrix_step(void);
64void led_matrix_disable(void); 101void led_matrix_step_noeeprom(void);
65void led_matrix_disable_noeeprom(void); 102void led_matrix_step_reverse(void);
66void led_matrix_step(void); 103void led_matrix_step_reverse_noeeprom(void);
67void led_matrix_step_reverse(void); 104void led_matrix_set_val(uint8_t val);
68void led_matrix_increase_val(void); 105void led_matrix_set_val_noeeprom(uint8_t val);
69void led_matrix_decrease_val(void); 106uint8_t led_matrix_get_val(void);
70void led_matrix_increase_speed(void); 107void led_matrix_increase_val(void);
71void led_matrix_decrease_speed(void); 108void led_matrix_increase_val_noeeprom(void);
72void led_matrix_mode(uint8_t mode, bool eeprom_write); 109void led_matrix_decrease_val(void);
73void led_matrix_mode_noeeprom(uint8_t mode); 110void led_matrix_decrease_val_noeeprom(void);
74uint8_t led_matrix_get_mode(void); 111void led_matrix_set_speed(uint8_t speed);
75void led_matrix_set_value(uint8_t mode); 112void led_matrix_set_speed_noeeprom(uint8_t speed);
76void led_matrix_set_value_noeeprom(uint8_t mode); 113uint8_t led_matrix_get_speed(void);
114void led_matrix_increase_speed(void);
115void led_matrix_increase_speed_noeeprom(void);
116void led_matrix_decrease_speed(void);
117void led_matrix_decrease_speed_noeeprom(void);
118led_flags_t led_matrix_get_flags(void);
119void led_matrix_set_flags(led_flags_t flags);
77 120
78typedef struct { 121typedef struct {
79 /* Perform any initialisation required for the other driver functions to work. */ 122 /* Perform any initialisation required for the other driver functions to work. */
@@ -91,4 +134,12 @@ extern const led_matrix_driver_t led_matrix_driver;
91 134
92extern led_eeconfig_t led_matrix_eeconfig; 135extern led_eeconfig_t led_matrix_eeconfig;
93 136
137extern bool g_suspend_state;
138extern uint32_t g_led_timer;
94extern led_config_t g_led_config; 139extern led_config_t g_led_config;
140#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
141extern last_hit_t g_last_hit_tracker;
142#endif
143#ifdef LED_MATRIX_FRAMEBUFFER_EFFECTS
144extern uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS];
145#endif
diff --git a/quantum/led_matrix_drivers.c b/quantum/led_matrix_drivers.c
index eddf3f286..370c5e685 100644
--- a/quantum/led_matrix_drivers.c
+++ b/quantum/led_matrix_drivers.c
@@ -15,9 +15,6 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18#include <stdint.h>
19#include <stdbool.h>
20#include "quantum.h"
21#include "led_matrix.h" 18#include "led_matrix.h"
22 19
23/* Each driver needs to define a struct: 20/* Each driver needs to define a struct:
@@ -30,10 +27,6 @@
30 27
31#if defined(IS31FL3731) || defined(IS31FL3733) 28#if defined(IS31FL3731) || defined(IS31FL3733)
32 29
33# if defined(IS31FL3731)
34# include "is31fl3731-simple.h"
35# endif
36
37# include "i2c_master.h" 30# include "i2c_master.h"
38 31
39static void init(void) { 32static void init(void) {
diff --git a/quantum/led_matrix_types.h b/quantum/led_matrix_types.h
index 669b67042..13f44b07e 100644
--- a/quantum/led_matrix_types.h
+++ b/quantum/led_matrix_types.h
@@ -29,16 +29,43 @@
29# pragma pack(push, 1) 29# pragma pack(push, 1)
30#endif 30#endif
31 31
32#if defined(LED_MATRIX_KEYPRESSES) || defined(LED_MATRIX_KEYRELEASES)
33# define LED_MATRIX_KEYREACTIVE_ENABLED
34#endif
35
32// Last led hit 36// Last led hit
33#ifndef LED_HITS_TO_REMEMBER 37#ifndef LED_HITS_TO_REMEMBER
34# define LED_HITS_TO_REMEMBER 8 38# define LED_HITS_TO_REMEMBER 8
35#endif // LED_HITS_TO_REMEMBER 39#endif // LED_HITS_TO_REMEMBER
36 40
41#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
42typedef struct PACKED {
43 uint8_t count;
44 uint8_t x[LED_HITS_TO_REMEMBER];
45 uint8_t y[LED_HITS_TO_REMEMBER];
46 uint8_t index[LED_HITS_TO_REMEMBER];
47 uint16_t tick[LED_HITS_TO_REMEMBER];
48} last_hit_t;
49#endif // LED_MATRIX_KEYREACTIVE_ENABLED
50
51typedef enum led_task_states { STARTING, RENDERING, FLUSHING, SYNCING } led_task_states;
52
53typedef uint8_t led_flags_t;
54
55typedef struct PACKED {
56 uint8_t iter;
57 led_flags_t flags;
58 bool init;
59} effect_params_t;
60
37typedef struct PACKED { 61typedef struct PACKED {
38 uint8_t x; 62 uint8_t x;
39 uint8_t y; 63 uint8_t y;
40} point_t; 64} point_t;
41 65
66#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
67#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00)
68
42#define LED_FLAG_ALL 0xFF 69#define LED_FLAG_ALL 0xFF
43#define LED_FLAG_NONE 0x00 70#define LED_FLAG_NONE 0x00
44#define LED_FLAG_MODIFIER 0x01 71#define LED_FLAG_MODIFIER 0x01
@@ -56,11 +83,12 @@ typedef struct PACKED {
56typedef union { 83typedef union {
57 uint32_t raw; 84 uint32_t raw;
58 struct PACKED { 85 struct PACKED {
59 uint8_t enable : 2; 86 uint8_t enable : 2;
60 uint8_t mode : 6; 87 uint8_t mode : 6;
61 uint16_t reserved; 88 uint16_t reserved;
62 uint8_t val; 89 uint8_t val;
63 uint8_t speed; // EECONFIG needs to be increased to support this 90 uint8_t speed; // EECONFIG needs to be increased to support this
91 led_flags_t flags;
64 }; 92 };
65} led_eeconfig_t; 93} led_eeconfig_t;
66 94
diff --git a/quantum/matrix.h b/quantum/matrix.h
index ce57010a4..3fe691aae 100644
--- a/quantum/matrix.h
+++ b/quantum/matrix.h
@@ -74,6 +74,11 @@ void matrix_scan_kb(void);
74void matrix_init_user(void); 74void matrix_init_user(void);
75void matrix_scan_user(void); 75void matrix_scan_user(void);
76 76
77#ifdef SPLIT_KEYBOARD
78void matrix_slave_scan_kb(void);
79void matrix_slave_scan_user(void);
80#endif
81
77#ifdef __cplusplus 82#ifdef __cplusplus
78} 83}
79#endif 84#endif
diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk
index f7329fc4d..edf44f5dc 100644
--- a/quantum/mcu_selection.mk
+++ b/quantum/mcu_selection.mk
@@ -81,6 +81,33 @@ ifneq ($(findstring MK20DX256, $(MCU)),)
81 BOARD ?= PJRC_TEENSY_3_1 81 BOARD ?= PJRC_TEENSY_3_1
82endif 82endif
83 83
84ifneq ($(findstring MK66F18, $(MCU)),)
85 # Cortex version
86 MCU = cortex-m4
87
88 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
89 ARMV = 7
90
91 ## chip/board settings
92 # - the next two should match the directories in
93 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
94 MCU_FAMILY = KINETIS
95 MCU_SERIES = MK66F18
96
97 # Linker script to use
98 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
99 # or <keyboard_dir>/ld/
100 MCU_LDSCRIPT ?= MK66FX1M0
101
102 # Startup code to use
103 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
104 MCU_STARTUP ?= MK66F18
105
106 # Board: it should exist either in <chibios>/os/hal/boards/,
107 # <keyboard_dir>/boards/, or drivers/boards/
108 BOARD ?= PJRC_TEENSY_3_6
109endif
110
84ifneq ($(findstring STM32F042, $(MCU)),) 111ifneq ($(findstring STM32F042, $(MCU)),)
85 # Cortex version 112 # Cortex version
86 MCU = cortex-m0 113 MCU = cortex-m0
@@ -112,6 +139,9 @@ ifneq ($(findstring STM32F042, $(MCU)),)
112 # Options to pass to dfu-util when flashing 139 # Options to pass to dfu-util when flashing
113 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 140 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
114 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 141 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
142
143 # UF2 settings
144 UF2_FAMILY ?= STM32F0
115endif 145endif
116 146
117ifneq ($(findstring STM32F072, $(MCU)),) 147ifneq ($(findstring STM32F072, $(MCU)),)
@@ -145,6 +175,9 @@ ifneq ($(findstring STM32F072, $(MCU)),)
145 # Options to pass to dfu-util when flashing 175 # Options to pass to dfu-util when flashing
146 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 176 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
147 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 177 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
178
179 # UF2 settings
180 UF2_FAMILY ?= STM32F0
148endif 181endif
149 182
150ifneq ($(findstring STM32F103, $(MCU)),) 183ifneq ($(findstring STM32F103, $(MCU)),)
@@ -178,6 +211,9 @@ ifneq ($(findstring STM32F103, $(MCU)),)
178 # Options to pass to dfu-util when flashing 211 # Options to pass to dfu-util when flashing
179 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 212 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
180 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 213 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
214
215 # UF2 settings
216 UF2_FAMILY ?= STM32F1
181endif 217endif
182 218
183ifneq ($(findstring STM32F303, $(MCU)),) 219ifneq ($(findstring STM32F303, $(MCU)),)
@@ -211,6 +247,9 @@ ifneq ($(findstring STM32F303, $(MCU)),)
211 # Options to pass to dfu-util when flashing 247 # Options to pass to dfu-util when flashing
212 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 248 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
213 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 249 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
250
251 # UF2 settings
252 UF2_FAMILY ?= STM32F3
214endif 253endif
215 254
216ifneq ($(findstring STM32F401, $(MCU)),) 255ifneq ($(findstring STM32F401, $(MCU)),)
@@ -244,6 +283,9 @@ ifneq ($(findstring STM32F401, $(MCU)),)
244 # Options to pass to dfu-util when flashing 283 # Options to pass to dfu-util when flashing
245 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 284 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
246 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 285 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
286
287 # UF2 settings
288 UF2_FAMILY ?= STM32F4
247endif 289endif
248 290
249ifneq ($(findstring STM32F411, $(MCU)),) 291ifneq ($(findstring STM32F411, $(MCU)),)
@@ -262,7 +304,12 @@ ifneq ($(findstring STM32F411, $(MCU)),)
262 # Linker script to use 304 # Linker script to use
263 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ 305 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
264 # or <keyboard_dir>/ld/ 306 # or <keyboard_dir>/ld/
265 MCU_LDSCRIPT ?= STM32F411xE 307 ifeq ($(strip $(BOOTLOADER)), tinyuf2)
308 MCU_LDSCRIPT ?= STM32F411xE_tinyuf2
309 FIRMWARE_FORMAT ?= uf2
310 else
311 MCU_LDSCRIPT ?= STM32F411xE
312 endif
266 313
267 # Startup code to use 314 # Startup code to use
268 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/ 315 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
@@ -277,6 +324,43 @@ ifneq ($(findstring STM32F411, $(MCU)),)
277 # Options to pass to dfu-util when flashing 324 # Options to pass to dfu-util when flashing
278 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 325 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
279 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 326 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
327
328 # UF2 settings
329 UF2_FAMILY ?= STM32F4
330endif
331
332ifneq ($(findstring STM32F446, $(MCU)),)
333 # Cortex version
334 MCU = cortex-m4
335
336 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
337 ARMV = 7
338
339 ## chip/board settings
340 # - the next two should match the directories in
341 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
342 MCU_FAMILY = STM32
343 MCU_SERIES = STM32F4xx
344
345 # Linker script to use
346 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
347 # or <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
348 # or <keyboard_dir>/ld/
349 MCU_LDSCRIPT ?= STM32F446xE
350
351 # Startup code to use
352 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
353 MCU_STARTUP ?= stm32f4xx
354
355 # Board: it should exist either in <chibios>/os/hal/boards/,
356 # <keyboard_dir>/boards/, or drivers/boards/
357 BOARD ?= GENERIC_STM32_F446XE
358
359 USE_FPU ?= yes
360
361 # Options to pass to dfu-util when flashing
362 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
363 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
280endif 364endif
281 365
282ifneq ($(findstring STM32G431, $(MCU)),) 366ifneq ($(findstring STM32G431, $(MCU)),)
@@ -310,6 +394,9 @@ ifneq ($(findstring STM32G431, $(MCU)),)
310 # Options to pass to dfu-util when flashing 394 # Options to pass to dfu-util when flashing
311 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 395 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
312 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 396 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
397
398 # UF2 settings
399 UF2_FAMILY ?= STM32G4
313endif 400endif
314 401
315ifneq ($(findstring STM32G474, $(MCU)),) 402ifneq ($(findstring STM32G474, $(MCU)),)
@@ -343,6 +430,9 @@ ifneq ($(findstring STM32G474, $(MCU)),)
343 # Options to pass to dfu-util when flashing 430 # Options to pass to dfu-util when flashing
344 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave 431 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
345 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11 432 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
433
434 # UF2 settings
435 UF2_FAMILY ?= STM32G4
346endif 436endif
347 437
348ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287)) 438ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287))
diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c
index bf359e994..51b0efdb4 100644
--- a/quantum/process_keycode/process_auto_shift.c
+++ b/quantum/process_keycode/process_auto_shift.c
@@ -216,7 +216,18 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
216# endif 216# endif
217 } 217 }
218 } 218 }
219 if (get_auto_shifted_key(keycode, record)) {
220 if (record->event.pressed) {
221 return autoshift_press(keycode, now, record);
222 } else {
223 autoshift_end(keycode, now, false);
224 return false;
225 }
226 }
227 return true;
228}
219 229
230__attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
220 switch (keycode) { 231 switch (keycode) {
221# ifndef NO_AUTO_SHIFT_ALPHA 232# ifndef NO_AUTO_SHIFT_ALPHA
222 case KC_A ... KC_Z: 233 case KC_A ... KC_Z:
@@ -229,14 +240,9 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
229 case KC_MINUS ... KC_SLASH: 240 case KC_MINUS ... KC_SLASH:
230 case KC_NONUS_BSLASH: 241 case KC_NONUS_BSLASH:
231# endif 242# endif
232 if (record->event.pressed) { 243 return true;
233 return autoshift_press(keycode, now, record);
234 } else {
235 autoshift_end(keycode, now, false);
236 return false;
237 }
238 } 244 }
239 return true; 245 return false;
240} 246}
241 247
242#endif 248#endif
diff --git a/quantum/process_keycode/process_auto_shift.h b/quantum/process_keycode/process_auto_shift.h
index 5b2718f11..00a9ab036 100644
--- a/quantum/process_keycode/process_auto_shift.h
+++ b/quantum/process_keycode/process_auto_shift.h
@@ -31,3 +31,4 @@ bool get_autoshift_state(void);
31uint16_t get_autoshift_timeout(void); 31uint16_t get_autoshift_timeout(void);
32void set_autoshift_timeout(uint16_t timeout); 32void set_autoshift_timeout(uint16_t timeout);
33void autoshift_matrix_scan(void); 33void autoshift_matrix_scan(void);
34bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_backlight.c b/quantum/process_keycode/process_backlight.c
index 4d12f6813..8b70339a5 100644
--- a/quantum/process_keycode/process_backlight.c
+++ b/quantum/process_keycode/process_backlight.c
@@ -16,11 +16,35 @@
16 16
17#include "process_backlight.h" 17#include "process_backlight.h"
18 18
19#include "backlight.h" 19#ifdef LED_MATRIX_ENABLE
20# include "led_matrix.h"
21#else
22# include "backlight.h"
23#endif
20 24
21bool process_backlight(uint16_t keycode, keyrecord_t *record) { 25bool process_backlight(uint16_t keycode, keyrecord_t *record) {
22 if (record->event.pressed) { 26 if (record->event.pressed) {
23 switch (keycode) { 27 switch (keycode) {
28#ifdef LED_MATRIX_ENABLE
29 case BL_ON:
30 led_matrix_enable();
31 return false;
32 case BL_OFF:
33 led_matrix_disable();
34 return false;
35 case BL_DEC:
36 led_matrix_decrease_val();
37 return false;
38 case BL_INC:
39 led_matrix_increase_val();
40 return false;
41 case BL_TOGG:
42 led_matrix_toggle();
43 return false;
44 case BL_STEP:
45 led_matrix_step();
46 return false;
47#else
24 case BL_ON: 48 case BL_ON:
25 backlight_level(BACKLIGHT_LEVELS); 49 backlight_level(BACKLIGHT_LEVELS);
26 return false; 50 return false;
@@ -39,10 +63,11 @@ bool process_backlight(uint16_t keycode, keyrecord_t *record) {
39 case BL_STEP: 63 case BL_STEP:
40 backlight_step(); 64 backlight_step();
41 return false; 65 return false;
42#ifdef BACKLIGHT_BREATHING 66# ifdef BACKLIGHT_BREATHING
43 case BL_BRTG: 67 case BL_BRTG:
44 backlight_toggle_breathing(); 68 backlight_toggle_breathing();
45 return false; 69 return false;
70# endif
46#endif 71#endif
47 } 72 }
48 } 73 }
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index 58a615d85..cf63f2514 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -49,7 +49,10 @@ bool process_leader(uint16_t keycode, keyrecord_t *record) {
49 // Leader key set-up 49 // Leader key set-up
50 if (record->event.pressed) { 50 if (record->event.pressed) {
51 if (leading) { 51 if (leading) {
52 if (timer_elapsed(leader_time) < LEADER_TIMEOUT) { 52# ifndef LEADER_NO_TIMEOUT
53 if (timer_elapsed(leader_time) < LEADER_TIMEOUT)
54# endif // LEADER_NO_TIMEOUT
55 {
53# ifndef LEADER_KEY_STRICT_KEY_PROCESSING 56# ifndef LEADER_KEY_STRICT_KEY_PROCESSING
54 if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) { 57 if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
55 keycode = keycode & 0xFF; 58 keycode = keycode & 0xFF;
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h
index 9844f27a1..32ccd42f7 100644
--- a/quantum/process_keycode/process_leader.h
+++ b/quantum/process_keycode/process_leader.h
@@ -35,4 +35,11 @@ void qk_leader_start(void);
35 extern uint16_t leader_time; \ 35 extern uint16_t leader_time; \
36 extern uint16_t leader_sequence[5]; \ 36 extern uint16_t leader_sequence[5]; \
37 extern uint8_t leader_sequence_size 37 extern uint8_t leader_sequence_size
38#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) 38
39#ifdef LEADER_NO_TIMEOUT
40# define LEADER_DICTIONARY() if (leading && leader_sequence_size > 0 && timer_elapsed(leader_time) > LEADER_TIMEOUT)
41#else
42# define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT)
43#endif
44
45#endif
diff --git a/quantum/process_keycode/process_rgb.c b/quantum/process_keycode/process_rgb.c
index 5dd8e7809..167c0c03c 100644
--- a/quantum/process_keycode/process_rgb.c
+++ b/quantum/process_keycode/process_rgb.c
@@ -207,6 +207,11 @@ bool process_rgb(const uint16_t keycode, const keyrecord_t *record) {
207 rgblight_mode(RGBLIGHT_MODE_RGB_TEST); 207 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
208#endif 208#endif
209 return false; 209 return false;
210 case RGB_MODE_TWINKLE:
211#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_TWINKLE)
212 handleKeycodeRGBMode(RGBLIGHT_MODE_TWINKLE, RGBLIGHT_MODE_TWINKLE_end);
213#endif
214 return false;
210 } 215 }
211 } 216 }
212 217
diff --git a/quantum/quantum.c b/quantum/quantum.c
index b40b40544..8ccdb774b 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "quantum.h" 17#include "quantum.h"
18#include "magic.h"
18 19
19#ifdef BLUETOOTH_ENABLE 20#ifdef BLUETOOTH_ENABLE
20# include "outputselect.h" 21# include "outputselect.h"
@@ -233,7 +234,7 @@ bool process_record_quantum(keyrecord_t *record) {
233#ifdef AUDIO_ENABLE 234#ifdef AUDIO_ENABLE
234 process_audio(keycode, record) && 235 process_audio(keycode, record) &&
235#endif 236#endif
236#ifdef BACKLIGHT_ENABLE 237#if defined(BACKLIGHT_ENABLE) || defined(LED_MATRIX_ENABLE)
237 process_backlight(keycode, record) && 238 process_backlight(keycode, record) &&
238#endif 239#endif
239#ifdef STENO_ENABLE 240#ifdef STENO_ENABLE
@@ -318,6 +319,17 @@ bool process_record_quantum(keyrecord_t *record) {
318 set_output(OUTPUT_BLUETOOTH); 319 set_output(OUTPUT_BLUETOOTH);
319 return false; 320 return false;
320#endif 321#endif
322#ifndef NO_ACTION_ONESHOT
323 case ONESHOT_TOGGLE:
324 oneshot_toggle();
325 break;
326 case ONESHOT_ENABLE:
327 oneshot_enable();
328 break;
329 case ONESHOT_DISABLE:
330 oneshot_disable();
331 break;
332#endif
321 } 333 }
322 } 334 }
323 335
@@ -341,26 +353,20 @@ layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_
341void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); } 353void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); }
342 354
343void matrix_init_quantum() { 355void matrix_init_quantum() {
344#ifdef BOOTMAGIC_LITE 356 magic();
345 bootmagic_lite();
346#endif
347 if (!eeconfig_is_enabled()) {
348 eeconfig_init();
349 }
350#if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN) 357#if defined(LED_NUM_LOCK_PIN) || defined(LED_CAPS_LOCK_PIN) || defined(LED_SCROLL_LOCK_PIN) || defined(LED_COMPOSE_PIN) || defined(LED_KANA_PIN)
351 // TODO: remove calls to led_init_ports from keyboards and remove ifdef 358 // TODO: remove calls to led_init_ports from keyboards and remove ifdef
352 led_init_ports(); 359 led_init_ports();
353#endif 360#endif
354#ifdef BACKLIGHT_ENABLE 361#ifdef BACKLIGHT_ENABLE
355# ifdef LED_MATRIX_ENABLE
356 led_matrix_init();
357# else
358 backlight_init_ports(); 362 backlight_init_ports();
359# endif
360#endif 363#endif
361#ifdef AUDIO_ENABLE 364#ifdef AUDIO_ENABLE
362 audio_init(); 365 audio_init();
363#endif 366#endif
367#ifdef LED_MATRIX_ENABLE
368 led_matrix_init();
369#endif
364#ifdef RGB_MATRIX_ENABLE 370#ifdef RGB_MATRIX_ENABLE
365 rgb_matrix_init(); 371 rgb_matrix_init();
366#endif 372#endif
diff --git a/quantum/quantum.h b/quantum/quantum.h
index e24a4c43a..fe6bf310a 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -30,11 +30,11 @@
30#include "keymap.h" 30#include "keymap.h"
31 31
32#ifdef BACKLIGHT_ENABLE 32#ifdef BACKLIGHT_ENABLE
33# ifdef LED_MATRIX_ENABLE 33# include "backlight.h"
34# include "led_matrix.h" 34#endif
35# else 35
36# include "backlight.h" 36#ifdef LED_MATRIX_ENABLE
37# endif 37# include "led_matrix.h"
38#endif 38#endif
39 39
40#if defined(RGBLIGHT_ENABLE) 40#if defined(RGBLIGHT_ENABLE)
@@ -52,6 +52,7 @@
52#include "action_layer.h" 52#include "action_layer.h"
53#include "eeconfig.h" 53#include "eeconfig.h"
54#include "bootloader.h" 54#include "bootloader.h"
55#include "bootmagic.h"
55#include "timer.h" 56#include "timer.h"
56#include "sync_timer.h" 57#include "sync_timer.h"
57#include "config_common.h" 58#include "config_common.h"
@@ -97,7 +98,7 @@ extern layer_state_t layer_state;
97# include "process_music.h" 98# include "process_music.h"
98#endif 99#endif
99 100
100#ifdef BACKLIGHT_ENABLE 101#if defined(BACKLIGHT_ENABLE) || defined(LED_MATRIX_ENABLE)
101# include "process_backlight.h" 102# include "process_backlight.h"
102#endif 103#endif
103 104
@@ -199,39 +200,6 @@ extern layer_state_t layer_state;
199# include "usbpd.h" 200# include "usbpd.h"
200#endif 201#endif
201 202
202// Function substitutions to ease GPIO manipulation
203#if defined(__AVR__)
204
205/* The AVR series GPIOs have a one clock read delay for changes in the digital input signal.
206 * But here's more margin to make it two clocks. */
207# if !defined(GPIO_INPUT_PIN_DELAY)
208# define GPIO_INPUT_PIN_DELAY 2
209# endif
210# define waitInputPinDelay() wait_cpuclock(GPIO_INPUT_PIN_DELAY)
211
212#elif defined(__ARMEL__) || defined(__ARMEB__)
213
214/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus
215 * to which the GPIO is connected.
216 * The connected buses differ depending on the various series of MCUs.
217 * And since the instruction execution clock of the CPU and the bus clock of GPIO are different,
218 * there is a delay of several clocks to read the change of the input signal.
219 *
220 * Define this delay with the GPIO_INPUT_PIN_DELAY macro.
221 * If the GPIO_INPUT_PIN_DELAY macro is not defined, the following default values will be used.
222 * (A fairly large value of 0.25 microseconds is set.)
223 */
224# if !defined(GPIO_INPUT_PIN_DELAY)
225# if defined(STM32_SYSCLK)
226# define GPIO_INPUT_PIN_DELAY (STM32_SYSCLK / 1000000L / 4)
227# elif defined(KINETIS_SYSCLK_FREQUENCY)
228# define GPIO_INPUT_PIN_DELAY (KINETIS_SYSCLK_FREQUENCY / 1000000L / 4)
229# endif
230# endif
231# define waitInputPinDelay() wait_cpuclock(GPIO_INPUT_PIN_DELAY)
232
233#endif
234
235// For tri-layer 203// For tri-layer
236void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); 204void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
237layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3); 205layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);
@@ -256,15 +224,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record);
256void post_process_record_kb(uint16_t keycode, keyrecord_t *record); 224void post_process_record_kb(uint16_t keycode, keyrecord_t *record);
257void post_process_record_user(uint16_t keycode, keyrecord_t *record); 225void post_process_record_user(uint16_t keycode, keyrecord_t *record);
258 226
259#ifndef BOOTMAGIC_LITE_COLUMN
260# define BOOTMAGIC_LITE_COLUMN 0
261#endif
262#ifndef BOOTMAGIC_LITE_ROW
263# define BOOTMAGIC_LITE_ROW 0
264#endif
265
266void bootmagic_lite(void);
267
268void reset_keyboard(void); 227void reset_keyboard(void);
269 228
270void startup_user(void); 229void startup_user(void);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index e49f8dcda..26021598a 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -16,19 +16,7 @@
16 16
17#pragma once 17#pragma once
18 18
19#if defined(SEQUENCER_ENABLE) 19#include "sequencer.h"
20# include "sequencer.h"
21#endif
22
23#ifndef MIDI_ENABLE_STRICT
24# define MIDI_ENABLE_STRICT 0
25#endif
26
27#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
28# ifndef MIDI_TONE_KEYCODE_OCTAVES
29# define MIDI_TONE_KEYCODE_OCTAVES 3
30# endif
31#endif
32 20
33// Fillers to make layering more clear 21// Fillers to make layering more clear
34#define _______ KC_TRNS 22#define _______ KC_TRNS
@@ -67,6 +55,8 @@ enum quantum_keycodes {
67 QK_ONE_SHOT_LAYER_MAX = 0x54FF, 55 QK_ONE_SHOT_LAYER_MAX = 0x54FF,
68 QK_ONE_SHOT_MOD = 0x5500, 56 QK_ONE_SHOT_MOD = 0x5500,
69 QK_ONE_SHOT_MOD_MAX = 0x55FF, 57 QK_ONE_SHOT_MOD_MAX = 0x55FF,
58 QK_SWAP_HANDS = 0x5600,
59 QK_SWAP_HANDS_MAX = 0x56FF,
70 QK_TAP_DANCE = 0x5700, 60 QK_TAP_DANCE = 0x5700,
71 QK_TAP_DANCE_MAX = 0x57FF, 61 QK_TAP_DANCE_MAX = 0x57FF,
72 QK_LAYER_TAP_TOGGLE = 0x5800, 62 QK_LAYER_TAP_TOGGLE = 0x5800,
@@ -77,507 +67,458 @@ enum quantum_keycodes {
77 QK_STENO_BOLT = 0x5A30, 67 QK_STENO_BOLT = 0x5A30,
78 QK_STENO_GEMINI = 0x5A31, 68 QK_STENO_GEMINI = 0x5A31,
79 QK_STENO_MAX = 0x5A3F, 69 QK_STENO_MAX = 0x5A3F,
80 QK_SWAP_HANDS = 0x5B00, 70 // 0x5C00 - 0x5FFF are reserved, see below
81 QK_SWAP_HANDS_MAX = 0x5BFF, 71 QK_MOD_TAP = 0x6000,
82 QK_MOD_TAP = 0x6000, 72 QK_MOD_TAP_MAX = 0x7FFF,
83 QK_MOD_TAP_MAX = 0x7FFF, 73 QK_UNICODE = 0x8000,
84 QK_UNICODE = 0x8000, 74 QK_UNICODE_MAX = 0xFFFF,
85 QK_UNICODE_MAX = 0xFFFF, 75 QK_UNICODEMAP = 0x8000,
86 QK_UNICODEMAP = 0x8000, 76 QK_UNICODEMAP_MAX = 0xBFFF,
87 QK_UNICODEMAP_MAX = 0xBFFF, 77 QK_UNICODEMAP_PAIR = 0xC000,
88 QK_UNICODEMAP_PAIR = 0xC000, 78 QK_UNICODEMAP_PAIR_MAX = 0xFFFF,
89 QK_UNICODEMAP_PAIR_MAX = 0xFFFF,
90 79
91 // Loose keycodes - to be used directly 80 // Loose keycodes - to be used directly
92 RESET = 0x5C00, 81 RESET = 0x5C00,
93 DEBUG, 82 DEBUG, // 5C01
94 MAGIC_SWAP_CONTROL_CAPSLOCK, 83
95 MAGIC_CAPSLOCK_TO_CONTROL, 84 // Magic
96 MAGIC_SWAP_LALT_LGUI, 85 MAGIC_SWAP_CONTROL_CAPSLOCK, // 5C02
97 MAGIC_SWAP_RALT_RGUI, 86 MAGIC_CAPSLOCK_TO_CONTROL, // 5C03
98 MAGIC_NO_GUI, 87 MAGIC_SWAP_LALT_LGUI, // 5C04
99 MAGIC_SWAP_GRAVE_ESC, 88 MAGIC_SWAP_RALT_RGUI, // 5C05
100 MAGIC_SWAP_BACKSLASH_BACKSPACE, 89 MAGIC_NO_GUI, // 5C06
101 MAGIC_HOST_NKRO, 90 MAGIC_SWAP_GRAVE_ESC, // 5C07
102 MAGIC_SWAP_ALT_GUI, 91 MAGIC_SWAP_BACKSLASH_BACKSPACE, // 5C08
103 MAGIC_UNSWAP_CONTROL_CAPSLOCK, 92 MAGIC_HOST_NKRO, // 5C09
104 MAGIC_UNCAPSLOCK_TO_CONTROL, 93 MAGIC_SWAP_ALT_GUI, // 5C0A
105 MAGIC_UNSWAP_LALT_LGUI, 94 MAGIC_UNSWAP_CONTROL_CAPSLOCK, // 5C0B
106 MAGIC_UNSWAP_RALT_RGUI, 95 MAGIC_UNCAPSLOCK_TO_CONTROL, // 5C0C
107 MAGIC_UNNO_GUI, 96 MAGIC_UNSWAP_LALT_LGUI, // 5C0D
108 MAGIC_UNSWAP_GRAVE_ESC, 97 MAGIC_UNSWAP_RALT_RGUI, // 5C0E
109 MAGIC_UNSWAP_BACKSLASH_BACKSPACE, 98 MAGIC_UNNO_GUI, // 5C0F
110 MAGIC_UNHOST_NKRO, 99 MAGIC_UNSWAP_GRAVE_ESC, // 5C10
111 MAGIC_UNSWAP_ALT_GUI, 100 MAGIC_UNSWAP_BACKSLASH_BACKSPACE, // 5C11
112 MAGIC_TOGGLE_NKRO, 101 MAGIC_UNHOST_NKRO, // 5C12
113 MAGIC_TOGGLE_ALT_GUI, 102 MAGIC_UNSWAP_ALT_GUI, // 5C13
114 GRAVE_ESC, 103 MAGIC_TOGGLE_NKRO, // 5C14
115 104 MAGIC_TOGGLE_ALT_GUI, // 5C15
116// Leader key 105
117#ifdef LEADER_ENABLE 106 // Grave Escape
118 KC_LEAD, 107 GRAVE_ESC, // 5C16
119#endif 108
120 109 // Auto Shift
121// Auto Shift setup 110 KC_ASUP, // 5C17
122#ifndef AUTO_SHIFT_NO_SETUP 111 KC_ASDN, // 5C18
123 KC_ASUP, 112 KC_ASRP, // 5C19
124 KC_ASDN, 113 KC_ASTG, // 5C1A
125 KC_ASRP, 114 KC_ASON, // 5C1B
126#endif 115 KC_ASOFF, // 5C1C
127 KC_ASTG, 116
128 KC_ASON, 117 // Audio
129 KC_ASOFF, 118 AU_ON, // 5C1D
130 119 AU_OFF, // 5C1E
131 // Audio on/off/toggle 120 AU_TOG, // 5C1F
132 AU_ON, 121
133 AU_OFF, 122 // Audio Clicky
134 AU_TOG, 123 CLICKY_TOGGLE, // 5C20
135 124 CLICKY_ENABLE, // 5C21
136 // Faux clicky as part of main audio feature 125 CLICKY_DISABLE, // 5C22
137 CLICKY_TOGGLE, 126 CLICKY_UP, // 5C23
138 CLICKY_ENABLE, 127 CLICKY_DOWN, // 5C24
139 CLICKY_DISABLE, 128 CLICKY_RESET, // 5C25
140 CLICKY_UP, 129
141 CLICKY_DOWN, 130 // Music mode
142 CLICKY_RESET, 131 MU_ON, // 5C26
143 132 MU_OFF, // 5C27
144 // Music mode on/off/toggle 133 MU_TOG, // 5C28
145 MU_ON, 134 MU_MOD, // 5C29
146 MU_OFF, 135 MUV_IN, // 5C2A
147 MU_TOG, 136 MUV_DE, // 5C2B
148 137
149 // Music mode cycle 138 // MIDI
150 MU_MOD, 139 MI_ON, // 5C2C
151 140 MI_OFF, // 5C2D
152 // Music voice iterate 141 MI_TOG, // 5C2E
153 MUV_IN, 142
154 MUV_DE, 143 MI_C, // 5C2F
155 144 MI_Cs, // 5C30
156// Midi
157#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
158 MI_ON,
159 MI_OFF,
160 MI_TOG,
161#endif
162
163#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
164 MIDI_TONE_MIN,
165
166# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 0
167 MI_C = MIDI_TONE_MIN,
168 MI_Cs,
169 MI_Db = MI_Cs, 145 MI_Db = MI_Cs,
170 MI_D, 146 MI_D, // 5C31
171 MI_Ds, 147 MI_Ds, // 5C32
172 MI_Eb = MI_Ds, 148 MI_Eb = MI_Ds,
173 MI_E, 149 MI_E, // 5C33
174 MI_F, 150 MI_F, // 5C34
175 MI_Fs, 151 MI_Fs, // 5C35
176 MI_Gb = MI_Fs, 152 MI_Gb = MI_Fs,
177 MI_G, 153 MI_G, // 5C36
178 MI_Gs, 154 MI_Gs, // 5C37
179 MI_Ab = MI_Gs, 155 MI_Ab = MI_Gs,
180 MI_A, 156 MI_A, // 5C38
181 MI_As, 157 MI_As, // 5C39
182 MI_Bb = MI_As, 158 MI_Bb = MI_As,
183 MI_B, 159 MI_B, // 5C3A
184# endif
185 160
186# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 1 161 MI_C_1, // 5C3B
187 MI_C_1, 162 MI_Cs_1, // 5C3C
188 MI_Cs_1,
189 MI_Db_1 = MI_Cs_1, 163 MI_Db_1 = MI_Cs_1,
190 MI_D_1, 164 MI_D_1, // 5C3D
191 MI_Ds_1, 165 MI_Ds_1, // 5C3E
192 MI_Eb_1 = MI_Ds_1, 166 MI_Eb_1 = MI_Ds_1,
193 MI_E_1, 167 MI_E_1, // 5C3F
194 MI_F_1, 168 MI_F_1, // 5C40
195 MI_Fs_1, 169 MI_Fs_1, // 5C41
196 MI_Gb_1 = MI_Fs_1, 170 MI_Gb_1 = MI_Fs_1,
197 MI_G_1, 171 MI_G_1, // 5C42
198 MI_Gs_1, 172 MI_Gs_1, // 5C43
199 MI_Ab_1 = MI_Gs_1, 173 MI_Ab_1 = MI_Gs_1,
200 MI_A_1, 174 MI_A_1, // 5C44
201 MI_As_1, 175 MI_As_1, // 5C45
202 MI_Bb_1 = MI_As_1, 176 MI_Bb_1 = MI_As_1,
203 MI_B_1, 177 MI_B_1, // 5C46
204# endif
205 178
206# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 2 179 MI_C_2, // 5C47
207 MI_C_2, 180 MI_Cs_2, // 5C48
208 MI_Cs_2,
209 MI_Db_2 = MI_Cs_2, 181 MI_Db_2 = MI_Cs_2,
210 MI_D_2, 182 MI_D_2, // 5C49
211 MI_Ds_2, 183 MI_Ds_2, // 5C4A
212 MI_Eb_2 = MI_Ds_2, 184 MI_Eb_2 = MI_Ds_2,
213 MI_E_2, 185 MI_E_2, // 5C4B
214 MI_F_2, 186 MI_F_2, // 5C4C
215 MI_Fs_2, 187 MI_Fs_2, // 5C4D
216 MI_Gb_2 = MI_Fs_2, 188 MI_Gb_2 = MI_Fs_2,
217 MI_G_2, 189 MI_G_2, // 5C4E
218 MI_Gs_2, 190 MI_Gs_2, // 5C4F
219 MI_Ab_2 = MI_Gs_2, 191 MI_Ab_2 = MI_Gs_2,
220 MI_A_2, 192 MI_A_2, // 5C50
221 MI_As_2, 193 MI_As_2, // 5C51
222 MI_Bb_2 = MI_As_2, 194 MI_Bb_2 = MI_As_2,
223 MI_B_2, 195 MI_B_2, // 5C52
224# endif
225 196
226# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 3 197 MI_C_3, // 5C53
227 MI_C_3, 198 MI_Cs_3, // 5C54
228 MI_Cs_3,
229 MI_Db_3 = MI_Cs_3, 199 MI_Db_3 = MI_Cs_3,
230 MI_D_3, 200 MI_D_3, // 5C55
231 MI_Ds_3, 201 MI_Ds_3, // 5C56
232 MI_Eb_3 = MI_Ds_3, 202 MI_Eb_3 = MI_Ds_3,
233 MI_E_3, 203 MI_E_3, // 5C57
234 MI_F_3, 204 MI_F_3, // 5C58
235 MI_Fs_3, 205 MI_Fs_3, // 5C59
236 MI_Gb_3 = MI_Fs_3, 206 MI_Gb_3 = MI_Fs_3,
237 MI_G_3, 207 MI_G_3, // 5C5A
238 MI_Gs_3, 208 MI_Gs_3, // 5C5B
239 MI_Ab_3 = MI_Gs_3, 209 MI_Ab_3 = MI_Gs_3,
240 MI_A_3, 210 MI_A_3, // 5C5C
241 MI_As_3, 211 MI_As_3, // 5C5D
242 MI_Bb_3 = MI_As_3, 212 MI_Bb_3 = MI_As_3,
243 MI_B_3, 213 MI_B_3, // 5C5E
244# endif
245 214
246# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 4 215 MI_C_4, // 5C5F
247 MI_C_4, 216 MI_Cs_4, // 5C60
248 MI_Cs_4,
249 MI_Db_4 = MI_Cs_4, 217 MI_Db_4 = MI_Cs_4,
250 MI_D_4, 218 MI_D_4, // 5C61
251 MI_Ds_4, 219 MI_Ds_4, // 5C62
252 MI_Eb_4 = MI_Ds_4, 220 MI_Eb_4 = MI_Ds_4,
253 MI_E_4, 221 MI_E_4, // 5C63
254 MI_F_4, 222 MI_F_4, // 5C64
255 MI_Fs_4, 223 MI_Fs_4, // 5C65
256 MI_Gb_4 = MI_Fs_4, 224 MI_Gb_4 = MI_Fs_4,
257 MI_G_4, 225 MI_G_4, // 5C66
258 MI_Gs_4, 226 MI_Gs_4, // 5C67
259 MI_Ab_4 = MI_Gs_4, 227 MI_Ab_4 = MI_Gs_4,
260 MI_A_4, 228 MI_A_4, // 5C68
261 MI_As_4, 229 MI_As_4, // 5C69
262 MI_Bb_4 = MI_As_4, 230 MI_Bb_4 = MI_As_4,
263 MI_B_4, 231 MI_B_4, // 5C6A
264# endif
265 232
266# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5 233 MI_C_5, // 5C6B
267 MI_C_5, 234 MI_Cs_5, // 5C6C
268 MI_Cs_5,
269 MI_Db_5 = MI_Cs_5, 235 MI_Db_5 = MI_Cs_5,
270 MI_D_5, 236 MI_D_5, // 5C6D
271 MI_Ds_5, 237 MI_Ds_5, // 5C6E
272 MI_Eb_5 = MI_Ds_5, 238 MI_Eb_5 = MI_Ds_5,
273 MI_E_5, 239 MI_E_5, // 5C6F
274 MI_F_5, 240 MI_F_5, // 5C70
275 MI_Fs_5, 241 MI_Fs_5, // 5C71
276 MI_Gb_5 = MI_Fs_5, 242 MI_Gb_5 = MI_Fs_5,
277 MI_G_5, 243 MI_G_5, // 5C72
278 MI_Gs_5, 244 MI_Gs_5, // 5C73
279 MI_Ab_5 = MI_Gs_5, 245 MI_Ab_5 = MI_Gs_5,
280 MI_A_5, 246 MI_A_5, // 5C74
281 MI_As_5, 247 MI_As_5, // 5C75
282 MI_Bb_5 = MI_As_5, 248 MI_Bb_5 = MI_As_5,
283 MI_B_5, 249 MI_B_5, // 5C76
284# endif 250
285 251 MI_OCT_N2, // 5C77
286# if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5 252 MI_OCT_N1, // 5C78
287 MIDI_TONE_MAX = MI_B_5, 253 MI_OCT_0, // 5C79
288# elif MIDI_TONE_KEYCODE_OCTAVES > 4 254 MI_OCT_1, // 5C7A
289 MIDI_TONE_MAX = MI_B_4, 255 MI_OCT_2, // 5C7B
290# elif MIDI_TONE_KEYCODE_OCTAVES > 3 256 MI_OCT_3, // 5C7C
291 MIDI_TONE_MAX = MI_B_3, 257 MI_OCT_4, // 5C7D
292# elif MIDI_TONE_KEYCODE_OCTAVES > 2 258 MI_OCT_5, // 5C7E
293 MIDI_TONE_MAX = MI_B_2, 259 MI_OCT_6, // 5C7F
294# elif MIDI_TONE_KEYCODE_OCTAVES > 1 260 MI_OCT_7, // 5C80
295 MIDI_TONE_MAX = MI_B_1, 261 MI_OCTD, // 5C81
296# elif MIDI_TONE_KEYCODE_OCTAVES > 0 262 MI_OCTU, // 5C82
297 MIDI_TONE_MAX = MI_B, 263
298# endif 264 MI_TRNS_N6, // 5C83
299 265 MI_TRNS_N5, // 5C84
300 MIDI_OCTAVE_MIN, 266 MI_TRNS_N4, // 5C85
301 MI_OCT_N2 = MIDI_OCTAVE_MIN, 267 MI_TRNS_N3, // 5C86
302 MI_OCT_N1, 268 MI_TRNS_N2, // 5C87
303 MI_OCT_0, 269 MI_TRNS_N1, // 5C88
304 MI_OCT_1, 270 MI_TRNS_0, // 5C89
305 MI_OCT_2, 271 MI_TRNS_1, // 5C8A
306 MI_OCT_3, 272 MI_TRNS_2, // 5C8B
307 MI_OCT_4, 273 MI_TRNS_3, // 5C8C
308 MI_OCT_5, 274 MI_TRNS_4, // 5C8D
309 MI_OCT_6, 275 MI_TRNS_5, // 5C8E
310 MI_OCT_7, 276 MI_TRNS_6, // 5C8F
311 MIDI_OCTAVE_MAX = MI_OCT_7, 277 MI_TRNSD, // 5C90
312 MI_OCTD, // octave down 278 MI_TRNSU, // 5C91
313 MI_OCTU, // octave up 279
314 280 MI_VEL_0, // 5C92
315 MIDI_TRANSPOSE_MIN, 281#ifdef VIA_ENABLE
316 MI_TRNS_N6 = MIDI_TRANSPOSE_MIN, 282 MI_VEL_1 = MI_VEL_0,
317 MI_TRNS_N5, 283#else
318 MI_TRNS_N4, 284 MI_VEL_1, // 5C93
319 MI_TRNS_N3,
320 MI_TRNS_N2,
321 MI_TRNS_N1,
322 MI_TRNS_0,
323 MI_TRNS_1,
324 MI_TRNS_2,
325 MI_TRNS_3,
326 MI_TRNS_4,
327 MI_TRNS_5,
328 MI_TRNS_6,
329 MIDI_TRANSPOSE_MAX = MI_TRNS_6,
330 MI_TRNSD, // transpose down
331 MI_TRNSU, // transpose up
332
333 MIDI_VELOCITY_MIN,
334 MI_VEL_0 = MIDI_VELOCITY_MIN,
335# ifdef VIA_ENABLE
336 MI_VEL_1 = MIDI_VELOCITY_MIN,
337# else
338 MI_VEL_1,
339# endif
340 MI_VEL_2,
341 MI_VEL_3,
342 MI_VEL_4,
343 MI_VEL_5,
344 MI_VEL_6,
345 MI_VEL_7,
346 MI_VEL_8,
347 MI_VEL_9,
348 MI_VEL_10,
349 MIDI_VELOCITY_MAX = MI_VEL_10,
350 MI_VELD, // velocity down
351 MI_VELU, // velocity up
352
353 MIDI_CHANNEL_MIN,
354 MI_CH1 = MIDI_CHANNEL_MIN,
355 MI_CH2,
356 MI_CH3,
357 MI_CH4,
358 MI_CH5,
359 MI_CH6,
360 MI_CH7,
361 MI_CH8,
362 MI_CH9,
363 MI_CH10,
364 MI_CH11,
365 MI_CH12,
366 MI_CH13,
367 MI_CH14,
368 MI_CH15,
369 MI_CH16,
370 MIDI_CHANNEL_MAX = MI_CH16,
371 MI_CHD, // previous channel
372 MI_CHU, // next channel
373
374 MI_ALLOFF, // all notes off
375
376 MI_SUS, // sustain
377 MI_PORT, // portamento
378 MI_SOST, // sostenuto
379 MI_SOFT, // soft pedal
380 MI_LEG, // legato
381
382 MI_MOD, // modulation
383 MI_MODSD, // decrease modulation speed
384 MI_MODSU, // increase modulation speed
385
386 MI_BENDD, // Bend down
387 MI_BENDU, // Bend up
388#endif // MIDI_ADVANCED
389
390 // Backlight functionality
391 BL_ON,
392 BL_OFF,
393 BL_DEC,
394 BL_INC,
395 BL_TOGG,
396 BL_STEP,
397 BL_BRTG,
398
399 // RGB functionality
400 RGB_TOG,
401 RGB_MODE_FORWARD,
402 RGB_MODE_REVERSE,
403 RGB_HUI,
404 RGB_HUD,
405 RGB_SAI,
406 RGB_SAD,
407 RGB_VAI,
408 RGB_VAD,
409 RGB_SPI,
410 RGB_SPD,
411 RGB_MODE_PLAIN,
412 RGB_MODE_BREATHE,
413 RGB_MODE_RAINBOW,
414 RGB_MODE_SWIRL,
415 RGB_MODE_SNAKE,
416 RGB_MODE_KNIGHT,
417 RGB_MODE_XMAS,
418 RGB_MODE_GRADIENT,
419 RGB_MODE_RGBTEST,
420
421 // Momentum matching toggle
422 VLK_TOG,
423
424 // Left shift, open paren
425 KC_LSPO,
426
427 // Right shift, close paren
428 KC_RSPC,
429
430 // Shift, Enter
431 KC_SFTENT,
432
433 // Printing
434 PRINT_ON,
435 PRINT_OFF,
436
437 // output selection
438 OUT_AUTO,
439 OUT_USB,
440#ifdef BLUETOOTH_ENABLE
441 OUT_BT,
442#endif
443
444#ifdef KEY_LOCK_ENABLE
445 KC_LOCK,
446#endif 285#endif
447 286 MI_VEL_2, // 5C94
448#ifdef TERMINAL_ENABLE 287 MI_VEL_3, // 5C95
449 TERM_ON, 288 MI_VEL_4, // 5C96
450 TERM_OFF, 289 MI_VEL_5, // 5C97
451#endif 290 MI_VEL_6, // 5C98
452 291 MI_VEL_7, // 5C99
453 EEPROM_RESET, 292 MI_VEL_8, // 5C9A
454 293 MI_VEL_9, // 5C9B
455 UNICODE_MODE_FORWARD, 294 MI_VEL_10, // 5C9C
456 UNICODE_MODE_REVERSE, 295 MI_VELD, // 5C9D
457 UNICODE_MODE_MAC, 296 MI_VELU, // 5C9E
458 UNICODE_MODE_LNX, 297
459 UNICODE_MODE_WIN, 298 MI_CH1, // 5C9F
460 UNICODE_MODE_BSD, 299 MI_CH2, // 5CA0
461 UNICODE_MODE_WINC, 300 MI_CH3, // 5CA1
462 301 MI_CH4, // 5CA2
463 HPT_ON, 302 MI_CH5, // 5CA3
464 HPT_OFF, 303 MI_CH6, // 5CA4
465 HPT_TOG, 304 MI_CH7, // 5CA5
466 HPT_RST, 305 MI_CH8, // 5CA6
467 HPT_FBK, 306 MI_CH9, // 5CA7
468 HPT_BUZ, 307 MI_CH10, // 5CA8
469 HPT_MODI, 308 MI_CH11, // 5CA9
470 HPT_MODD, 309 MI_CH12, // 5CAA
471 HPT_CONT, 310 MI_CH13, // 5CAB
472 HPT_CONI, 311 MI_CH14, // 5CAC
473 HPT_COND, 312 MI_CH15, // 5CAD
474 HPT_DWLI, 313 MI_CH16, // 5CAE
475 HPT_DWLD, 314 MI_CHD, // 5CAF
476 315 MI_CHU, // 5CB0
477 // Left control, open paren 316
478 KC_LCPO, 317 MI_ALLOFF, // 5CB1
479 318
480 // Right control, close paren 319 MI_SUS, // 5CB2
481 KC_RCPC, 320 MI_PORT, // 5CB3
482 321 MI_SOST, // 5CB4
483 // Left control, open paren 322 MI_SOFT, // 5CB5
484 KC_LAPO, 323 MI_LEG, // 5CB6
485 324
486 // Right control, close paren 325 MI_MOD, // 5CB7
487 KC_RAPC, 326 MI_MODSD, // 5CB8
488 327 MI_MODSU, // 5CB9
489 CMB_ON, 328
490 CMB_OFF, 329 MI_BENDD, // 5CBA
491 CMB_TOG, 330 MI_BENDU, // 5CBB
492 331
493 MAGIC_SWAP_LCTL_LGUI, 332 // Backlight
494 MAGIC_SWAP_RCTL_RGUI, 333 BL_ON, // 5CBC
495 MAGIC_UNSWAP_LCTL_LGUI, 334 BL_OFF, // 5CBD
496 MAGIC_UNSWAP_RCTL_RGUI, 335 BL_DEC, // 5CBE
497 MAGIC_SWAP_CTL_GUI, 336 BL_INC, // 5CBF
498 MAGIC_UNSWAP_CTL_GUI, 337 BL_TOGG, // 5CC0
499 MAGIC_TOGGLE_CTL_GUI, 338 BL_STEP, // 5CC1
500 MAGIC_EE_HANDS_LEFT, 339 BL_BRTG, // 5CC2
501 MAGIC_EE_HANDS_RIGHT, 340
341 // RGB underglow/matrix
342 RGB_TOG, // 5CC3
343 RGB_MODE_FORWARD, // 5CC4
344 RGB_MODE_REVERSE, // 5CC5
345 RGB_HUI, // 5CC6
346 RGB_HUD, // 5CC7
347 RGB_SAI, // 5CC8
348 RGB_SAD, // 5CC9
349 RGB_VAI, // 5CCA
350 RGB_VAD, // 5CCB
351 RGB_SPI, // 5CCC
352 RGB_SPD, // 5CCD
353 RGB_MODE_PLAIN, // 5CCE
354 RGB_MODE_BREATHE, // 5CCF
355 RGB_MODE_RAINBOW, // 5CD0
356 RGB_MODE_SWIRL, // 5CD1
357 RGB_MODE_SNAKE, // 5CD2
358 RGB_MODE_KNIGHT, // 5CD3
359 RGB_MODE_XMAS, // 5CD4
360 RGB_MODE_GRADIENT, // 5CD5
361 RGB_MODE_RGBTEST, // 5CD6
362
363 // Velocikey
364 VLK_TOG, // 5CD7
365
366 // Space Cadet
367 KC_LSPO, // 5CD8
368 KC_RSPC, // 5CD9
369 KC_SFTENT, // 5CDA
370
371 // Thermal Printer
372 PRINT_ON, // 5CDB
373 PRINT_OFF, // 5CDC
374
375 // Bluetooth: output selection
376 OUT_AUTO, // 5CDD
377 OUT_USB, // 5CDE
378
379 // Clear EEPROM
380 EEPROM_RESET, // 5CDF
381
382 // Unicode
383 UNICODE_MODE_FORWARD, // 5CE0
384 UNICODE_MODE_REVERSE, // 5CE1
385 UNICODE_MODE_MAC, // 5CE2
386 UNICODE_MODE_LNX, // 5CE3
387 UNICODE_MODE_WIN, // 5CE4
388 UNICODE_MODE_BSD, // 5CE5
389 UNICODE_MODE_WINC, // 5CE6
390
391 // Haptic
392 HPT_ON, // 5CE7
393 HPT_OFF, // 5CE8
394 HPT_TOG, // 5CE9
395 HPT_RST, // 5CEA
396 HPT_FBK, // 5CEB
397 HPT_BUZ, // 5CEC
398 HPT_MODI, // 5CED
399 HPT_MODD, // 5CEE
400 HPT_CONT, // 5CEF
401 HPT_CONI, // 5CF0
402 HPT_COND, // 5CF1
403 HPT_DWLI, // 5CF2
404 HPT_DWLD, // 5CF3
405
406 // Space Cadet (continued)
407 KC_LCPO, // 5CF4
408 KC_RCPC, // 5CF5
409 KC_LAPO, // 5CF6
410 KC_RAPC, // 5CF7
411
412 // Combos
413 CMB_ON, // 5CF8
414 CMB_OFF, // 5CF9
415 CMB_TOG, // 5CFA
416
417 // Magic (continued)
418 MAGIC_SWAP_LCTL_LGUI, // 5CFB
419 MAGIC_SWAP_RCTL_RGUI, // 5CFC
420 MAGIC_UNSWAP_LCTL_LGUI, // 5CFD
421 MAGIC_UNSWAP_RCTL_RGUI, // 5CFE
422 MAGIC_SWAP_CTL_GUI, // 5CFF
423 MAGIC_UNSWAP_CTL_GUI, // 5D00
424 MAGIC_TOGGLE_CTL_GUI, // 5D01
425 MAGIC_EE_HANDS_LEFT, // 5D02
426 MAGIC_EE_HANDS_RIGHT, // 5D03
502 427
503 // Dynamic Macros 428 // Dynamic Macros
504 DYN_REC_START1, 429 DYN_REC_START1, // 5D04
505 DYN_REC_START2, 430 DYN_REC_START2, // 5D05
506 DYN_REC_STOP, 431 DYN_REC_STOP, // 5D06
507 DYN_MACRO_PLAY1, 432 DYN_MACRO_PLAY1, // 5D07
508 DYN_MACRO_PLAY2, 433 DYN_MACRO_PLAY2, // 5D08
509 434
510 JS_BUTTON0, 435 // Joystick
511 JS_BUTTON_MIN = JS_BUTTON0, 436 JS_BUTTON0, // 5D09
512 JS_BUTTON1, 437 JS_BUTTON1, // 5D0A
513 JS_BUTTON2, 438 JS_BUTTON2, // 5D0B
514 JS_BUTTON3, 439 JS_BUTTON3, // 5D0C
515 JS_BUTTON4, 440 JS_BUTTON4, // 5D0D
516 JS_BUTTON5, 441 JS_BUTTON5, // 5D0E
517 JS_BUTTON6, 442 JS_BUTTON6, // 5D0F
518 JS_BUTTON7, 443 JS_BUTTON7, // 5D10
519 JS_BUTTON8, 444 JS_BUTTON8, // 5D11
520 JS_BUTTON9, 445 JS_BUTTON9, // 5D12
521 JS_BUTTON10, 446 JS_BUTTON10, // 5D13
522 JS_BUTTON11, 447 JS_BUTTON11, // 5D14
523 JS_BUTTON12, 448 JS_BUTTON12, // 5D15
524 JS_BUTTON13, 449 JS_BUTTON13, // 5D16
525 JS_BUTTON14, 450 JS_BUTTON14, // 5D17
526 JS_BUTTON15, 451 JS_BUTTON15, // 5D18
527 JS_BUTTON16, 452 JS_BUTTON16, // 5D19
528 JS_BUTTON17, 453 JS_BUTTON17, // 5D1A
529 JS_BUTTON18, 454 JS_BUTTON18, // 5D1B
530 JS_BUTTON19, 455 JS_BUTTON19, // 5D1C
531 JS_BUTTON20, 456 JS_BUTTON20, // 5D1D
532 JS_BUTTON21, 457 JS_BUTTON21, // 5D1E
533 JS_BUTTON22, 458 JS_BUTTON22, // 5D1F
534 JS_BUTTON23, 459 JS_BUTTON23, // 5D20
535 JS_BUTTON24, 460 JS_BUTTON24, // 5D21
536 JS_BUTTON25, 461 JS_BUTTON25, // 5D22
537 JS_BUTTON26, 462 JS_BUTTON26, // 5D23
538 JS_BUTTON27, 463 JS_BUTTON27, // 5D24
539 JS_BUTTON28, 464 JS_BUTTON28, // 5D25
540 JS_BUTTON29, 465 JS_BUTTON29, // 5D26
541 JS_BUTTON30, 466 JS_BUTTON30, // 5D27
542 JS_BUTTON31, 467 JS_BUTTON31, // 5D28
543 JS_BUTTON_MAX = JS_BUTTON31, 468
544 469 // Leader Key
545#if defined(SEQUENCER_ENABLE) 470 KC_LEAD, // 5D29
546 SQ_ON, 471
547 SQ_OFF, 472 // Bluetooth: output selection (continued)
548 SQ_TOG, 473 OUT_BT, // 5D2A
549 474
550 SQ_TMPD, // Decrease tempo 475 // Lock Key
551 SQ_TMPU, // Increase tempo 476 KC_LOCK, // 5D2B
477
478 // Terminal
479 TERM_ON, // 5D2C
480 TERM_OFF, // 5D2D
481
482 // Sequencer
483 SQ_ON, // 5D2E
484 SQ_OFF, // 5D2F
485 SQ_TOG, // 5D30
486
487 SQ_TMPD, // 5D31
488 SQ_TMPU, // 5D32
489
490 SQ_RESD, // 5D33
491 SQ_RESU, // 5D34
492
493 SQ_SALL, // 5D35
494 SQ_SCLR, // 5D36
495
496 SEQUENCER_STEP_MIN, // 5D37
497 SEQUENCER_STEP_MAX = SEQUENCER_STEP_MIN + SEQUENCER_STEPS,
552 498
553 SEQUENCER_RESOLUTION_MIN, 499 SEQUENCER_RESOLUTION_MIN,
554 SEQUENCER_RESOLUTION_MAX = SEQUENCER_RESOLUTION_MIN + SEQUENCER_RESOLUTIONS, 500 SEQUENCER_RESOLUTION_MAX = SEQUENCER_RESOLUTION_MIN + SEQUENCER_RESOLUTIONS,
555 SQ_RESD, // Decrease resolution
556 SQ_RESU, // Increase resolution
557
558 SQ_SALL, // All steps on
559 SQ_SCLR, // All steps off
560 SEQUENCER_STEP_MIN,
561 SEQUENCER_STEP_MAX = SEQUENCER_STEP_MIN + SEQUENCER_STEPS,
562 501
563 SEQUENCER_TRACK_MIN, 502 SEQUENCER_TRACK_MIN,
564 SEQUENCER_TRACK_MAX = SEQUENCER_TRACK_MIN + SEQUENCER_TRACKS, 503 SEQUENCER_TRACK_MAX = SEQUENCER_TRACK_MIN + SEQUENCER_TRACKS,
565 504
566/** 505#define SQ_S(n) (n < SEQUENCER_STEPS ? SEQUENCER_STEP_MIN + n : KC_NO)
567 * Helpers to assign a keycode to a step, a resolution, or a track. 506#define SQ_R(n) (n < SEQUENCER_RESOLUTIONS ? SEQUENCER_RESOLUTION_MIN + n : KC_NO)
568 * Falls back to NOOP if n is out of range. 507#define SQ_T(n) (n < SEQUENCER_TRACKS ? SEQUENCER_TRACK_MIN + n : KC_NO)
569 */
570# define SQ_S(n) (n < SEQUENCER_STEPS ? SEQUENCER_STEP_MIN + n : XXXXXXX)
571# define SQ_R(n) (n < SEQUENCER_RESOLUTIONS ? SEQUENCER_RESOLUTION_MIN + n : XXXXXXX)
572# define SQ_T(n) (n < SEQUENCER_TRACKS ? SEQUENCER_TRACK_MIN + n : XXXXXXX)
573 508
574#endif 509 // One Shot
510 ONESHOT_ENABLE,
511 ONESHOT_DISABLE,
512 ONESHOT_TOGGLE,
513
514 // RGB underglow/matrix (continued)
515 RGB_MODE_TWINKLE,
575 516
576 // always leave at the end 517 // Start of custom keycode range for keyboards and keymaps - always leave at the end
577 SAFE_RANGE 518 SAFE_RANGE
578}; 519};
579 520
580// Ability to use mods in layouts 521// Keycode modifiers & aliases
581#define LCTL(kc) (QK_LCTL | (kc)) 522#define LCTL(kc) (QK_LCTL | (kc))
582#define LSFT(kc) (QK_LSFT | (kc)) 523#define LSFT(kc) (QK_LSFT | (kc))
583#define LALT(kc) (QK_LALT | (kc)) 524#define LALT(kc) (QK_LALT | (kc))
@@ -609,11 +550,7 @@ enum quantum_keycodes {
609#define MOD_HYPR 0xF 550#define MOD_HYPR 0xF
610#define MOD_MEH 0x7 551#define MOD_MEH 0x7
611 552
612// Aliases for shifted symbols 553// US ANSI shifted keycode aliases
613// Each key has a 4-letter code, and some have longer aliases too.
614// While the long aliases are descriptive, the 4-letter codes
615// make for nicer grid layouts (everything lines up), and are
616// the preferred style for Quantum.
617#define KC_TILD LSFT(KC_GRV) // ~ 554#define KC_TILD LSFT(KC_GRV) // ~
618#define KC_TILDE KC_TILD 555#define KC_TILDE KC_TILD
619 556
@@ -680,18 +617,15 @@ enum quantum_keycodes {
680 617
681#define KC_DELT KC_DELETE // Del key (four letter code) 618#define KC_DELT KC_DELETE // Del key (four letter code)
682 619
683// Alias for function layers than expand past FN31 620// Modified keycode aliases
684#define FUNC(kc) (QK_FUNCTION | (kc))
685
686// Aliases
687#define C(kc) LCTL(kc) 621#define C(kc) LCTL(kc)
688#define S(kc) LSFT(kc) 622#define S(kc) LSFT(kc)
689#define A(kc) LALT(kc) 623#define A(kc) LALT(kc)
690#define G(kc) LGUI(kc) 624#define G(kc) LGUI(kc)
691 625
692#define F(kc) FUNC(kc) 626// Deprecated - do not use
627#define F(kc) (QK_FUNCTION | (kc))
693#define M(kc) (QK_MACRO | (kc)) 628#define M(kc) (QK_MACRO | (kc))
694
695#define MACROTAP(kc) (QK_MACRO | (FUNC_TAP << 8) | (kc)) 629#define MACROTAP(kc) (QK_MACRO | (FUNC_TAP << 8) | (kc))
696#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) 630#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
697 631
@@ -699,19 +633,21 @@ enum quantum_keycodes {
699 633
700#define EEP_RST EEPROM_RESET 634#define EEP_RST EEPROM_RESET
701 635
636// Audio Clicky aliases
702#define CK_TOGG CLICKY_TOGGLE 637#define CK_TOGG CLICKY_TOGGLE
703#define CK_RST CLICKY_RESET 638#define CK_RST CLICKY_RESET
704#define CK_UP CLICKY_UP 639#define CK_UP CLICKY_UP
705#define CK_DOWN CLICKY_DOWN 640#define CK_DOWN CLICKY_DOWN
706#define CK_ON CLICKY_ENABLE 641#define CK_ON CLICKY_ENABLE
707#define CK_OFF CLICKY_DISABLE 642#define CK_OFF CLICKY_DISABLE
643// Fauxclicky (deprecated) redirects to Audio Clicky
708#define FC_ON CLICKY_ENABLE 644#define FC_ON CLICKY_ENABLE
709#define FC_OFF CLICKY_DISABLE 645#define FC_OFF CLICKY_DISABLE
710#define FC_TOGG CLICKY_TOGGLE 646#define FC_TOGG CLICKY_TOGGLE
711 647
648// RGB aliases
712#define RGB_MOD RGB_MODE_FORWARD 649#define RGB_MOD RGB_MODE_FORWARD
713#define RGB_RMOD RGB_MODE_REVERSE 650#define RGB_RMOD RGB_MODE_REVERSE
714
715#define RGB_M_P RGB_MODE_PLAIN 651#define RGB_M_P RGB_MODE_PLAIN
716#define RGB_M_B RGB_MODE_BREATHE 652#define RGB_M_B RGB_MODE_BREATHE
717#define RGB_M_R RGB_MODE_RAINBOW 653#define RGB_M_R RGB_MODE_RAINBOW
@@ -721,10 +657,9 @@ enum quantum_keycodes {
721#define RGB_M_X RGB_MODE_XMAS 657#define RGB_M_X RGB_MODE_XMAS
722#define RGB_M_G RGB_MODE_GRADIENT 658#define RGB_M_G RGB_MODE_GRADIENT
723#define RGB_M_T RGB_MODE_RGBTEST 659#define RGB_M_T RGB_MODE_RGBTEST
660#define RGB_M_TW RGB_MODE_TWINKLE
724 661
725// L-ayer, T-ap - 256 keycode max, 16 layer max 662// Magic aliases
726#define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF))
727
728#define CL_SWAP MAGIC_SWAP_CONTROL_CAPSLOCK 663#define CL_SWAP MAGIC_SWAP_CONTROL_CAPSLOCK
729#define CL_NORM MAGIC_UNSWAP_CONTROL_CAPSLOCK 664#define CL_NORM MAGIC_UNSWAP_CONTROL_CAPSLOCK
730#define CL_CTRL MAGIC_CAPSLOCK_TO_CONTROL 665#define CL_CTRL MAGIC_CAPSLOCK_TO_CONTROL
@@ -793,6 +728,9 @@ enum quantum_keycodes {
793// Layer tap-toggle 728// Layer tap-toggle
794#define TT(layer) (QK_LAYER_TAP_TOGGLE | ((layer)&0xFF)) 729#define TT(layer) (QK_LAYER_TAP_TOGGLE | ((layer)&0xFF))
795 730
731// L-ayer, T-ap - 256 keycode max, 16 layer max
732#define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF))
733
796// M-od, T-ap - 256 keycode max 734// M-od, T-ap - 256 keycode max
797#define MT(mod, kc) (QK_MOD_TAP | (((mod)&0x1F) << 8) | ((kc)&0xFF)) 735#define MT(mod, kc) (QK_MOD_TAP | (((mod)&0x1F) << 8) | ((kc)&0xFF))
798 736
@@ -842,6 +780,7 @@ enum quantum_keycodes {
842#define KC_HYPR HYPR(KC_NO) 780#define KC_HYPR HYPR(KC_NO)
843#define KC_MEH MEH(KC_NO) 781#define KC_MEH MEH(KC_NO)
844 782
783// Unicode aliases
845// UNICODE_ENABLE - Allows Unicode input up to 0x7FFF 784// UNICODE_ENABLE - Allows Unicode input up to 0x7FFF
846#define UC(c) (QK_UNICODE | (c)) 785#define UC(c) (QK_UNICODE | (c))
847// UNICODEMAP_ENABLE - Allows Unicode input up to 0x10FFFF, requires unicode_map 786// UNICODEMAP_ENABLE - Allows Unicode input up to 0x10FFFF, requires unicode_map
@@ -859,6 +798,7 @@ enum quantum_keycodes {
859#define UC_M_BS UNICODE_MODE_BSD 798#define UC_M_BS UNICODE_MODE_BSD
860#define UC_M_WC UNICODE_MODE_WINC 799#define UC_M_WC UNICODE_MODE_WINC
861 800
801// Swap Hands
862#define SH_T(kc) (QK_SWAP_HANDS | (kc)) 802#define SH_T(kc) (QK_SWAP_HANDS | (kc))
863#define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) 803#define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE)
864#define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) 804#define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE)
@@ -868,9 +808,30 @@ enum quantum_keycodes {
868#define SH_ON (QK_SWAP_HANDS | OP_SH_ON) 808#define SH_ON (QK_SWAP_HANDS | OP_SH_ON)
869#define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF) 809#define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF)
870 810
811// MIDI aliases
812#define MIDI_TONE_MIN MI_C
813#define MIDI_TONE_MAX MI_B_5
814#define MIDI_OCTAVE_MIN MI_OCT_N2
815#define MIDI_OCTAVE_MAX MI_OCT_7
816#define MIDI_TRANSPOSE_MIN MI_TRNS_N6
817#define MIDI_TRANSPOSE_MAX MI_TRNS_6
818#define MIDI_VELOCITY_MIN MI_VEL_0
819#define MIDI_VELOCITY_MAX MI_VEL_10
820#define MIDI_CHANNEL_MIN MI_CH1
821#define MIDI_CHANNEL_MAX MI_CH16
822
871// Dynamic Macros aliases 823// Dynamic Macros aliases
872#define DM_REC1 DYN_REC_START1 824#define DM_REC1 DYN_REC_START1
873#define DM_REC2 DYN_REC_START2 825#define DM_REC2 DYN_REC_START2
874#define DM_RSTP DYN_REC_STOP 826#define DM_RSTP DYN_REC_STOP
875#define DM_PLY1 DYN_MACRO_PLAY1 827#define DM_PLY1 DYN_MACRO_PLAY1
876#define DM_PLY2 DYN_MACRO_PLAY2 828#define DM_PLY2 DYN_MACRO_PLAY2
829
830// Joystick aliases
831#define JS_BUTTON_MIN JS_BUTTON0
832#define JS_BUTTON_MAX JS_BUTTON31
833
834// One Shot aliases
835#define OS_TOGG ONESHOT_TOGGLE
836#define OS_ON ONESHOT_ENABLE
837#define OS_OFF ONESHOT_DISABLE
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index ec17b4d72..8aae48603 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -131,7 +131,7 @@ last_hit_t g_last_hit_tracker;
131// internals 131// internals
132static uint8_t rgb_last_enable = UINT8_MAX; 132static uint8_t rgb_last_enable = UINT8_MAX;
133static uint8_t rgb_last_effect = UINT8_MAX; 133static uint8_t rgb_last_effect = UINT8_MAX;
134static effect_params_t rgb_effect_params = {0, 0xFF}; 134static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false};
135static rgb_task_states rgb_task_state = SYNCING; 135static rgb_task_states rgb_task_state = SYNCING;
136#if RGB_DISABLE_TIMEOUT > 0 136#if RGB_DISABLE_TIMEOUT > 0
137static uint32_t rgb_anykey_timer; 137static uint32_t rgb_anykey_timer;
@@ -143,6 +143,11 @@ static uint32_t rgb_timer_buffer;
143static last_hit_t last_hit_buffer; 143static last_hit_t last_hit_buffer;
144#endif // RGB_MATRIX_KEYREACTIVE_ENABLED 144#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
145 145
146// split rgb matrix
147#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
148const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
149#endif
150
146void eeconfig_read_rgb_matrix(void) { eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); } 151void eeconfig_read_rgb_matrix(void) { eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); }
147 152
148void eeconfig_update_rgb_matrix(void) { eeprom_update_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); } 153void eeconfig_update_rgb_matrix(void) { eeprom_update_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); }
@@ -153,6 +158,7 @@ void eeconfig_update_rgb_matrix_default(void) {
153 rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE; 158 rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE;
154 rgb_matrix_config.hsv = (HSV){RGB_MATRIX_STARTUP_HUE, RGB_MATRIX_STARTUP_SAT, RGB_MATRIX_STARTUP_VAL}; 159 rgb_matrix_config.hsv = (HSV){RGB_MATRIX_STARTUP_HUE, RGB_MATRIX_STARTUP_SAT, RGB_MATRIX_STARTUP_VAL};
155 rgb_matrix_config.speed = RGB_MATRIX_STARTUP_SPD; 160 rgb_matrix_config.speed = RGB_MATRIX_STARTUP_SPD;
161 rgb_matrix_config.flags = LED_FLAG_ALL;
156 eeconfig_update_rgb_matrix(); 162 eeconfig_update_rgb_matrix();
157} 163}
158 164
@@ -164,6 +170,7 @@ void eeconfig_debug_rgb_matrix(void) {
164 dprintf("rgb_matrix_config.hsv.s = %d\n", rgb_matrix_config.hsv.s); 170 dprintf("rgb_matrix_config.hsv.s = %d\n", rgb_matrix_config.hsv.s);
165 dprintf("rgb_matrix_config.hsv.v = %d\n", rgb_matrix_config.hsv.v); 171 dprintf("rgb_matrix_config.hsv.v = %d\n", rgb_matrix_config.hsv.v);
166 dprintf("rgb_matrix_config.speed = %d\n", rgb_matrix_config.speed); 172 dprintf("rgb_matrix_config.speed = %d\n", rgb_matrix_config.speed);
173 dprintf("rgb_matrix_config.flags = %d\n", rgb_matrix_config.flags);
167} 174}
168 175
169__attribute__((weak)) uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { return 0; } 176__attribute__((weak)) uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { return 0; }
@@ -180,9 +187,22 @@ uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *l
180 187
181void rgb_matrix_update_pwm_buffers(void) { rgb_matrix_driver.flush(); } 188void rgb_matrix_update_pwm_buffers(void) { rgb_matrix_driver.flush(); }
182 189
183void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { rgb_matrix_driver.set_color(index, red, green, blue); } 190void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
191#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
192 if (!is_keyboard_left() && index >= k_rgb_matrix_split[0])
193 rgb_matrix_driver.set_color(index - k_rgb_matrix_split[0], red, green, blue);
194 else if (is_keyboard_left() && index < k_rgb_matrix_split[0])
195#endif
196 rgb_matrix_driver.set_color(index, red, green, blue);
197}
184 198
185void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { rgb_matrix_driver.set_color_all(red, green, blue); } 199void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
200#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
201 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) rgb_matrix_set_color(i, red, green, blue);
202#else
203 rgb_matrix_driver.set_color_all(red, green, blue);
204#endif
205}
186 206
187void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) { 207void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) {
188#ifndef RGB_MATRIX_SPLIT 208#ifndef RGB_MATRIX_SPLIT
@@ -315,6 +335,10 @@ static void rgb_task_start(void) {
315static void rgb_task_render(uint8_t effect) { 335static void rgb_task_render(uint8_t effect) {
316 bool rendering = false; 336 bool rendering = false;
317 rgb_effect_params.init = (effect != rgb_last_effect) || (rgb_matrix_config.enable != rgb_last_enable); 337 rgb_effect_params.init = (effect != rgb_last_effect) || (rgb_matrix_config.enable != rgb_last_enable);
338 if (rgb_effect_params.flags != rgb_matrix_config.flags) {
339 rgb_effect_params.flags = rgb_matrix_config.flags;
340 rgb_matrix_set_color_all(0, 0, 0);
341 }
318 342
319 // each effect can opt to do calculations 343 // each effect can opt to do calculations
320 // and/or request PWM buffer updates. 344 // and/or request PWM buffer updates.
@@ -618,6 +642,6 @@ void rgb_matrix_decrease_speed_helper(bool write_to_eeprom) { rgb_matrix_set_spe
618void rgb_matrix_decrease_speed_noeeprom(void) { rgb_matrix_decrease_speed_helper(false); } 642void rgb_matrix_decrease_speed_noeeprom(void) { rgb_matrix_decrease_speed_helper(false); }
619void rgb_matrix_decrease_speed(void) { rgb_matrix_decrease_speed_helper(true); } 643void rgb_matrix_decrease_speed(void) { rgb_matrix_decrease_speed_helper(true); }
620 644
621led_flags_t rgb_matrix_get_flags(void) { return rgb_effect_params.flags; } 645led_flags_t rgb_matrix_get_flags(void) { return rgb_matrix_config.flags; }
622 646
623void rgb_matrix_set_flags(led_flags_t flags) { rgb_effect_params.flags = flags; } 647void rgb_matrix_set_flags(led_flags_t flags) { rgb_matrix_config.flags = flags; }
diff --git a/quantum/rgb_matrix_types.h b/quantum/rgb_matrix_types.h
index 7b8171fb2..1a37922af 100644
--- a/quantum/rgb_matrix_types.h
+++ b/quantum/rgb_matrix_types.h
@@ -85,10 +85,11 @@ typedef struct PACKED {
85typedef union { 85typedef union {
86 uint32_t raw; 86 uint32_t raw;
87 struct PACKED { 87 struct PACKED {
88 uint8_t enable : 2; 88 uint8_t enable : 2;
89 uint8_t mode : 6; 89 uint8_t mode : 6;
90 HSV hsv; 90 HSV hsv;
91 uint8_t speed; // EECONFIG needs to be increased to support this 91 uint8_t speed; // EECONFIG needs to be increased to support this
92 led_flags_t flags;
92 }; 93 };
93} rgb_config_t; 94} rgb_config_t;
94 95
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index d6636b886..f8de17809 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -43,6 +43,7 @@ extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
43uint8_t thisHand, thatHand; 43uint8_t thisHand, thatHand;
44 44
45// user-defined overridable functions 45// user-defined overridable functions
46__attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); }
46__attribute__((weak)) void matrix_slave_scan_user(void) {} 47__attribute__((weak)) void matrix_slave_scan_user(void) {}
47 48
48static inline void setPinOutput_writeLow(pin_t pin) { 49static inline void setPinOutput_writeLow(pin_t pin) {
@@ -284,7 +285,7 @@ bool matrix_post_scan(void) {
284 } else { 285 } else {
285 transport_slave(matrix + thatHand, matrix + thisHand); 286 transport_slave(matrix + thatHand, matrix + thisHand);
286 287
287 matrix_slave_scan_user(); 288 matrix_slave_scan_kb();
288 } 289 }
289 290
290 return changed; 291 return changed;
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 2ae44e6e1..9e75e19ce 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -1,3 +1,18 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include "split_util.h" 16#include "split_util.h"
2#include "matrix.h" 17#include "matrix.h"
3#include "keyboard.h" 18#include "keyboard.h"
@@ -6,14 +21,7 @@
6#include "transport.h" 21#include "transport.h"
7#include "quantum.h" 22#include "quantum.h"
8#include "wait.h" 23#include "wait.h"
9 24#include "usb_util.h"
10#ifdef PROTOCOL_LUFA
11# include <LUFA/Drivers/USB/USB.h>
12#endif
13
14#ifdef PROTOCOL_VUSB
15# include <usbdrv/usbdrv.h>
16#endif
17 25
18#ifdef EE_HANDS 26#ifdef EE_HANDS
19# include "eeconfig.h" 27# include "eeconfig.h"
@@ -31,56 +39,21 @@
31# define SPLIT_USB_TIMEOUT_POLL 10 39# define SPLIT_USB_TIMEOUT_POLL 10
32#endif 40#endif
33 41
34#ifdef PROTOCOL_CHIBIOS
35# define SPLIT_USB_DETECT // Force this on for now
36#endif
37
38volatile bool isLeftHand = true; 42volatile bool isLeftHand = true;
39 43
40#if defined(SPLIT_USB_DETECT) 44#if defined(SPLIT_USB_DETECT)
41# if defined(PROTOCOL_LUFA) 45static bool usbIsActive(void) {
42static inline bool usbHasActiveConnection(void) { return USB_Device_IsAddressSet(); }
43static inline void usbDisable(void) {
44 USB_Disable();
45 USB_DeviceState = DEVICE_STATE_Unattached;
46}
47# elif defined(PROTOCOL_CHIBIOS)
48static inline bool usbHasActiveConnection(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; }
49static inline void usbDisable(void) { usbStop(&USBD1); }
50# elif defined(PROTOCOL_VUSB)
51static inline bool usbHasActiveConnection(void) {
52 usbPoll();
53 return usbConfiguration;
54}
55static inline void usbDisable(void) { usbDeviceDisconnect(); }
56# else
57static inline bool usbHasActiveConnection(void) { return true; }
58static inline void usbDisable(void) {}
59# endif
60
61bool usbIsActive(void) {
62 for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) { 46 for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
63 // This will return true if a USB connection has been established 47 // This will return true if a USB connection has been established
64 if (usbHasActiveConnection()) { 48 if (usb_connected_state()) {
65 return true; 49 return true;
66 } 50 }
67 wait_ms(SPLIT_USB_TIMEOUT_POLL); 51 wait_ms(SPLIT_USB_TIMEOUT_POLL);
68 } 52 }
69
70 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
71 usbDisable();
72
73 return false; 53 return false;
74} 54}
75#elif defined(PROTOCOL_LUFA) && defined(OTGPADE)
76static inline bool usbIsActive(void) {
77 USB_OTGPAD_On(); // enables VBUS pad
78 wait_us(5);
79
80 return USB_VBUS_GetStatus(); // checks state of VBUS
81}
82#else 55#else
83static inline bool usbIsActive(void) { return true; } 56static inline bool usbIsActive(void) { return usb_vbus_state(); }
84#endif 57#endif
85 58
86#ifdef SPLIT_HAND_MATRIX_GRID 59#ifdef SPLIT_HAND_MATRIX_GRID
@@ -126,6 +99,11 @@ __attribute__((weak)) bool is_keyboard_master(void) {
126 // only check once, as this is called often 99 // only check once, as this is called often
127 if (usbstate == UNKNOWN) { 100 if (usbstate == UNKNOWN) {
128 usbstate = usbIsActive() ? MASTER : SLAVE; 101 usbstate = usbIsActive() ? MASTER : SLAVE;
102
103 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
104 if (usbstate == SLAVE) {
105 usb_disable();
106 }
129 } 107 }
130 108
131 return (usbstate == MASTER); 109 return (usbstate == MASTER);
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index 61b61ea08..b67702f15 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -22,6 +22,13 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A;
22# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) 22# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
23#endif 23#endif
24 24
25#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
26# include "led_matrix.h"
27#endif
28#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
29# include "rgb_matrix.h"
30#endif
31
25#if defined(USE_I2C) 32#if defined(USE_I2C)
26 33
27# include "i2c_master.h" 34# include "i2c_master.h"
@@ -54,6 +61,14 @@ typedef struct _I2C_slave_buffer_t {
54# ifdef WPM_ENABLE 61# ifdef WPM_ENABLE
55 uint8_t current_wpm; 62 uint8_t current_wpm;
56# endif 63# endif
64# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
65 led_eeconfig_t led_matrix;
66 bool led_suspend_state;
67# endif
68# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
69 rgb_config_t rgb_matrix;
70 bool rgb_suspend_state;
71# endif
57} I2C_slave_buffer_t; 72} I2C_slave_buffer_t;
58 73
59static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; 74static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg;
@@ -68,6 +83,10 @@ static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_re
68# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) 83# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync)
69# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) 84# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state)
70# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) 85# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm)
86# define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix)
87# define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state)
88# define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix)
89# define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state)
71 90
72# define TIMEOUT 100 91# define TIMEOUT 100
73 92
@@ -141,6 +160,15 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
141# endif 160# endif
142# endif 161# endif
143 162
163# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
164 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT);
165 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT);
166# endif
167# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
168 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT);
169 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT);
170# endif
171
144# ifndef DISABLE_SYNC_TIMER 172# ifndef DISABLE_SYNC_TIMER
145 i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; 173 i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
146 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT); 174 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
@@ -186,6 +214,15 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
186 set_oneshot_mods(i2c_buffer->oneshot_mods); 214 set_oneshot_mods(i2c_buffer->oneshot_mods);
187# endif 215# endif
188# endif 216# endif
217
218# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
219 memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix));
220 memcpy((void *)i2c_buffer->led_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state));
221# endif
222# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
223 memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix));
224 memcpy((void *)i2c_buffer->rgb_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state));
225# endif
189} 226}
190 227
191void transport_master_init(void) { i2c_init(); } 228void transport_master_init(void) { i2c_init(); }
@@ -208,23 +245,31 @@ typedef struct _Serial_s2m_buffer_t {
208 245
209typedef struct _Serial_m2s_buffer_t { 246typedef struct _Serial_m2s_buffer_t {
210# ifdef SPLIT_MODS_ENABLE 247# ifdef SPLIT_MODS_ENABLE
211 uint8_t real_mods; 248 uint8_t real_mods;
212 uint8_t weak_mods; 249 uint8_t weak_mods;
213# ifndef NO_ACTION_ONESHOT 250# ifndef NO_ACTION_ONESHOT
214 uint8_t oneshot_mods; 251 uint8_t oneshot_mods;
215# endif 252# endif
216# endif 253# endif
217# ifndef DISABLE_SYNC_TIMER 254# ifndef DISABLE_SYNC_TIMER
218 uint32_t sync_timer; 255 uint32_t sync_timer;
219# endif 256# endif
220# ifdef SPLIT_TRANSPORT_MIRROR 257# ifdef SPLIT_TRANSPORT_MIRROR
221 matrix_row_t mmatrix[ROWS_PER_HAND]; 258 matrix_row_t mmatrix[ROWS_PER_HAND];
222# endif 259# endif
223# ifdef BACKLIGHT_ENABLE 260# ifdef BACKLIGHT_ENABLE
224 uint8_t backlight_level; 261 uint8_t backlight_level;
225# endif 262# endif
226# ifdef WPM_ENABLE 263# ifdef WPM_ENABLE
227 uint8_t current_wpm; 264 uint8_t current_wpm;
265# endif
266# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
267 led_eeconfig_t led_matrix;
268 bool led_suspend_state;
269# endif
270# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
271 rgb_config_t rgb_matrix;
272 bool rgb_suspend_state;
228# endif 273# endif
229} Serial_m2s_buffer_t; 274} Serial_m2s_buffer_t;
230 275
@@ -333,18 +378,28 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
333 378
334# ifdef WPM_ENABLE 379# ifdef WPM_ENABLE
335 // Write wpm to slave 380 // Write wpm to slave
336 serial_m2s_buffer.current_wpm = get_current_wpm(); 381 serial_m2s_buffer.current_wpm = get_current_wpm();
337# endif 382# endif
338 383
339# ifdef SPLIT_MODS_ENABLE 384# ifdef SPLIT_MODS_ENABLE
340 serial_m2s_buffer.real_mods = get_mods(); 385 serial_m2s_buffer.real_mods = get_mods();
341 serial_m2s_buffer.weak_mods = get_weak_mods(); 386 serial_m2s_buffer.weak_mods = get_weak_mods();
342# ifndef NO_ACTION_ONESHOT 387# ifndef NO_ACTION_ONESHOT
343 serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); 388 serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
344# endif 389# endif
345# endif 390# endif
391
392# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
393 serial_m2s_buffer.led_matrix = led_matrix_econfig;
394 serial_m2s_buffer.led_suspend_state = g_suspend_state;
395# endif
396# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
397 serial_m2s_buffer.rgb_matrix = rgb_matrix_config;
398 serial_m2s_buffer.rgb_suspend_state = g_suspend_state;
399# endif
400
346# ifndef DISABLE_SYNC_TIMER 401# ifndef DISABLE_SYNC_TIMER
347 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; 402 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
348# endif 403# endif
349 return true; 404 return true;
350} 405}
@@ -381,6 +436,15 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
381 set_oneshot_mods(serial_m2s_buffer.oneshot_mods); 436 set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
382# endif 437# endif
383# endif 438# endif
439
440# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
441 led_matrix_eeconfig = serial_m2s_buffer.led_matrix;
442 g_suspend_state = serial_m2s_buffer.led_suspend_state;
443# endif
444# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
445 rgb_matrix_config = serial_m2s_buffer.rgb_matrix;
446 g_suspend_state = serial_m2s_buffer.rgb_suspend_state;
447# endif
384} 448}
385 449
386#endif 450#endif
diff --git a/quantum/wpm.c b/quantum/wpm.c
index da30bd252..bec419a48 100644
--- a/quantum/wpm.c
+++ b/quantum/wpm.c
@@ -19,11 +19,10 @@
19 19
20// WPM Stuff 20// WPM Stuff
21static uint8_t current_wpm = 0; 21static uint8_t current_wpm = 0;
22static uint8_t latest_wpm = 0;
23static uint16_t wpm_timer = 0; 22static uint16_t wpm_timer = 0;
24 23
25// This smoothing is 40 keystrokes 24// This smoothing is 40 keystrokes
26static const float wpm_smoothing = 0.0487; 25static const float wpm_smoothing = WPM_SMOOTHING;
27 26
28void set_current_wpm(uint8_t new_wpm) { current_wpm = new_wpm; } 27void set_current_wpm(uint8_t new_wpm) { current_wpm = new_wpm; }
29 28
@@ -46,19 +45,46 @@ __attribute__((weak)) bool wpm_keycode_user(uint16_t keycode) {
46 return false; 45 return false;
47} 46}
48 47
48#ifdef WPM_ALLOW_COUNT_REGRESSION
49__attribute__((weak)) uint8_t wpm_regress_count(uint16_t keycode) {
50 bool weak_modded = (keycode >= QK_LCTL && keycode < QK_LSFT) || (keycode >= QK_RCTL && keycode < QK_RSFT);
51
52 if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) {
53 keycode = keycode & 0xFF;
54 } else if (keycode > 0xFF) {
55 keycode = 0;
56 }
57 if (keycode == KC_DEL || keycode == KC_BSPC) {
58 if (((get_mods() | get_oneshot_mods()) & MOD_MASK_CTRL) || weak_modded) {
59 return WPM_ESTIMATED_WORD_SIZE;
60 } else {
61 return 1;
62 }
63 } else {
64 return 0;
65 }
66}
67#endif
68
49void update_wpm(uint16_t keycode) { 69void update_wpm(uint16_t keycode) {
50 if (wpm_keycode(keycode)) { 70 if (wpm_keycode(keycode)) {
51 if (wpm_timer > 0) { 71 if (wpm_timer > 0) {
52 latest_wpm = 60000 / timer_elapsed(wpm_timer) / 5; 72 current_wpm += ((60000 / timer_elapsed(wpm_timer) / WPM_ESTIMATED_WORD_SIZE) - current_wpm) * wpm_smoothing;
53 current_wpm = (latest_wpm - current_wpm) * wpm_smoothing + current_wpm;
54 } 73 }
55 wpm_timer = timer_read(); 74 wpm_timer = timer_read();
56 } 75 }
76#ifdef WPM_ALLOW_COUNT_REGRESSION
77 uint8_t regress = wpm_regress_count(keycode);
78 if (regress) {
79 current_wpm -= regress;
80 wpm_timer = timer_read();
81 }
82#endif
57} 83}
58 84
59void decay_wpm(void) { 85void decay_wpm(void) {
60 if (timer_elapsed(wpm_timer) > 1000) { 86 if (timer_elapsed(wpm_timer) > 1000) {
61 current_wpm = (0 - current_wpm) * wpm_smoothing + current_wpm; 87 current_wpm += (-current_wpm) * wpm_smoothing;
62 wpm_timer = timer_read(); 88 wpm_timer = timer_read();
63 } 89 }
64} 90}
diff --git a/quantum/wpm.h b/quantum/wpm.h
index 15ab4ffcd..4af52d2b9 100644
--- a/quantum/wpm.h
+++ b/quantum/wpm.h
@@ -19,10 +19,21 @@
19 19
20#include "quantum.h" 20#include "quantum.h"
21 21
22#ifndef WPM_ESTIMATED_WORD_SIZE
23# define WPM_ESTIMATED_WORD_SIZE 5
24#endif
25#ifndef WPM_SMOOTHING
26# define WPM_SMOOTHING 0.0487
27#endif
28
22bool wpm_keycode(uint16_t keycode); 29bool wpm_keycode(uint16_t keycode);
23bool wpm_keycode_kb(uint16_t keycode); 30bool wpm_keycode_kb(uint16_t keycode);
24bool wpm_keycode_user(uint16_t keycode); 31bool wpm_keycode_user(uint16_t keycode);
25 32
33#ifdef WPM_ALLOW_COUNT_REGRESSION
34uint8_t wpm_regress_count(uint16_t keycode);
35#endif
36
26void set_current_wpm(uint8_t); 37void set_current_wpm(uint8_t);
27uint8_t get_current_wpm(void); 38uint8_t get_current_wpm(void);
28void update_wpm(uint16_t); 39void update_wpm(uint16_t);