aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
authorJames Young <18669334+noroadsleft@users.noreply.github.com>2021-05-29 14:38:50 -0700
committerGitHub <noreply@github.com>2021-05-29 14:38:50 -0700
commit1646c0f26cfa21a7023d404008e4d0aa4917193d (patch)
tree337ab0498a929285a234518fee34a4d9dcf51656 /quantum
parentf55e39e8a2246f6f96fd5d4a84a866e2615cde7b (diff)
downloadqmk_firmware-1646c0f26cfa21a7023d404008e4d0aa4917193d.tar.gz
qmk_firmware-1646c0f26cfa21a7023d404008e4d0aa4917193d.zip
2021 May 29 Breaking Changes Update (#13034)
* Add Per Key functionality for AutoShift (#11536) * LED Matrix: Reactive effect buffers & advanced indicators (#12588) * [Keyboard] kint36: switch to sym_eager_pk debouncing (#12626) * [Keyboard] kint2pp: reduce input latency by ≈10ms (#12625) * LED Matrix: Split (#12633) * [CI] Format code according to conventions (#12650) * feat: infinite timeout for leader key (#6580) * feat: implement leader_no_timeout logic * docs(leader_key): infinite leader timeout docs * Format code according to conventions (#12680) * Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx (#12403) * Fix default ADC_RESOLUTION for ADCv3 (and ADCv4) Recent ChibiOS update removed ADC_CFGR1_RES_10BIT from the ADCv3 headers (that macro should not have been there, because ADCv3 has CFGR instead of CFGR1). Fix the default value for ADC_RESOLUTION to use ADC_CFGR_RES_10BITS if it is defined (that name is used for ADCv3 and ADCv4). * Update ADC docs to match the actually used resolution ADC driver for ChibiOS actually uses the 10-bit resolution by default (probably to match AVR); fix the documentation accordingly. Also add both ADC_CFGR_RES_10BITS and ADC_CFGR1_RES_10BIT constants (these names differ according to the ADC implementation in the particular MCU). * Fix pinToMux() for B12 and B13 on STM32F3xx Testing on STM32F303CCT6 revealed that the ADC mux values for B12 and B13 pins were wrong. * Add support for all possible analog pins on STM32F1xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 on STM32F1xx (they are the same at least for STM32F103x8 and larger F103 devices, and also F102, F105, F107 families). Actually tested on STM32F103C8T6 (therefore pins C0...C5 were not tested). Pins F6...F10, which are present on STM32F103x[C-G] in 144-pin packages, cannot be supported at the moment, because those pins are connected only to ADC3, but the ChibiOS ADC driver for STM32F1xx supports only ADC1. * Add support for all possible analog pins on STM32F4xx Added ADC mux values for pins A0...A7, B0, B1, C0...C5 and optionally F3...F10 (if STM32_ADC_USE_ADC3 is enabled). These mux values are apparently the same for all F4xx devices, except some smaller devices may not have ADC3. Actually tested on STM32F401CCU6, STM32F401CEU6, STM32F411CEU6 (using various WeAct “Blackpill” boards); only pins A0...A7, B0, B1 were tested. Pins F3...F10 are inside `#if STM32_ADC_USE_ADC3` because some devices which don't have ADC3 also don't have the GPIOF port, therefore the code which refers to Fx pins does not compile. * Fix STM32F3xx ADC mux table in documentation The ADC driver documentation had some errors in the mux table for STM32F3xx. Fix this table to match the datasheet and the actual code (mux settings for B12 and B13 were also tested on a real STM32F303CCT6 chip). * Add STM32F1xx ADC pins to the documentation * Add STM32F4xx ADC pins to the documentation * Add initial support for tinyuf2 bootloader (when hosted on F411 blackpill) (#12600) * Add support for jumping to tinyuf2 bootloader. Adds blackpill UF2 example. * Update flashing.md * Update chconf.h * Update config.h * Update halconf.h * Update mcuconf.h * eeprom driver: Refactor where eeprom driver initialisation (and EEPROM emulation initialisation) occurs to make it non-target-specific. (#12671) * Add support for MCU = STM32F446 (#12619) * Add support for MCU = STM32F446 * Update platforms/chibios/GENERIC_STM32_F446XE/configs/config.h * Restore mcuconf.h to the one used by RT-STM32F446RE-NUCLEO64 * stm32f446: update mcuconf.h and board.h for 16MHz operation, with USB enabled, and other peripherals disabled. * Format code according to conventions (#12682) * Format code according to conventions (#12687) * Add STM32L433 and L443 support (#12063) * initial L433 commit * change to XC * fix L433 * disable all peripherals * update system and peripheral clocks * 433 change * use its own board files * revert its own board files * l433 specific change * fix stm32l432xx define * remove duplicate #define * fix bootloader jump * move to L443xx and add i2c2, spi2, usart3 to mcuconf.h * move to L443 * move to L443 * fix sdmmc in mcuconf.h * include STM32L443 * add L443 * Include L443 in compatible microcontrollers * Include L443 in compatible microcontrollers * Update config bootloader jump description * Update ChibiOS define reasoning * Update quantum/mcu_selection.mk * fix git conflict * Updated Function96 with V2 files and removed chconf.h and halconf.h (#12613) * Fix bad PR merge for #6580. (#12721) * Change RGB/LED Matrix to use a simple define for USB suspend (#12697) * [CI] Format code according to conventions (#12731) * Fixing transport's led/rgb matrix suspend state logic (#12770) * [CI] Format code according to conventions (#12772) * Fix comment parsing (#12750) * Added OLED fade out support (#12086) * fix some references to bin/qmk that slipped in (#12832) * Resolve a number of warnings in `qmk generate-api` (#12833) * New command: qmk console (#12828) * stash poc * stash * tidy up implementation * Tidy up slightly for review * Tidy up slightly for review * Bodge environment to make tests pass * Refactor away from asyncio due to windows issues * Filter devices * align vid/pid printing * Add hidapi to the installers * start preparing for multiple hid_listeners * udev rules for hid_listen * refactor to move closer to end state * very basic implementation of the threaded model * refactor how vid/pid/index are supplied and parsed * windows improvements * read the report directly when usage page isn't available * add per-device colors, the choice to show names or numbers, and refactor * add timestamps * Add support for showing bootloaders * tweak the color for bootloaders * Align bootloader disconnect with connect color * add support for showing all bootloaders * fix the pyusb check * tweaks * fix exception * hide a stack trace behind -v * add --no-bootloaders option * add documentation for qmk console * Apply suggestions from code review * pyformat * clean up and flesh out KNOWN_BOOTLOADERS * Remove pointless SERIAL_LINK_ENABLE rules (#12846) * Make Swap Hands use PROGMEM (#12284) This converts the array that the Swap Hands feature uses to use PROGMEM, and to read from that array, as such. Since this array never changes at runtime, there is no reason to keep it in memory. Especially for AVR boards, as memory is a precious resource. * Fix another bin/qmk reference (#12856) * [Keymap] Turn OLED off on suspend in soundmonster keymap (#10419) * Fixup build errors on `develop` branch. (#12723) * LED Matrix: Effects! (#12651) * Fix syntax error when compiling for ARM (#12866) * Remove KEYMAP and LAYOUT_kc (#12160) * alias KEYMAP to LAYOUT * remove KEYMAP and LAYOUT_kc * Add setup, clone, and env to the list of commands we allow even with broken modules (#12868) * Rename `point_t` -> `led_point_t` (#12864) * [Keyboard] updated a vendor name / fixed minor keymap issues (#12881) * Add missing LED Matrix suspend code to suspend.c (#12878) * LED Matrix: Documentation (#12685) * Deprecate `send_unicode_hex_string()` (#12602) * Fix spelling mistake regarding LED Matrix in split_common. (#12888) * [Keymap] Fix QWERTY/DVORAK status output for kzar keymap (#12895) * Use milc.subcommand.config instead of qmk.cli.config (#12915) * Use milc.subcommand.config instead * pyformat * remove the config test * Add function to allow repeated blinking of one layer (#12237) * Implement function rgblight_blink_layer_repeat to allow repeated blinking of one layer at a time * Update doc * Rework rgblight blinking according to requested change * optimize storage * Fixup housekeeping from being invoked twice per loop. (#12933) * matrix: wait for row signal to go HIGH for every row (#12945) I noticed this discrepancy (last row of the matrix treated differently than the others) when optimizing the input latency of my keyboard controller, see also https://michael.stapelberg.ch/posts/2021-05-08-keyboard-input-latency-qmk-kinesis/ Before this commit, when tuning the delays I noticed ghost key presses when pressing the F2 key, which is on the last row of the keyboard matrix: the dead_grave key, which is on the first row of the keyboard matrix, would be incorrectly detected as pressed. After this commit, all keyboard matrix rows are interpreted correctly. I suspect that my setup is more susceptible to this nuance than others because I use GPIO_INPUT_PIN_DELAY=0 and hence don’t have another delay that might mask the problem. * ensure we do not conflict with existing keymap aliases (#12976) * Add support for up to 4 IS31FL3733 drivers (#12342) * Convert Encoder callbacks to be boolean functions (#12805) * [Keyboard] Fix Terrazzo build failure (#12977) * Do not hard set config in CPTC files (#11864) * [Keyboard] Corne - Remove legacy revision support (#12226) * [Keymap] Update to Drashna keymap and user code (based on develop) (#12936) * Add Full-duplex serial driver for ARM boards (#9842) * Document LED_MATRIX_FRAMEBUFFER_EFFECTS (#12987) * Backlight: add defines for default level and breathing state (#12560) * Add dire message about LUFA mass storage bootloader (#13014) * [Keyboard] Remove redundant legacy and common headers for crkbd (#13023) Was causing compiler errors on some systems. * Fix keyboards/keymaps for boolean encoder callback changes (#12985) * `backlight.c`: include `eeprom.h` (#13024) * Add changelog for 2021-05-29 Breaking Changes merge (#12939) * Add ChangeLog for 2021-05-29 Breaking Changes Merge: initial version * Add recent develop changes * Sort recent develop changes * Remove sections for ChibiOS changes per tzarc No ChibiOS changes this round. * Add and sort recent develop changes * add notes about keyboard moves/deletions * import changelog for PR 12172 Documents the change to BOOTMAGIC_ENABLE. * update section headings * re-sort changelog * add additional note regarding Bootmagic changes * remove changelog timestamp * update dates in main Breaking Changes docs * fix broken section anchors in previous changelogs * add link to backlight/eeprom patch to changelog * highlight some more changes * link PRs from section headers * Restore standard readme * run: qmk cformat --core-only
Diffstat (limited to 'quantum')
-rw-r--r--quantum/backlight/backlight.c24
-rw-r--r--quantum/backlight/backlight.h4
-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/config_common.h3
-rw-r--r--quantum/encoder.c10
-rw-r--r--quantum/encoder.h4
-rw-r--r--quantum/keycode_config.h1
-rw-r--r--quantum/led_matrix.c615
-rw-r--r--quantum/led_matrix.h144
-rw-r--r--quantum/led_matrix_animations/alpha_mods_anim.h24
-rw-r--r--quantum/led_matrix_animations/band_anim.h13
-rw-r--r--quantum/led_matrix_animations/band_pinwheel_anim.h10
-rw-r--r--quantum/led_matrix_animations/band_spiral_anim.h10
-rw-r--r--quantum/led_matrix_animations/breathing_anim.h19
-rw-r--r--quantum/led_matrix_animations/cycle_left_right_anim.h10
-rw-r--r--quantum/led_matrix_animations/cycle_out_in_anim.h10
-rw-r--r--quantum/led_matrix_animations/cycle_up_down_anim.h10
-rw-r--r--quantum/led_matrix_animations/dual_beacon_anim.h10
-rw-r--r--quantum/led_matrix_animations/led_matrix_effects.inc18
-rw-r--r--quantum/led_matrix_animations/solid_anim.h15
-rw-r--r--quantum/led_matrix_animations/solid_reactive_cross.h35
-rw-r--r--quantum/led_matrix_animations/solid_reactive_nexus.h32
-rw-r--r--quantum/led_matrix_animations/solid_reactive_simple_anim.h12
-rw-r--r--quantum/led_matrix_animations/solid_reactive_wide.h30
-rw-r--r--quantum/led_matrix_animations/solid_splash_anim.h30
-rw-r--r--quantum/led_matrix_animations/wave_left_right_anim.h10
-rw-r--r--quantum/led_matrix_animations/wave_up_down_anim.h10
-rw-r--r--quantum/led_matrix_drivers.c27
-rw-r--r--quantum/led_matrix_runners/effect_runner_dx_dy.h16
-rw-r--r--quantum/led_matrix_runners/effect_runner_dx_dy_dist.h17
-rw-r--r--quantum/led_matrix_runners/effect_runner_i.h14
-rw-r--r--quantum/led_matrix_runners/effect_runner_reactive.h28
-rw-r--r--quantum/led_matrix_runners/effect_runner_reactive_splash.h26
-rw-r--r--quantum/led_matrix_runners/effect_runner_sin_cos_i.h16
-rw-r--r--quantum/led_matrix_types.h46
-rw-r--r--quantum/matrix.c8
-rw-r--r--quantum/matrix.h5
-rw-r--r--quantum/mcu_selection.mk130
-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.h7
-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.h925
-rw-r--r--quantum/rgb_matrix.c61
-rw-r--r--quantum/rgb_matrix.h1
-rw-r--r--quantum/rgb_matrix_drivers.c39
-rw-r--r--quantum/rgb_matrix_types.h17
-rw-r--r--quantum/rgblight.c44
-rw-r--r--quantum/rgblight.h1
-rw-r--r--quantum/split_common/matrix.c11
-rw-r--r--quantum/split_common/split_util.c70
-rw-r--r--quantum/split_common/transport.c92
-rw-r--r--quantum/wpm.c38
-rw-r--r--quantum/wpm.h11
64 files changed, 2424 insertions, 931 deletions
diff --git a/quantum/backlight/backlight.c b/quantum/backlight/backlight.c
index 113beb832..dfb98419e 100644
--- a/quantum/backlight/backlight.c
+++ b/quantum/backlight/backlight.c
@@ -17,11 +17,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18#include "quantum.h" 18#include "quantum.h"
19#include "backlight.h" 19#include "backlight.h"
20#include "eeprom.h"
20#include "eeconfig.h" 21#include "eeconfig.h"
21#include "debug.h" 22#include "debug.h"
22 23
23backlight_config_t backlight_config; 24backlight_config_t backlight_config;
24 25
26#ifndef BACKLIGHT_DEFAULT_LEVEL
27# define BACKLIGHT_DEFAULT_LEVEL BACKLIGHT_LEVELS
28#endif
29
25#ifdef BACKLIGHT_BREATHING 30#ifdef BACKLIGHT_BREATHING
26// TODO: migrate to backlight_config_t 31// TODO: migrate to backlight_config_t
27static uint8_t breathing_period = BREATHING_PERIOD; 32static uint8_t breathing_period = BREATHING_PERIOD;
@@ -35,6 +40,7 @@ void backlight_init(void) {
35 /* check signature */ 40 /* check signature */
36 if (!eeconfig_is_enabled()) { 41 if (!eeconfig_is_enabled()) {
37 eeconfig_init(); 42 eeconfig_init();
43 eeconfig_update_backlight_default();
38 } 44 }
39 backlight_config.raw = eeconfig_read_backlight(); 45 backlight_config.raw = eeconfig_read_backlight();
40 if (backlight_config.level > BACKLIGHT_LEVELS) { 46 if (backlight_config.level > BACKLIGHT_LEVELS) {
@@ -152,11 +158,23 @@ void backlight_level(uint8_t level) {
152 eeconfig_update_backlight(backlight_config.raw); 158 eeconfig_update_backlight(backlight_config.raw);
153} 159}
154 160
155/** \brief Update current backlight state to EEPROM 161uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
156 * 162
157 */ 163void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
164
158void eeconfig_update_backlight_current(void) { eeconfig_update_backlight(backlight_config.raw); } 165void eeconfig_update_backlight_current(void) { eeconfig_update_backlight(backlight_config.raw); }
159 166
167void eeconfig_update_backlight_default(void) {
168 backlight_config.enable = 1;
169#ifdef BACKLIGHT_DEFAULT_BREATHING
170 backlight_config.breathing = 1;
171#else
172 backlight_config.breathing = 0;
173#endif
174 backlight_config.level = BACKLIGHT_DEFAULT_LEVEL;
175 eeconfig_update_backlight(backlight_config.raw);
176}
177
160/** \brief Get backlight level 178/** \brief Get backlight level
161 * 179 *
162 * FIXME: needs doc 180 * FIXME: needs doc
diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h
index 3e506737d..c30c70fd6 100644
--- a/quantum/backlight/backlight.h
+++ b/quantum/backlight/backlight.h
@@ -55,7 +55,11 @@ void backlight_decrease(void);
55void backlight_level_noeeprom(uint8_t level); 55void backlight_level_noeeprom(uint8_t level);
56void backlight_level(uint8_t level); 56void backlight_level(uint8_t level);
57uint8_t get_backlight_level(void); 57uint8_t get_backlight_level(void);
58
59uint8_t eeconfig_read_backlight(void);
60void eeconfig_update_backlight(uint8_t val);
58void eeconfig_update_backlight_current(void); 61void eeconfig_update_backlight_current(void);
62void eeconfig_update_backlight_default(void);
59 63
60// implementation specific 64// implementation specific
61void backlight_init_ports(void); 65void backlight_init_ports(void);
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/config_common.h b/quantum/config_common.h
index d93477b27..661609ef2 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -24,4 +24,7 @@
24#define COL2ROW 0 24#define COL2ROW 0
25#define ROW2COL 1 25#define ROW2COL 1
26 26
27// Deprecated alias - avoid using
28#define KEYMAP LAYOUT
29
27#include "song_list.h" 30#include "song_list.h"
diff --git a/quantum/encoder.c b/quantum/encoder.c
index 2ed64c1e3..c30bf01cb 100644
--- a/quantum/encoder.c
+++ b/quantum/encoder.c
@@ -59,9 +59,9 @@ static uint8_t thisHand, thatHand;
59static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; 59static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0};
60#endif 60#endif
61 61
62__attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} 62__attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) { return true; }
63 63
64__attribute__((weak)) void encoder_update_kb(int8_t index, bool clockwise) { encoder_update_user(index, clockwise); } 64__attribute__((weak)) bool encoder_update_kb(uint8_t index, bool clockwise) { return encoder_update_user(index, clockwise); }
65 65
66void encoder_init(void) { 66void encoder_init(void) {
67#if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) 67#if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT)
@@ -94,14 +94,14 @@ void encoder_init(void) {
94#endif 94#endif
95} 95}
96 96
97static bool encoder_update(int8_t index, uint8_t state) { 97static bool encoder_update(uint8_t index, uint8_t state) {
98 bool changed = false; 98 bool changed = false;
99 uint8_t i = index; 99 uint8_t i = index;
100 100
101#ifdef ENCODER_RESOLUTIONS 101#ifdef ENCODER_RESOLUTIONS
102 int8_t resolution = encoder_resolutions[i]; 102 uint8_t resolution = encoder_resolutions[i];
103#else 103#else
104 int8_t resolution = ENCODER_RESOLUTION; 104 uint8_t resolution = ENCODER_RESOLUTION;
105#endif 105#endif
106 106
107#ifdef SPLIT_KEYBOARD 107#ifdef SPLIT_KEYBOARD
diff --git a/quantum/encoder.h b/quantum/encoder.h
index db6f220da..25dc77721 100644
--- a/quantum/encoder.h
+++ b/quantum/encoder.h
@@ -22,8 +22,8 @@
22void encoder_init(void); 22void encoder_init(void);
23bool encoder_read(void); 23bool encoder_read(void);
24 24
25void encoder_update_kb(int8_t index, bool clockwise); 25bool encoder_update_kb(uint8_t index, bool clockwise);
26void encoder_update_user(int8_t index, bool clockwise); 26bool encoder_update_user(uint8_t index, bool clockwise);
27 27
28#ifdef SPLIT_KEYBOARD 28#ifdef SPLIT_KEYBOARD
29void encoder_state_raw(uint8_t* slave_state); 29void encoder_state_raw(uint8_t* slave_state);
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..d612fbfa9 100644
--- a/quantum/led_matrix.c
+++ b/quantum/led_matrix.c
@@ -17,79 +17,143 @@
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#ifndef LED_MATRIX_CENTER
33# define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 31const led_point_t k_led_matrix_center = {112, 32};
32#else
33const led_point_t k_led_matrix_center = LED_MATRIX_CENTER;
34#endif 34#endif
35 35
36#ifndef MIN 36// Generic effect runners
37# define MIN(a, b) ((a) < (b) ? (a) : (b)) 37#include "led_matrix_runners/effect_runner_dx_dy_dist.h"
38#include "led_matrix_runners/effect_runner_dx_dy.h"
39#include "led_matrix_runners/effect_runner_i.h"
40#include "led_matrix_runners/effect_runner_sin_cos_i.h"
41#include "led_matrix_runners/effect_runner_reactive.h"
42#include "led_matrix_runners/effect_runner_reactive_splash.h"
43
44// ------------------------------------------
45// -----Begin led effect includes macros-----
46#define LED_MATRIX_EFFECT(name)
47#define LED_MATRIX_CUSTOM_EFFECT_IMPLS
48
49#include "led_matrix_animations/led_matrix_effects.inc"
50#ifdef LED_MATRIX_CUSTOM_KB
51# include "led_matrix_kb.inc"
38#endif 52#endif
53#ifdef LED_MATRIX_CUSTOM_USER
54# include "led_matrix_user.inc"
55#endif
56
57#undef LED_MATRIX_CUSTOM_EFFECT_IMPLS
58#undef LED_MATRIX_EFFECT
59// -----End led effect includes macros-------
60// ------------------------------------------
39 61
40#ifndef LED_DISABLE_AFTER_TIMEOUT 62#if defined(LED_DISABLE_AFTER_TIMEOUT) && !defined(LED_DISABLE_TIMEOUT)
41# define LED_DISABLE_AFTER_TIMEOUT 0 63# define LED_DISABLE_TIMEOUT (LED_DISABLE_AFTER_TIMEOUT * 1200UL)
42#endif 64#endif
43 65
44#ifndef LED_DISABLE_WHEN_USB_SUSPENDED 66#ifndef LED_DISABLE_TIMEOUT
45# define LED_DISABLE_WHEN_USB_SUSPENDED false 67# define LED_DISABLE_TIMEOUT 0
46#endif 68#endif
47 69
48#ifndef EECONFIG_LED_MATRIX 70#if LED_DISABLE_WHEN_USB_SUSPENDED == false
49# define EECONFIG_LED_MATRIX EECONFIG_RGBLIGHT 71# undef LED_DISABLE_WHEN_USB_SUSPENDED
50#endif 72#endif
51 73
52#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > 255 74#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX
53# define LED_MATRIX_MAXIMUM_BRIGHTNESS 255 75# undef LED_MATRIX_MAXIMUM_BRIGHTNESS
76# define LED_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX
54#endif 77#endif
55 78
56bool g_suspend_state = false; 79#if !defined(LED_MATRIX_VAL_STEP)
80# define LED_MATRIX_VAL_STEP 8
81#endif
57 82
58// Global tick at 20 Hz 83#if !defined(LED_MATRIX_SPD_STEP)
59uint32_t g_tick = 0; 84# define LED_MATRIX_SPD_STEP 16
85#endif
60 86
61// Ticks since this key was last hit. 87#if !defined(LED_MATRIX_STARTUP_MODE)
62uint8_t g_key_hit[DRIVER_LED_TOTAL]; 88# define LED_MATRIX_STARTUP_MODE LED_MATRIX_SOLID
89#endif
63 90
64// Ticks since any key was last hit. 91#if !defined(LED_MATRIX_STARTUP_VAL)
65uint32_t g_any_key_hit = 0; 92# define LED_MATRIX_STARTUP_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS
93#endif
66 94
67uint32_t eeconfig_read_led_matrix(void) { return eeprom_read_dword(EECONFIG_LED_MATRIX); } 95#if !defined(LED_MATRIX_STARTUP_SPD)
96# define LED_MATRIX_STARTUP_SPD UINT8_MAX / 2
97#endif
68 98
69void eeconfig_update_led_matrix(uint32_t config_value) { eeprom_update_dword(EECONFIG_LED_MATRIX, config_value); } 99// globals
100led_eeconfig_t led_matrix_eeconfig; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr
101uint32_t g_led_timer;
102#ifdef LED_MATRIX_FRAMEBUFFER_EFFECTS
103uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
104#endif // LED_MATRIX_FRAMEBUFFER_EFFECTS
105#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
106last_hit_t g_last_hit_tracker;
107#endif // LED_MATRIX_KEYREACTIVE_ENABLED
108
109// internals
110static bool suspend_state = false;
111static uint8_t led_last_enable = UINT8_MAX;
112static uint8_t led_last_effect = UINT8_MAX;
113static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false};
114static led_task_states led_task_state = SYNCING;
115#if LED_DISABLE_TIMEOUT > 0
116static uint32_t led_anykey_timer;
117#endif // LED_DISABLE_TIMEOUT > 0
118
119// double buffers
120static uint32_t led_timer_buffer;
121#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
122static last_hit_t last_hit_buffer;
123#endif // LED_MATRIX_KEYREACTIVE_ENABLED
124
125// split led matrix
126#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
127const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT;
128#endif
129
130void eeconfig_read_led_matrix(void) { eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }
131
132void eeconfig_update_led_matrix(void) { eeprom_update_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }
70 133
71void eeconfig_update_led_matrix_default(void) { 134void eeconfig_update_led_matrix_default(void) {
72 dprintf("eeconfig_update_led_matrix_default\n"); 135 dprintf("eeconfig_update_led_matrix_default\n");
73 led_matrix_eeconfig.enable = 1; 136 led_matrix_eeconfig.enable = 1;
74 led_matrix_eeconfig.mode = LED_MATRIX_UNIFORM_BRIGHTNESS; 137 led_matrix_eeconfig.mode = LED_MATRIX_STARTUP_MODE;
75 led_matrix_eeconfig.val = 128; 138 led_matrix_eeconfig.val = LED_MATRIX_STARTUP_VAL;
76 led_matrix_eeconfig.speed = 0; 139 led_matrix_eeconfig.speed = LED_MATRIX_STARTUP_SPD;
77 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 140 led_matrix_eeconfig.flags = LED_FLAG_ALL;
141 eeconfig_update_led_matrix();
78} 142}
79 143
80void eeconfig_debug_led_matrix(void) { 144void eeconfig_debug_led_matrix(void) {
81 dprintf("led_matrix_eeconfig eeprom\n"); 145 dprintf("led_matrix_eeconfig EEPROM\n");
82 dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable); 146 dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable);
83 dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode); 147 dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode);
84 dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val); 148 dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val);
85 dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed); 149 dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed);
150 dprintf("led_matrix_eeconfig.flags = %d\n", led_matrix_eeconfig.flags);
86} 151}
87 152
88uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255}; 153__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 154
91uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { 155uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
92 uint8_t led_count = 0; 156 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]; 157 uint8_t led_index = g_led_config.matrix_co[row][column];
94 if (led_index != NO_LED) { 158 if (led_index != NO_LED) {
95 led_i[led_count] = led_index; 159 led_i[led_count] = led_index;
@@ -100,88 +164,235 @@ uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
100 164
101void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); } 165void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); }
102 166
103void led_matrix_set_index_value(int index, uint8_t value) { led_matrix_driver.set_value(index, value); } 167void led_matrix_set_value(int index, uint8_t value) {
104 168#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); } 169 if (!is_keyboard_left() && index >= k_led_matrix_split[0])
106 170# ifdef USE_CIE1931_CURVE
107bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { 171 led_matrix_driver.set_value(index - k_led_matrix_split[0], pgm_read_byte(&CIE1931_CURVE[value]));
108 if (record->event.pressed) { 172# else
109 uint8_t led[8]; 173 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); 174# endif
111 if (led_count > 0) { 175 else if (is_keyboard_left() && index < k_led_matrix_split[0])
112 for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) { 176#endif
113 g_last_led_hit[i - 1] = g_last_led_hit[i - 2]; 177#ifdef USE_CIE1931_CURVE
114 } 178 led_matrix_driver.set_value(index, pgm_read_byte(&CIE1931_CURVE[value]));
115 g_last_led_hit[0] = led[0]; 179#else
116 g_last_led_count = MIN(LED_HITS_TO_REMEMBER, g_last_led_count + 1); 180 led_matrix_driver.set_value(index, value);
117 } 181#endif
118 for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 0; 182}
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 183
126 g_any_key_hit = 255; 184void led_matrix_set_value_all(uint8_t value) {
185#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
186 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) led_matrix_set_value(i, value);
187#else
188# ifdef USE_CIE1931_CURVE
189 led_matrix_driver.set_value_all(pgm_read_byte(&CIE1931_CURVE[value]));
190# else
191 led_matrix_driver.set_value_all(value);
192# endif
127#endif 193#endif
128 }
129 return true;
130} 194}
131 195
132void led_matrix_set_suspend_state(bool state) { g_suspend_state = state; } 196void process_led_matrix(uint8_t row, uint8_t col, bool pressed) {
197#ifndef LED_MATRIX_SPLIT
198 if (!is_keyboard_master()) return;
199#endif
200#if LED_DISABLE_TIMEOUT > 0
201 led_anykey_timer = 0;
202#endif // LED_DISABLE_TIMEOUT > 0
133 203
134// All LEDs off 204#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
135void led_matrix_all_off(void) { led_matrix_set_index_value_all(0); } 205 uint8_t led[LED_HITS_TO_REMEMBER];
206 uint8_t led_count = 0;
136 207
137// Uniform brightness 208# 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); } 209 if (!pressed)
210# elif defined(LED_MATRIX_KEYPRESSES)
211 if (pressed)
212# endif // defined(LED_MATRIX_KEYRELEASES)
213 {
214 led_count = led_matrix_map_row_column_to_led(row, col, led);
215 }
139 216
140void led_matrix_custom(void) {} 217 if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) {
218 memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count);
219 memcpy(&last_hit_buffer.y[0], &last_hit_buffer.y[led_count], LED_HITS_TO_REMEMBER - led_count);
220 memcpy(&last_hit_buffer.tick[0], &last_hit_buffer.tick[led_count], (LED_HITS_TO_REMEMBER - led_count) * 2); // 16 bit
221 memcpy(&last_hit_buffer.index[0], &last_hit_buffer.index[led_count], LED_HITS_TO_REMEMBER - led_count);
222 last_hit_buffer.count--;
223 }
141 224
142void led_matrix_task(void) { 225 for (uint8_t i = 0; i < led_count; i++) {
143 if (!led_matrix_eeconfig.enable) { 226 uint8_t index = last_hit_buffer.count;
144 led_matrix_all_off(); 227 last_hit_buffer.x[index] = g_led_config.point[led[i]].x;
145 led_matrix_indicators(); 228 last_hit_buffer.y[index] = g_led_config.point[led[i]].y;
146 return; 229 last_hit_buffer.index[index] = led[i];
230 last_hit_buffer.tick[index] = 0;
231 last_hit_buffer.count++;
147 } 232 }
233#endif // LED_MATRIX_KEYREACTIVE_ENABLED
148 234
149 g_tick++; 235#if defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_LED_MATRIX_TYPING_HEATMAP)
236 if (led_matrix_eeconfig.mode == LED_MATRIX_TYPING_HEATMAP) {
237 process_led_matrix_typing_heatmap(row, col);
238 }
239#endif // defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_LED_MATRIX_TYPING_HEATMAP)
240}
150 241
151 if (g_any_key_hit < 0xFFFFFFFF) { 242static bool led_matrix_none(effect_params_t *params) {
152 g_any_key_hit++; 243 if (!params->init) {
244 return false;
153 } 245 }
154 246
155 for (int led = 0; led < DRIVER_LED_TOTAL; led++) { 247 led_matrix_set_value_all(0);
156 if (g_key_hit[led] < 255) { 248 return false;
157 if (g_key_hit[led] == 254) g_last_led_count = MAX(g_last_led_count - 1, 0); 249}
158 g_key_hit[led]++; 250
251static void led_task_timers(void) {
252#if defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_DISABLE_TIMEOUT > 0
253 uint32_t deltaTime = sync_timer_elapsed32(led_timer_buffer);
254#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_DISABLE_TIMEOUT > 0
255 led_timer_buffer = sync_timer_read32();
256
257 // Update double buffer timers
258#if LED_DISABLE_TIMEOUT > 0
259 if (led_anykey_timer < UINT32_MAX) {
260 if (UINT32_MAX - deltaTime < led_anykey_timer) {
261 led_anykey_timer = UINT32_MAX;
262 } else {
263 led_anykey_timer += deltaTime;
159 } 264 }
160 } 265 }
266#endif // LED_DISABLE_TIMEOUT > 0
267
268 // Update double buffer last hit timers
269#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
270 uint8_t count = last_hit_buffer.count;
271 for (uint8_t i = 0; i < count; ++i) {
272 if (UINT16_MAX - deltaTime < last_hit_buffer.tick[i]) {
273 last_hit_buffer.count--;
274 continue;
275 }
276 last_hit_buffer.tick[i] += deltaTime;
277 }
278#endif // LED_MATRIX_KEYREACTIVE_ENABLED
279}
161 280
162 // Ideally we would also stop sending zeros to the LED driver PWM buffers 281static void led_task_sync(void) {
163 // while suspended and just do a software shutdown. This is a cheap hack for now. 282 // 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)); 283 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; 284}
285
286static void led_task_start(void) {
287 // reset iter
288 led_effect_params.iter = 0;
289
290 // update double buffers
291 g_led_timer = led_timer_buffer;
292#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
293 g_last_hit_tracker = last_hit_buffer;
294#endif // LED_MATRIX_KEYREACTIVE_ENABLED
295
296 // next task
297 led_task_state = RENDERING;
298}
299
300static void led_task_render(uint8_t effect) {
301 bool rendering = false;
302 led_effect_params.init = (effect != led_last_effect) || (led_matrix_eeconfig.enable != led_last_enable);
303 if (led_effect_params.flags != led_matrix_eeconfig.flags) {
304 led_effect_params.flags = led_matrix_eeconfig.flags;
305 led_matrix_set_value_all(0);
306 }
166 307
167 // this gets ticked at 20 Hz.
168 // each effect can opt to do calculations 308 // each effect can opt to do calculations
169 // and/or request PWM buffer updates. 309 // and/or request PWM buffer updates.
170 switch (effect) { 310 switch (effect) {
171 case LED_MATRIX_UNIFORM_BRIGHTNESS: 311 case LED_MATRIX_NONE:
172 led_matrix_uniform_brightness(); 312 rendering = led_matrix_none(&led_effect_params);
173 break; 313 break;
174 default: 314
175 led_matrix_custom(); 315// ---------------------------------------------
316// -----Begin led effect switch case macros-----
317#define LED_MATRIX_EFFECT(name, ...) \
318 case LED_MATRIX_##name: \
319 rendering = name(&led_effect_params); \
320 break;
321#include "led_matrix_animations/led_matrix_effects.inc"
322#undef LED_MATRIX_EFFECT
323
324#if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER)
325# define LED_MATRIX_EFFECT(name, ...) \
326 case LED_MATRIX_CUSTOM_##name: \
327 rendering = name(&led_effect_params); \
176 break; 328 break;
329# ifdef LED_MATRIX_CUSTOM_KB
330# include "led_matrix_kb.inc"
331# endif
332# ifdef LED_MATRIX_CUSTOM_USER
333# include "led_matrix_user.inc"
334# endif
335# undef LED_MATRIX_EFFECT
336#endif
337 // -----End led effect switch case macros-------
338 // ---------------------------------------------
177 } 339 }
178 340
179 if (!suspend_backlight) { 341 led_effect_params.iter++;
180 led_matrix_indicators(); 342
343 // next task
344 if (!rendering) {
345 led_task_state = FLUSHING;
346 if (!led_effect_params.init && effect == LED_MATRIX_NONE) {
347 // We only need to flush once if we are LED_MATRIX_NONE
348 led_task_state = SYNCING;
349 }
181 } 350 }
351}
352
353static void led_task_flush(uint8_t effect) {
354 // update last trackers after the first full render so we can init over several frames
355 led_last_effect = effect;
356 led_last_enable = led_matrix_eeconfig.enable;
357
358 // update pwm buffers
359 led_matrix_update_pwm_buffers();
182 360
183 // Tell the LED driver to update its state 361 // next task
184 led_matrix_driver.flush(); 362 led_task_state = SYNCING;
363}
364
365void led_matrix_task(void) {
366 led_task_timers();
367
368 // Ideally we would also stop sending zeros to the LED driver PWM buffers
369 // while suspended and just do a software shutdown. This is a cheap hack for now.
370 bool suspend_backlight = suspend_state ||
371#if LED_DISABLE_TIMEOUT > 0
372 (led_anykey_timer > (uint32_t)LED_DISABLE_TIMEOUT) ||
373#endif // LED_DISABLE_TIMEOUT > 0
374 false;
375
376 uint8_t effect = suspend_backlight || !led_matrix_eeconfig.enable ? 0 : led_matrix_eeconfig.mode;
377
378 switch (led_task_state) {
379 case STARTING:
380 led_task_start();
381 break;
382 case RENDERING:
383 led_task_render(effect);
384 if (effect) {
385 led_matrix_indicators();
386 led_matrix_indicators_advanced(&led_effect_params);
387 }
388 break;
389 case FLUSHING:
390 led_task_flush(effect);
391 break;
392 case SYNCING:
393 led_task_sync();
394 break;
395 }
185} 396}
186 397
187void led_matrix_indicators(void) { 398void led_matrix_indicators(void) {
@@ -193,33 +404,42 @@ __attribute__((weak)) void led_matrix_indicators_kb(void) {}
193 404
194__attribute__((weak)) void led_matrix_indicators_user(void) {} 405__attribute__((weak)) void led_matrix_indicators_user(void) {}
195 406
196// void led_matrix_set_indicator_index(uint8_t *index, uint8_t row, uint8_t column) 407void led_matrix_indicators_advanced(effect_params_t *params) {
197// { 408 /* special handling is needed for "params->iter", since it's already been incremented.
198// if (row >= MATRIX_ROWS) 409 * Could move the invocations to led_task_render, but then it's missing a few checks
199// { 410 * and not sure which would be better. Otherwise, this should be called from
200// // Special value, 255=none, 254=all 411 * led_task_render, right before the iter++ line.
201// *index = row; 412 */
202// } 413#if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL
203// else 414 uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * (params->iter - 1);
204// { 415 uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT;
205// // This needs updated to something like 416 if (max > DRIVER_LED_TOTAL) max = DRIVER_LED_TOTAL;
206// // uint8_t led[8]; 417#else
207// // uint8_t led_count = map_row_column_to_led(row, column, led); 418 uint8_t min = 0;
208// // for(uint8_t i = 0; i < led_count; i++) 419 uint8_t max = DRIVER_LED_TOTAL;
209// map_row_column_to_led(row, column, index); 420#endif
210// } 421 led_matrix_indicators_advanced_kb(min, max);
211// } 422 led_matrix_indicators_advanced_user(min, max);
423}
424
425__attribute__((weak)) void led_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) {}
426
427__attribute__((weak)) void led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {}
212 428
213void led_matrix_init(void) { 429void led_matrix_init(void) {
214 led_matrix_driver.init(); 430 led_matrix_driver.init();
215 431
216 // Wait half a second for the driver to finish initializing 432#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
217 wait_ms(500); 433 g_last_hit_tracker.count = 0;
434 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
435 g_last_hit_tracker.tick[i] = UINT16_MAX;
436 }
218 437
219 // clear the key hits 438 last_hit_buffer.count = 0;
220 for (int led = 0; led < DRIVER_LED_TOTAL; led++) { 439 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
221 g_key_hit[led] = 255; 440 last_hit_buffer.tick[i] = UINT16_MAX;
222 } 441 }
442#endif // LED_MATRIX_KEYREACTIVE_ENABLED
223 443
224 if (!eeconfig_is_enabled()) { 444 if (!eeconfig_is_enabled()) {
225 dprintf("led_matrix_init_drivers eeconfig is not enabled.\n"); 445 dprintf("led_matrix_init_drivers eeconfig is not enabled.\n");
@@ -227,122 +447,137 @@ void led_matrix_init(void) {
227 eeconfig_update_led_matrix_default(); 447 eeconfig_update_led_matrix_default();
228 } 448 }
229 449
230 led_matrix_eeconfig.raw = eeconfig_read_led_matrix(); 450 eeconfig_read_led_matrix();
231
232 if (!led_matrix_eeconfig.mode) { 451 if (!led_matrix_eeconfig.mode) {
233 dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n"); 452 dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");
234 eeconfig_update_led_matrix_default(); 453 eeconfig_update_led_matrix_default();
235 led_matrix_eeconfig.raw = eeconfig_read_led_matrix();
236 } 454 }
237
238 eeconfig_debug_led_matrix(); // display current eeprom values 455 eeconfig_debug_led_matrix(); // display current eeprom values
239} 456}
240 457
241// Deals with the messy details of incrementing an integer 458void led_matrix_set_suspend_state(bool state) {
242static uint8_t increment(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { 459#ifdef LED_DISABLE_WHEN_USB_SUSPENDED
243 int16_t new_value = value; 460 if (state) {
244 new_value += step; 461 led_matrix_set_value_all(0); // turn off all LEDs when suspending
245 return MIN(MAX(new_value, min), max); 462 }
463 suspend_state = state;
464#endif
246} 465}
247 466
248static uint8_t decrement(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { 467bool led_matrix_get_suspend_state(void) { return suspend_state; }
249 int16_t new_value = value;
250 new_value -= step;
251 return MIN(MAX(new_value, min), max);
252}
253 468
254// void *backlight_get_custom_key_value_eeprom_address(uint8_t led) { 469void 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; 470 led_matrix_eeconfig.enable ^= 1;
279 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 471 led_task_state = STARTING;
472 if (write_to_eeprom) {
473 eeconfig_update_led_matrix();
474 }
475 dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable);
280} 476}
477void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); }
478void led_matrix_toggle(void) { led_matrix_toggle_eeprom_helper(true); }
281 479
282void led_matrix_enable(void) { 480void led_matrix_enable(void) {
283 led_matrix_eeconfig.enable = 1; 481 led_matrix_enable_noeeprom();
284 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 482 eeconfig_update_led_matrix();
285} 483}
286 484
287void led_matrix_enable_noeeprom(void) { led_matrix_eeconfig.enable = 1; } 485void led_matrix_enable_noeeprom(void) {
486 if (!led_matrix_eeconfig.enable) led_task_state = STARTING;
487 led_matrix_eeconfig.enable = 1;
488}
288 489
289void led_matrix_disable(void) { 490void led_matrix_disable(void) {
491 led_matrix_disable_noeeprom();
492 eeconfig_update_led_matrix();
493}
494
495void led_matrix_disable_noeeprom(void) {
496 if (led_matrix_eeconfig.enable) led_task_state = STARTING;
290 led_matrix_eeconfig.enable = 0; 497 led_matrix_eeconfig.enable = 0;
291 eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
292} 498}
293 499
294void led_matrix_disable_noeeprom(void) { led_matrix_eeconfig.enable = 0; } 500uint8_t led_matrix_is_enabled(void) { return led_matrix_eeconfig.enable; }
295 501
296void led_matrix_step(void) { 502void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
297 led_matrix_eeconfig.mode++; 503 if (!led_matrix_eeconfig.enable) {
298 if (led_matrix_eeconfig.mode >= LED_MATRIX_EFFECT_MAX) { 504 return;
299 led_matrix_eeconfig.mode = 1;
300 } 505 }
301 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 506 if (mode < 1) {
302} 507 led_matrix_eeconfig.mode = 1;
303 508 } 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; 509 led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1;
510 } else {
511 led_matrix_eeconfig.mode = mode;
512 }
513 led_task_state = STARTING;
514 if (write_to_eeprom) {
515 eeconfig_update_led_matrix();
308 } 516 }
309 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 517 dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode);
310} 518}
519void led_matrix_mode_noeeprom(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, false); }
520void led_matrix_mode(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, true); }
311 521
312void led_matrix_increase_val(void) { 522uint8_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 523
317void led_matrix_decrease_val(void) { 524void led_matrix_step_helper(bool write_to_eeprom) {
318 led_matrix_eeconfig.val = decrement(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); 525 uint8_t mode = led_matrix_eeconfig.mode + 1;
319 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 526 led_matrix_mode_eeprom_helper((mode < LED_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom);
320} 527}
528void led_matrix_step_noeeprom(void) { led_matrix_step_helper(false); }
529void led_matrix_step(void) { led_matrix_step_helper(true); }
321 530
322void led_matrix_increase_speed(void) { 531void led_matrix_step_reverse_helper(bool write_to_eeprom) {
323 led_matrix_eeconfig.speed = increment(led_matrix_eeconfig.speed, 1, 0, 3); 532 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 533 led_matrix_mode_eeprom_helper((mode < 1) ? LED_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom);
325} 534}
535void led_matrix_step_reverse_noeeprom(void) { led_matrix_step_reverse_helper(false); }
536void led_matrix_step_reverse(void) { led_matrix_step_reverse_helper(true); }
326 537
327void led_matrix_decrease_speed(void) { 538void 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); 539 if (!led_matrix_eeconfig.enable) {
329 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this 540 return;
541 }
542 led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val;
543 if (write_to_eeprom) {
544 eeconfig_update_led_matrix();
545 }
546 dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val);
330} 547}
548void led_matrix_set_val_noeeprom(uint8_t val) { led_matrix_set_val_eeprom_helper(val, false); }
549void led_matrix_set_val(uint8_t val) { led_matrix_set_val_eeprom_helper(val, true); }
331 550
332void led_matrix_mode(uint8_t mode, bool eeprom_write) { 551uint8_t led_matrix_get_val(void) { return led_matrix_eeconfig.val; }
333 led_matrix_eeconfig.mode = mode; 552
334 if (eeprom_write) { 553void 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); 554void led_matrix_increase_val_noeeprom(void) { led_matrix_increase_val_helper(false); }
555void led_matrix_increase_val(void) { led_matrix_increase_val_helper(true); }
556
557void 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); }
558void led_matrix_decrease_val_noeeprom(void) { led_matrix_decrease_val_helper(false); }
559void led_matrix_decrease_val(void) { led_matrix_decrease_val_helper(true); }
560
561void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
562 led_matrix_eeconfig.speed = speed;
563 if (write_to_eeprom) {
564 eeconfig_update_led_matrix();
336 } 565 }
566 dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed);
337} 567}
568void led_matrix_set_speed_noeeprom(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, false); }
569void led_matrix_set_speed(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, true); }
338 570
339uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; } 571uint8_t led_matrix_get_speed(void) { return led_matrix_eeconfig.speed; }
340 572
341void led_matrix_set_value_noeeprom(uint8_t val) { led_matrix_eeconfig.val = val; } 573void 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); }
574void led_matrix_increase_speed_noeeprom(void) { led_matrix_increase_speed_helper(false); }
575void led_matrix_increase_speed(void) { led_matrix_increase_speed_helper(true); }
342 576
343void led_matrix_set_value(uint8_t val) { 577void 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); 578void led_matrix_decrease_speed_noeeprom(void) { led_matrix_decrease_speed_helper(false); }
345 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 579void led_matrix_decrease_speed(void) { led_matrix_decrease_speed_helper(true); }
346} 580
581led_flags_t led_matrix_get_flags(void) { return led_matrix_eeconfig.flags; }
347 582
348void backlight_set(uint8_t val) { led_matrix_set_value(val); } 583void 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..0984de73b 100644
--- a/quantum/led_matrix.h
+++ b/quantum/led_matrix.h
@@ -19,61 +19,120 @@
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,
30 // All new effects go above this line 55
56// --------------------------------------
57// -----Begin led effect enum macros-----
58#define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_##name,
59#include "led_matrix_animations/led_matrix_effects.inc"
60#undef LED_MATRIX_EFFECT
61
62#if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER)
63# define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_CUSTOM_##name,
64# ifdef LED_MATRIX_CUSTOM_KB
65# include "led_matrix_kb.inc"
66# endif
67# ifdef LED_MATRIX_CUSTOM_USER
68# include "led_matrix_user.inc"
69# endif
70# undef LED_MATRIX_EFFECT
71#endif
72 // --------------------------------------
73 // -----End led effect enum macros-------
74
31 LED_MATRIX_EFFECT_MAX 75 LED_MATRIX_EFFECT_MAX
32}; 76};
33 77
34void led_matrix_set_index_value(int index, uint8_t value); 78void eeconfig_update_led_matrix_default(void);
35void led_matrix_set_index_value_all(uint8_t value); 79void eeconfig_update_led_matrix(void);
80void eeconfig_debug_led_matrix(void);
81
82uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
83uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
84
85void led_matrix_set_value(int index, uint8_t value);
86void led_matrix_set_value_all(uint8_t value);
87
88void process_led_matrix(uint8_t row, uint8_t col, bool pressed);
89
90void led_matrix_task(void);
36 91
37// This runs after another backlight effect and replaces 92// This runs after another backlight effect and replaces
38// colors already set 93// values already set
39void led_matrix_indicators(void); 94void led_matrix_indicators(void);
40void led_matrix_indicators_kb(void); 95void led_matrix_indicators_kb(void);
41void led_matrix_indicators_user(void); 96void led_matrix_indicators_user(void);
42 97
43void led_matrix_init(void); 98void led_matrix_indicators_advanced(effect_params_t *params);
44void led_matrix_setup_drivers(void); 99void led_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max);
45 100void 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 101
49void led_matrix_task(void); 102void led_matrix_init(void);
50 103
51// This should not be called from an interrupt 104void led_matrix_set_suspend_state(bool state);
52// (eg. from a timer interrupt). 105bool led_matrix_get_suspend_state(void);
53// Call this while idle (in between matrix scans). 106void led_matrix_toggle(void);
54// If the buffer is dirty, it will update the driver with the buffer. 107void led_matrix_toggle_noeeprom(void);
55void led_matrix_update_pwm_buffers(void); 108void led_matrix_enable(void);
56 109void led_matrix_enable_noeeprom(void);
57bool process_led_matrix(uint16_t keycode, keyrecord_t *record); 110void led_matrix_disable(void);
58 111void led_matrix_disable_noeeprom(void);
59uint32_t led_matrix_get_tick(void); 112uint8_t led_matrix_is_enabled(void);
60 113void led_matrix_mode(uint8_t mode);
61void led_matrix_toggle(void); 114void led_matrix_mode_noeeprom(uint8_t mode);
62void led_matrix_enable(void); 115uint8_t led_matrix_get_mode(void);
63void led_matrix_enable_noeeprom(void); 116void led_matrix_step(void);
64void led_matrix_disable(void); 117void led_matrix_step_noeeprom(void);
65void led_matrix_disable_noeeprom(void); 118void led_matrix_step_reverse(void);
66void led_matrix_step(void); 119void led_matrix_step_reverse_noeeprom(void);
67void led_matrix_step_reverse(void); 120void led_matrix_set_val(uint8_t val);
68void led_matrix_increase_val(void); 121void led_matrix_set_val_noeeprom(uint8_t val);
69void led_matrix_decrease_val(void); 122uint8_t led_matrix_get_val(void);
70void led_matrix_increase_speed(void); 123void led_matrix_increase_val(void);
71void led_matrix_decrease_speed(void); 124void led_matrix_increase_val_noeeprom(void);
72void led_matrix_mode(uint8_t mode, bool eeprom_write); 125void led_matrix_decrease_val(void);
73void led_matrix_mode_noeeprom(uint8_t mode); 126void led_matrix_decrease_val_noeeprom(void);
74uint8_t led_matrix_get_mode(void); 127void led_matrix_set_speed(uint8_t speed);
75void led_matrix_set_value(uint8_t mode); 128void led_matrix_set_speed_noeeprom(uint8_t speed);
76void led_matrix_set_value_noeeprom(uint8_t mode); 129uint8_t led_matrix_get_speed(void);
130void led_matrix_increase_speed(void);
131void led_matrix_increase_speed_noeeprom(void);
132void led_matrix_decrease_speed(void);
133void led_matrix_decrease_speed_noeeprom(void);
134led_flags_t led_matrix_get_flags(void);
135void led_matrix_set_flags(led_flags_t flags);
77 136
78typedef struct { 137typedef struct {
79 /* Perform any initialisation required for the other driver functions to work. */ 138 /* Perform any initialisation required for the other driver functions to work. */
@@ -91,4 +150,11 @@ extern const led_matrix_driver_t led_matrix_driver;
91 150
92extern led_eeconfig_t led_matrix_eeconfig; 151extern led_eeconfig_t led_matrix_eeconfig;
93 152
153extern uint32_t g_led_timer;
94extern led_config_t g_led_config; 154extern led_config_t g_led_config;
155#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
156extern last_hit_t g_last_hit_tracker;
157#endif
158#ifdef LED_MATRIX_FRAMEBUFFER_EFFECTS
159extern uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS];
160#endif
diff --git a/quantum/led_matrix_animations/alpha_mods_anim.h b/quantum/led_matrix_animations/alpha_mods_anim.h
new file mode 100644
index 000000000..6f69f6892
--- /dev/null
+++ b/quantum/led_matrix_animations/alpha_mods_anim.h
@@ -0,0 +1,24 @@
1#ifndef DISABLE_LED_MATRIX_ALPHAS_MODS
2LED_MATRIX_EFFECT(ALPHAS_MODS)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5// alphas = val1, mods = val2
6bool ALPHAS_MODS(effect_params_t* params) {
7 LED_MATRIX_USE_LIMITS(led_min, led_max);
8
9 uint8_t val1 = led_matrix_eeconfig.val;
10 uint8_t val2 = val1 + led_matrix_eeconfig.speed;
11
12 for (uint8_t i = led_min; i < led_max; i++) {
13 LED_MATRIX_TEST_LED_FLAGS();
14 if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_MODIFIER)) {
15 led_matrix_set_value(i, val2);
16 } else {
17 led_matrix_set_value(i, val1);
18 }
19 }
20 return led_max < DRIVER_LED_TOTAL;
21}
22
23# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
24#endif // DISABLE_LED_MATRIX_ALPHAS_MODS
diff --git a/quantum/led_matrix_animations/band_anim.h b/quantum/led_matrix_animations/band_anim.h
new file mode 100644
index 000000000..523dba1b7
--- /dev/null
+++ b/quantum/led_matrix_animations/band_anim.h
@@ -0,0 +1,13 @@
1#ifndef DISABLE_LED_MATRIX_BAND
2LED_MATRIX_EFFECT(BAND)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t BAND_math(uint8_t val, uint8_t i, uint8_t time) {
6 int16_t v = val - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8;
7 return scale8(v < 0 ? 0 : v, val);
8}
9
10bool BAND(effect_params_t* params) { return effect_runner_i(params, &BAND_math); }
11
12# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
13#endif // DISABLE_LED_MATRIX_BAND
diff --git a/quantum/led_matrix_animations/band_pinwheel_anim.h b/quantum/led_matrix_animations/band_pinwheel_anim.h
new file mode 100644
index 000000000..fb3b835ca
--- /dev/null
+++ b/quantum/led_matrix_animations/band_pinwheel_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_BAND_PINWHEEL
2LED_MATRIX_EFFECT(BAND_PINWHEEL)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t BAND_PINWHEEL_math(uint8_t val, int16_t dx, int16_t dy, uint8_t time) { return scale8(val - time - atan2_8(dy, dx) * 3, val); }
6
7bool BAND_PINWHEEL(effect_params_t* params) { return effect_runner_dx_dy(params, &BAND_PINWHEEL_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_BAND_PINWHEEL
diff --git a/quantum/led_matrix_animations/band_spiral_anim.h b/quantum/led_matrix_animations/band_spiral_anim.h
new file mode 100644
index 000000000..fca22aad9
--- /dev/null
+++ b/quantum/led_matrix_animations/band_spiral_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_BAND_SPIRAL
2LED_MATRIX_EFFECT(BAND_SPIRAL)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t BAND_SPIRAL_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { return scale8(val + dist - time - atan2_8(dy, dx), val); }
6
7bool BAND_SPIRAL(effect_params_t* params) { return effect_runner_dx_dy_dist(params, &BAND_SPIRAL_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_BAND_SPIRAL
diff --git a/quantum/led_matrix_animations/breathing_anim.h b/quantum/led_matrix_animations/breathing_anim.h
new file mode 100644
index 000000000..00310e3f6
--- /dev/null
+++ b/quantum/led_matrix_animations/breathing_anim.h
@@ -0,0 +1,19 @@
1#ifndef DISABLE_LED_MATRIX_BREATHING
2LED_MATRIX_EFFECT(BREATHING)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5bool BREATHING(effect_params_t* params) {
6 LED_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t val = led_matrix_eeconfig.val;
9 uint16_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 8);
10 val = scale8(abs8(sin8(time) - 128) * 2, val);
11 for (uint8_t i = led_min; i < led_max; i++) {
12 LED_MATRIX_TEST_LED_FLAGS();
13 led_matrix_set_value(i, val);
14 }
15 return led_max < DRIVER_LED_TOTAL;
16}
17
18# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
19#endif // DISABLE_LED_MATRIX_BREATHING
diff --git a/quantum/led_matrix_animations/cycle_left_right_anim.h b/quantum/led_matrix_animations/cycle_left_right_anim.h
new file mode 100644
index 000000000..51e81d57c
--- /dev/null
+++ b/quantum/led_matrix_animations/cycle_left_right_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_CYCLE_LEFT_RIGHT
2LED_MATRIX_EFFECT(CYCLE_LEFT_RIGHT)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t CYCLE_LEFT_RIGHT_math(uint8_t val, uint8_t i, uint8_t time) { return scale8(g_led_config.point[i].x - time, val); }
6
7bool CYCLE_LEFT_RIGHT(effect_params_t* params) { return effect_runner_i(params, &CYCLE_LEFT_RIGHT_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_CYCLE_LEFT_RIGHT
diff --git a/quantum/led_matrix_animations/cycle_out_in_anim.h b/quantum/led_matrix_animations/cycle_out_in_anim.h
new file mode 100644
index 000000000..f62061552
--- /dev/null
+++ b/quantum/led_matrix_animations/cycle_out_in_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_CYCLE_OUT_IN
2LED_MATRIX_EFFECT(CYCLE_OUT_IN)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t CYCLE_OUT_IN_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { return scale8(3 * dist / 2 + time, val); }
6
7bool CYCLE_OUT_IN(effect_params_t* params) { return effect_runner_dx_dy_dist(params, &CYCLE_OUT_IN_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_CYCLE_OUT_IN
diff --git a/quantum/led_matrix_animations/cycle_up_down_anim.h b/quantum/led_matrix_animations/cycle_up_down_anim.h
new file mode 100644
index 000000000..bd1d12567
--- /dev/null
+++ b/quantum/led_matrix_animations/cycle_up_down_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_CYCLE_UP_DOWN
2LED_MATRIX_EFFECT(CYCLE_UP_DOWN)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t CYCLE_UP_DOWN_math(uint8_t val, uint8_t i, uint8_t time) { return scale8(g_led_config.point[i].y - time, val); }
6
7bool CYCLE_UP_DOWN(effect_params_t* params) { return effect_runner_i(params, &CYCLE_UP_DOWN_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_CYCLE_UP_DOWN
diff --git a/quantum/led_matrix_animations/dual_beacon_anim.h b/quantum/led_matrix_animations/dual_beacon_anim.h
new file mode 100644
index 000000000..9b8a7877c
--- /dev/null
+++ b/quantum/led_matrix_animations/dual_beacon_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_DUAL_BEACON
2LED_MATRIX_EFFECT(DUAL_BEACON)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t DUAL_BEACON_math(uint8_t val, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { return scale8(((g_led_config.point[i].y - k_led_matrix_center.y) * cos + (g_led_config.point[i].x - k_led_matrix_center.x) * sin) / 128, val); }
6
7bool DUAL_BEACON(effect_params_t* params) { return effect_runner_sin_cos_i(params, &DUAL_BEACON_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_DUAL_BEACON
diff --git a/quantum/led_matrix_animations/led_matrix_effects.inc b/quantum/led_matrix_animations/led_matrix_effects.inc
new file mode 100644
index 000000000..67237c568
--- /dev/null
+++ b/quantum/led_matrix_animations/led_matrix_effects.inc
@@ -0,0 +1,18 @@
1// Add your new core led matrix effect here, order determins enum order, requires "led_matrix_animations/ directory
2#include "led_matrix_animations/solid_anim.h"
3#include "led_matrix_animations/alpha_mods_anim.h"
4#include "led_matrix_animations/breathing_anim.h"
5#include "led_matrix_animations/band_anim.h"
6#include "led_matrix_animations/band_pinwheel_anim.h"
7#include "led_matrix_animations/band_spiral_anim.h"
8#include "led_matrix_animations/cycle_left_right_anim.h"
9#include "led_matrix_animations/cycle_up_down_anim.h"
10#include "led_matrix_animations/cycle_out_in_anim.h"
11#include "led_matrix_animations/dual_beacon_anim.h"
12#include "led_matrix_animations/solid_reactive_simple_anim.h"
13#include "led_matrix_animations/solid_reactive_wide.h"
14#include "led_matrix_animations/solid_reactive_cross.h"
15#include "led_matrix_animations/solid_reactive_nexus.h"
16#include "led_matrix_animations/solid_splash_anim.h"
17#include "led_matrix_animations/wave_left_right_anim.h"
18#include "led_matrix_animations/wave_up_down_anim.h"
diff --git a/quantum/led_matrix_animations/solid_anim.h b/quantum/led_matrix_animations/solid_anim.h
new file mode 100644
index 000000000..4c9e43c58
--- /dev/null
+++ b/quantum/led_matrix_animations/solid_anim.h
@@ -0,0 +1,15 @@
1LED_MATRIX_EFFECT(SOLID)
2#ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
3
4bool SOLID(effect_params_t* params) {
5 LED_MATRIX_USE_LIMITS(led_min, led_max);
6
7 uint8_t val = led_matrix_eeconfig.val;
8 for (uint8_t i = led_min; i < led_max; i++) {
9 LED_MATRIX_TEST_LED_FLAGS();
10 led_matrix_set_value(i, val);
11 }
12 return led_max < DRIVER_LED_TOTAL;
13}
14
15#endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/led_matrix_animations/solid_reactive_cross.h b/quantum/led_matrix_animations/solid_reactive_cross.h
new file mode 100644
index 000000000..f402d99b3
--- /dev/null
+++ b/quantum/led_matrix_animations/solid_reactive_cross.h
@@ -0,0 +1,35 @@
1#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_CROSS) || !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS)
3
4# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_CROSS
5LED_MATRIX_EFFECT(SOLID_REACTIVE_CROSS)
6# endif
7
8# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS
9LED_MATRIX_EFFECT(SOLID_REACTIVE_MULTICROSS)
10# endif
11
12# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
13
14static uint8_t SOLID_REACTIVE_CROSS_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick + dist;
16 dx = dx < 0 ? dx * -1 : dx;
17 dy = dy < 0 ? dy * -1 : dy;
18 dx = dx * 16 > 255 ? 255 : dx * 16;
19 dy = dy * 16 > 255 ? 255 : dy * 16;
20 effect += dx > dy ? dy : dx;
21 if (effect > 255) effect = 255;
22 return qadd8(val, 255 - effect);
23}
24
25# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_CROSS
26bool SOLID_REACTIVE_CROSS(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_CROSS_math); }
27# endif
28
29# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS
30bool SOLID_REACTIVE_MULTICROSS(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_CROSS_math); }
31# endif
32
33# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
34# endif // !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_CROSS) || !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS)
35#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_animations/solid_reactive_nexus.h b/quantum/led_matrix_animations/solid_reactive_nexus.h
new file mode 100644
index 000000000..4d0d25226
--- /dev/null
+++ b/quantum/led_matrix_animations/solid_reactive_nexus.h
@@ -0,0 +1,32 @@
1#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS)
3
4# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS
5LED_MATRIX_EFFECT(SOLID_REACTIVE_NEXUS)
6# endif
7
8# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS
9LED_MATRIX_EFFECT(SOLID_REACTIVE_MULTINEXUS)
10# endif
11
12# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
13
14static uint8_t SOLID_REACTIVE_NEXUS_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick - dist;
16 if (effect > 255) effect = 255;
17 if (dist > 72) effect = 255;
18 if ((dx > 8 || dx < -8) && (dy > 8 || dy < -8)) effect = 255;
19 return qadd8(val, 255 - effect);
20}
21
22# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS
23bool SOLID_REACTIVE_NEXUS(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_NEXUS_math); }
24# endif
25
26# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS
27bool SOLID_REACTIVE_MULTINEXUS(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_NEXUS_math); }
28# endif
29
30# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
31# endif // !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS)
32#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_animations/solid_reactive_simple_anim.h b/quantum/led_matrix_animations/solid_reactive_simple_anim.h
new file mode 100644
index 000000000..30e2527f6
--- /dev/null
+++ b/quantum/led_matrix_animations/solid_reactive_simple_anim.h
@@ -0,0 +1,12 @@
1#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
2# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE
3LED_MATRIX_EFFECT(SOLID_REACTIVE_SIMPLE)
4# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
5
6static uint8_t SOLID_REACTIVE_SIMPLE_math(uint8_t val, uint16_t offset) { return scale8(255 - offset, val); }
7
8bool SOLID_REACTIVE_SIMPLE(effect_params_t* params) { return effect_runner_reactive(params, &SOLID_REACTIVE_SIMPLE_math); }
9
10# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
11# endif // DISABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE
12#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_animations/solid_reactive_wide.h b/quantum/led_matrix_animations/solid_reactive_wide.h
new file mode 100644
index 000000000..34a230c25
--- /dev/null
+++ b/quantum/led_matrix_animations/solid_reactive_wide.h
@@ -0,0 +1,30 @@
1#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_WIDE) || !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE)
3
4# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_WIDE
5LED_MATRIX_EFFECT(SOLID_REACTIVE_WIDE)
6# endif
7
8# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE
9LED_MATRIX_EFFECT(SOLID_REACTIVE_MULTIWIDE)
10# endif
11
12# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
13
14static uint8_t SOLID_REACTIVE_WIDE_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick + dist * 5;
16 if (effect > 255) effect = 255;
17 return qadd8(val, 255 - effect);
18}
19
20# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_WIDE
21bool SOLID_REACTIVE_WIDE(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_WIDE_math); }
22# endif
23
24# ifndef DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE
25bool SOLID_REACTIVE_MULTIWIDE(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_WIDE_math); }
26# endif
27
28# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
29# endif // !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_WIDE) || !defined(DISABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE)
30#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_animations/solid_splash_anim.h b/quantum/led_matrix_animations/solid_splash_anim.h
new file mode 100644
index 000000000..4f6ba3d34
--- /dev/null
+++ b/quantum/led_matrix_animations/solid_splash_anim.h
@@ -0,0 +1,30 @@
1#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
2# if !defined(DISABLE_LED_MATRIX_SOLID_SPLASH) || !defined(DISABLE_LED_MATRIX_SOLID_MULTISPLASH)
3
4# ifndef DISABLE_LED_MATRIX_SOLID_SPLASH
5LED_MATRIX_EFFECT(SOLID_SPLASH)
6# endif
7
8# ifndef DISABLE_LED_MATRIX_SOLID_MULTISPLASH
9LED_MATRIX_EFFECT(SOLID_MULTISPLASH)
10# endif
11
12# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
13
14uint8_t SOLID_SPLASH_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) {
15 uint16_t effect = tick - dist;
16 if (effect > 255) effect = 255;
17 return qadd8(val, 255 - effect);
18}
19
20# ifndef DISABLE_LED_MATRIX_SOLID_SPLASH
21bool SOLID_SPLASH(effect_params_t* params) { return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_SPLASH_math); }
22# endif
23
24# ifndef DISABLE_LED_MATRIX_SOLID_MULTISPLASH
25bool SOLID_MULTISPLASH(effect_params_t* params) { return effect_runner_reactive_splash(0, params, &SOLID_SPLASH_math); }
26# endif
27
28# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
29# endif // !defined(DISABLE_LED_MATRIX_SPLASH) && !defined(DISABLE_LED_MATRIX_MULTISPLASH)
30#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_animations/wave_left_right_anim.h b/quantum/led_matrix_animations/wave_left_right_anim.h
new file mode 100644
index 000000000..736f22ddc
--- /dev/null
+++ b/quantum/led_matrix_animations/wave_left_right_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_WAVE_LEFT_RIGHT
2LED_MATRIX_EFFECT(WAVE_LEFT_RIGHT)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t WAVE_LEFT_RIGHT_math(uint8_t val, uint8_t i, uint8_t time) { return scale8(sin8(g_led_config.point[i].x - time), val); }
6
7bool WAVE_LEFT_RIGHT(effect_params_t* params) { return effect_runner_i(params, &WAVE_LEFT_RIGHT_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_WAVE_LEFT_RIGHT
diff --git a/quantum/led_matrix_animations/wave_up_down_anim.h b/quantum/led_matrix_animations/wave_up_down_anim.h
new file mode 100644
index 000000000..3cab0597d
--- /dev/null
+++ b/quantum/led_matrix_animations/wave_up_down_anim.h
@@ -0,0 +1,10 @@
1#ifndef DISABLE_LED_MATRIX_WAVE_UP_DOWN
2LED_MATRIX_EFFECT(WAVE_UP_DOWN)
3# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
4
5static uint8_t WAVE_UP_DOWN_math(uint8_t val, uint8_t i, uint8_t time) { return scale8(sin8(g_led_config.point[i].y - time), val); }
6
7bool WAVE_UP_DOWN(effect_params_t* params) { return effect_runner_i(params, &WAVE_UP_DOWN_math); }
8
9# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS
10#endif // DISABLE_LED_MATRIX_WAVE_UP_DOWN
diff --git a/quantum/led_matrix_drivers.c b/quantum/led_matrix_drivers.c
index eddf3f286..1d46b2c50 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) {
@@ -53,16 +46,28 @@ static void init(void) {
53# endif 46# endif
54# else 47# else
55# ifdef LED_DRIVER_ADDR_1 48# ifdef LED_DRIVER_ADDR_1
56 IS31FL3733_init(LED_DRIVER_ADDR_1, 0); 49# ifndef LED_DRIVER_SYNC_1
50# define LED_DRIVER_SYNC_1 0
51# endif
52 IS31FL3733_init(LED_DRIVER_ADDR_1, LED_DRIVER_SYNC_1);
57# endif 53# endif
58# ifdef LED_DRIVER_ADDR_2 54# ifdef LED_DRIVER_ADDR_2
59 IS31FL3733_init(LED_DRIVER_ADDR_2, 0); 55# ifndef LED_DRIVER_SYNC_2
56# define LED_DRIVER_SYNC_2 0
57# endif
58 IS31FL3733_init(LED_DRIVER_ADDR_2, LED_DRIVER_SYNC_2);
60# endif 59# endif
61# ifdef LED_DRIVER_ADDR_3 60# ifdef LED_DRIVER_ADDR_3
62 IS31FL3733_init(LED_DRIVER_ADDR_3, 0); 61# ifndef LED_DRIVER_SYNC_3
62# define LED_DRIVER_SYNC_3 0
63# endif
64 IS31FL3733_init(LED_DRIVER_ADDR_3, LED_DRIVER_SYNC_3);
63# endif 65# endif
64# ifdef LED_DRIVER_ADDR_4 66# ifdef LED_DRIVER_ADDR_4
65 IS31FL3733_init(LED_DRIVER_ADDR_4, 0); 67# ifndef LED_DRIVER_SYNC_4
68# define LED_DRIVER_SYNC_4 0
69# endif
70 IS31FL3733_init(LED_DRIVER_ADDR_4, LED_DRIVER_SYNC_4);
66# endif 71# endif
67# endif 72# endif
68 73
diff --git a/quantum/led_matrix_runners/effect_runner_dx_dy.h b/quantum/led_matrix_runners/effect_runner_dx_dy.h
new file mode 100644
index 000000000..ef97631b9
--- /dev/null
+++ b/quantum/led_matrix_runners/effect_runner_dx_dy.h
@@ -0,0 +1,16 @@
1#pragma once
2
3typedef uint8_t (*dx_dy_f)(uint8_t val, int16_t dx, int16_t dy, uint8_t time);
4
5bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {
6 LED_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 2);
9 for (uint8_t i = led_min; i < led_max; i++) {
10 LED_MATRIX_TEST_LED_FLAGS();
11 int16_t dx = g_led_config.point[i].x - k_led_matrix_center.x;
12 int16_t dy = g_led_config.point[i].y - k_led_matrix_center.y;
13 led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, dx, dy, time));
14 }
15 return led_max < DRIVER_LED_TOTAL;
16}
diff --git a/quantum/led_matrix_runners/effect_runner_dx_dy_dist.h b/quantum/led_matrix_runners/effect_runner_dx_dy_dist.h
new file mode 100644
index 000000000..5ef5938be
--- /dev/null
+++ b/quantum/led_matrix_runners/effect_runner_dx_dy_dist.h
@@ -0,0 +1,17 @@
1#pragma once
2
3typedef uint8_t (*dx_dy_dist_f)(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint8_t time);
4
5bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) {
6 LED_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 2);
9 for (uint8_t i = led_min; i < led_max; i++) {
10 LED_MATRIX_TEST_LED_FLAGS();
11 int16_t dx = g_led_config.point[i].x - k_led_matrix_center.x;
12 int16_t dy = g_led_config.point[i].y - k_led_matrix_center.y;
13 uint8_t dist = sqrt16(dx * dx + dy * dy);
14 led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, dx, dy, dist, time));
15 }
16 return led_max < DRIVER_LED_TOTAL;
17}
diff --git a/quantum/led_matrix_runners/effect_runner_i.h b/quantum/led_matrix_runners/effect_runner_i.h
new file mode 100644
index 000000000..b3015759b
--- /dev/null
+++ b/quantum/led_matrix_runners/effect_runner_i.h
@@ -0,0 +1,14 @@
1#pragma once
2
3typedef uint8_t (*i_f)(uint8_t val, uint8_t i, uint8_t time);
4
5bool effect_runner_i(effect_params_t* params, i_f effect_func) {
6 LED_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint8_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 4);
9 for (uint8_t i = led_min; i < led_max; i++) {
10 LED_MATRIX_TEST_LED_FLAGS();
11 led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, i, time));
12 }
13 return led_max < DRIVER_LED_TOTAL;
14}
diff --git a/quantum/led_matrix_runners/effect_runner_reactive.h b/quantum/led_matrix_runners/effect_runner_reactive.h
new file mode 100644
index 000000000..4369ea8c4
--- /dev/null
+++ b/quantum/led_matrix_runners/effect_runner_reactive.h
@@ -0,0 +1,28 @@
1#pragma once
2
3#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
4
5typedef uint8_t (*reactive_f)(uint8_t val, uint16_t offset);
6
7bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) {
8 LED_MATRIX_USE_LIMITS(led_min, led_max);
9
10 uint16_t max_tick = 65535 / led_matrix_eeconfig.speed;
11 for (uint8_t i = led_min; i < led_max; i++) {
12 LED_MATRIX_TEST_LED_FLAGS();
13 uint16_t tick = max_tick;
14 // Reverse search to find most recent key hit
15 for (int8_t j = g_last_hit_tracker.count - 1; j >= 0; j--) {
16 if (g_last_hit_tracker.index[j] == i && g_last_hit_tracker.tick[j] < tick) {
17 tick = g_last_hit_tracker.tick[j];
18 break;
19 }
20 }
21
22 uint16_t offset = scale16by8(tick, led_matrix_eeconfig.speed);
23 led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, offset));
24 }
25 return led_max < DRIVER_LED_TOTAL;
26}
27
28#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_runners/effect_runner_reactive_splash.h b/quantum/led_matrix_runners/effect_runner_reactive_splash.h
new file mode 100644
index 000000000..d6eb9731e
--- /dev/null
+++ b/quantum/led_matrix_runners/effect_runner_reactive_splash.h
@@ -0,0 +1,26 @@
1#pragma once
2
3#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
4
5typedef uint8_t (*reactive_splash_f)(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick);
6
7bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, reactive_splash_f effect_func) {
8 LED_MATRIX_USE_LIMITS(led_min, led_max);
9
10 uint8_t count = g_last_hit_tracker.count;
11 for (uint8_t i = led_min; i < led_max; i++) {
12 LED_MATRIX_TEST_LED_FLAGS();
13 uint8_t val = 0;
14 for (uint8_t j = start; j < count; j++) {
15 int16_t dx = g_led_config.point[i].x - g_last_hit_tracker.x[j];
16 int16_t dy = g_led_config.point[i].y - g_last_hit_tracker.y[j];
17 uint8_t dist = sqrt16(dx * dx + dy * dy);
18 uint16_t tick = scale16by8(g_last_hit_tracker.tick[j], led_matrix_eeconfig.speed);
19 val = effect_func(val, dx, dy, dist, tick);
20 }
21 led_matrix_set_value(i, scale8(val, led_matrix_eeconfig.val));
22 }
23 return led_max < DRIVER_LED_TOTAL;
24}
25
26#endif // LED_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/led_matrix_runners/effect_runner_sin_cos_i.h b/quantum/led_matrix_runners/effect_runner_sin_cos_i.h
new file mode 100644
index 000000000..4a5219abd
--- /dev/null
+++ b/quantum/led_matrix_runners/effect_runner_sin_cos_i.h
@@ -0,0 +1,16 @@
1#pragma once
2
3typedef uint8_t (*sin_cos_i_f)(uint8_t val, int8_t sin, int8_t cos, uint8_t i, uint8_t time);
4
5bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {
6 LED_MATRIX_USE_LIMITS(led_min, led_max);
7
8 uint16_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 4);
9 int8_t cos_value = cos8(time) - 128;
10 int8_t sin_value = sin8(time) - 128;
11 for (uint8_t i = led_min; i < led_max; i++) {
12 LED_MATRIX_TEST_LED_FLAGS();
13 led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, cos_value, sin_value, i, time));
14 }
15 return led_max < DRIVER_LED_TOTAL;
16}
diff --git a/quantum/led_matrix_types.h b/quantum/led_matrix_types.h
index 669b67042..61cdbd9b8 100644
--- a/quantum/led_matrix_types.h
+++ b/quantum/led_matrix_types.h
@@ -29,15 +29,42 @@
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} led_point_t;
65
66#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
67#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00)
41 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
@@ -48,19 +75,20 @@ typedef struct PACKED {
48#define NO_LED 255 75#define NO_LED 255
49 76
50typedef struct PACKED { 77typedef struct PACKED {
51 uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS]; 78 uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS];
52 point_t point[DRIVER_LED_TOTAL]; 79 led_point_t point[DRIVER_LED_TOTAL];
53 uint8_t flags[DRIVER_LED_TOTAL]; 80 uint8_t flags[DRIVER_LED_TOTAL];
54} led_config_t; 81} led_config_t;
55 82
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.c b/quantum/matrix.c
index c027b7bf2..34d6af2e6 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -116,9 +116,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
116 116
117 // Unselect row 117 // Unselect row
118 unselect_row(current_row); 118 unselect_row(current_row);
119 if (current_row + 1 < MATRIX_ROWS) { 119 matrix_output_unselect_delay(); // wait for all Col signals to go HIGH
120 matrix_output_unselect_delay(); // wait for row signal to go HIGH
121 }
122 120
123 // If the row has changed, store the row and return the changed flag. 121 // If the row has changed, store the row and return the changed flag.
124 if (current_matrix[current_row] != current_row_value) { 122 if (current_matrix[current_row] != current_row_value) {
@@ -178,9 +176,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
178 176
179 // Unselect col 177 // Unselect col
180 unselect_col(current_col); 178 unselect_col(current_col);
181 if (current_col + 1 < MATRIX_COLS) { 179 matrix_output_unselect_delay(); // wait for all Row signals to go HIGH
182 matrix_output_unselect_delay(); // wait for col signal to go HIGH
183 }
184 180
185 return matrix_changed; 181 return matrix_changed;
186} 182}
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..9268c4522 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,47 @@ 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
436endif
437
438ifneq (,$(filter $(MCU),STM32L433 STM32L443))
439 # Cortex version
440 MCU = cortex-m4
441
442 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
443 ARMV = 7
444
445 ## chip/board settings
446 # - the next two should match the directories in
447 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
448 MCU_FAMILY = STM32
449 MCU_SERIES = STM32L4xx
450
451 # Linker script to use
452 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
453 # or <keyboard_dir>/ld/
454 MCU_LDSCRIPT ?= STM32L432xC
455
456 # Startup code to use
457 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
458 MCU_STARTUP ?= stm32l4xx
459
460 # Board: it should exist either in <chibios>/os/hal/boards/,
461 # <keyboard_dir>/boards/, or drivers/boards/
462 BOARD ?= GENERIC_STM32_L433XC
463
464 PLATFORM_NAME ?= platform_l432
465
466 USE_FPU ?= yes
467
468 # Options to pass to dfu-util when flashing
469 DFU_ARGS ?= -d 0483:DF11 -a 0 -s 0x08000000:leave
470 DFU_SUFFIX_ARGS ?= -v 0483 -p DF11
471
472 # UF2 settings
473 UF2_FAMILY ?= STM32L4
346endif 474endif
347 475
348ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287)) 476ifneq (,$(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..f3fe14a43 100644
--- a/quantum/process_keycode/process_leader.h
+++ b/quantum/process_keycode/process_leader.h
@@ -35,4 +35,9 @@ 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
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..e4a7c5723 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,37 +200,8 @@ 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#ifdef ENCODER_ENABLE
203#if defined(__AVR__) 204# include "encoder.h"
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 205#endif
234 206
235// For tri-layer 207// For tri-layer
@@ -256,15 +228,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record);
256void post_process_record_kb(uint16_t keycode, keyrecord_t *record); 228void post_process_record_kb(uint16_t keycode, keyrecord_t *record);
257void post_process_record_user(uint16_t keycode, keyrecord_t *record); 229void post_process_record_user(uint16_t keycode, keyrecord_t *record);
258 230
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); 231void reset_keyboard(void);
269 232
270void startup_user(void); 233void startup_user(void);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index e49f8dcda..316c20fce 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
@@ -822,12 +760,12 @@ enum quantum_keycodes {
822#define CMD_T(kc) LCMD_T(kc) 760#define CMD_T(kc) LCMD_T(kc)
823#define WIN_T(kc) LWIN_T(kc) 761#define WIN_T(kc) LWIN_T(kc)
824 762
825#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Left Control + Shift e.g. for gnome-terminal 763#define C_S_T(kc) MT(MOD_LCTL | MOD_LSFT, kc) // Left Control + Shift e.g. for gnome-terminal
826#define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc) // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt 764#define MEH_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT, kc) // Meh is a less hyper version of the Hyper key -- doesn't include GUI, so just Left Control + Shift + Alt
827#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left Control + Alt + GUI 765#define LCAG_T(kc) MT(MOD_LCTL | MOD_LALT | MOD_LGUI, kc) // Left Control + Alt + GUI
828#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right Control + Alt + GUI 766#define RCAG_T(kc) MT(MOD_RCTL | MOD_RALT | MOD_RGUI, kc) // Right Control + Alt + GUI
829#define HYPR_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ 767#define HYPR_T(kc) MT(MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
830#define SGUI_T(kc) MT(MOD_LGUI | MOD_LSFT, kc) // Left Shift + GUI 768#define SGUI_T(kc) MT(MOD_LGUI | MOD_LSFT, kc) // Left Shift + GUI
831#define SCMD_T(kc) SGUI_T(kc) 769#define SCMD_T(kc) SGUI_T(kc)
832#define SWIN_T(kc) SGUI_T(kc) 770#define SWIN_T(kc) SGUI_T(kc)
833#define LCA_T(kc) MT(MOD_LCTL | MOD_LALT, kc) // Left Control + Alt 771#define LCA_T(kc) MT(MOD_LCTL | MOD_LALT, kc) // Left Control + Alt
@@ -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
@@ -853,12 +792,13 @@ enum quantum_keycodes {
853 792
854#define UC_M_MA UNICODE_MODE_MAC 793#define UC_M_MA UNICODE_MODE_MAC
855#define UNICODE_MODE_OSX UNICODE_MODE_MAC // Deprecated alias 794#define UNICODE_MODE_OSX UNICODE_MODE_MAC // Deprecated alias
856#define UC_M_OS UNICODE_MODE_MAC // Deprecated alias 795#define UC_M_OS UNICODE_MODE_MAC // Deprecated alias
857#define UC_M_LN UNICODE_MODE_LNX 796#define UC_M_LN UNICODE_MODE_LNX
858#define UC_M_WI UNICODE_MODE_WIN 797#define UC_M_WI UNICODE_MODE_WIN
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..e716c6aad 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -26,9 +26,9 @@
26#include <lib/lib8tion/lib8tion.h> 26#include <lib/lib8tion/lib8tion.h>
27 27
28#ifndef RGB_MATRIX_CENTER 28#ifndef RGB_MATRIX_CENTER
29const point_t k_rgb_matrix_center = {112, 32}; 29const led_point_t k_rgb_matrix_center = {112, 32};
30#else 30#else
31const point_t k_rgb_matrix_center = RGB_MATRIX_CENTER; 31const led_point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;
32#endif 32#endif
33 33
34__attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); } 34__attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); }
@@ -67,8 +67,8 @@ __attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv
67# define RGB_DISABLE_TIMEOUT 0 67# define RGB_DISABLE_TIMEOUT 0
68#endif 68#endif
69 69
70#ifndef RGB_DISABLE_WHEN_USB_SUSPENDED 70#if RGB_DISABLE_WHEN_USB_SUSPENDED == false
71# define RGB_DISABLE_WHEN_USB_SUSPENDED false 71# undef RGB_DISABLE_WHEN_USB_SUSPENDED
72#endif 72#endif
73 73
74#if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX 74#if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX
@@ -118,7 +118,6 @@ __attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv
118#endif 118#endif
119 119
120// globals 120// globals
121bool g_suspend_state = false;
122rgb_config_t rgb_matrix_config; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr 121rgb_config_t rgb_matrix_config; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr
123uint32_t g_rgb_timer; 122uint32_t g_rgb_timer;
124#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS 123#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
@@ -129,9 +128,10 @@ last_hit_t g_last_hit_tracker;
129#endif // RGB_MATRIX_KEYREACTIVE_ENABLED 128#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
130 129
131// internals 130// internals
131static bool suspend_state = false;
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.
@@ -385,14 +409,11 @@ void rgb_matrix_task(void) {
385 409
386 // Ideally we would also stop sending zeros to the LED driver PWM buffers 410 // Ideally we would also stop sending zeros to the LED driver PWM buffers
387 // while suspended and just do a software shutdown. This is a cheap hack for now. 411 // while suspended and just do a software shutdown. This is a cheap hack for now.
388 bool suspend_backlight = 412 bool suspend_backlight = suspend_state ||
389#if RGB_DISABLE_WHEN_USB_SUSPENDED == true
390 g_suspend_state ||
391#endif // RGB_DISABLE_WHEN_USB_SUSPENDED == true
392#if RGB_DISABLE_TIMEOUT > 0 413#if RGB_DISABLE_TIMEOUT > 0
393 (rgb_anykey_timer > (uint32_t)RGB_DISABLE_TIMEOUT) || 414 (rgb_anykey_timer > (uint32_t)RGB_DISABLE_TIMEOUT) ||
394#endif // RGB_DISABLE_TIMEOUT > 0 415#endif // RGB_DISABLE_TIMEOUT > 0
395 false; 416 false;
396 417
397 uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode; 418 uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode;
398 419
@@ -477,13 +498,15 @@ void rgb_matrix_init(void) {
477} 498}
478 499
479void rgb_matrix_set_suspend_state(bool state) { 500void rgb_matrix_set_suspend_state(bool state) {
480 if (RGB_DISABLE_WHEN_USB_SUSPENDED && state) { 501#ifdef RGB_DISABLE_WHEN_USB_SUSPENDED
502 if (state) {
481 rgb_matrix_set_color_all(0, 0, 0); // turn off all LEDs when suspending 503 rgb_matrix_set_color_all(0, 0, 0); // turn off all LEDs when suspending
482 } 504 }
483 g_suspend_state = state; 505 suspend_state = state;
506#endif
484} 507}
485 508
486bool rgb_matrix_get_suspend_state(void) { return g_suspend_state; } 509bool rgb_matrix_get_suspend_state(void) { return suspend_state; }
487 510
488void rgb_matrix_toggle_eeprom_helper(bool write_to_eeprom) { 511void rgb_matrix_toggle_eeprom_helper(bool write_to_eeprom) {
489 rgb_matrix_config.enable ^= 1; 512 rgb_matrix_config.enable ^= 1;
@@ -618,6 +641,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); } 641void rgb_matrix_decrease_speed_noeeprom(void) { rgb_matrix_decrease_speed_helper(false); }
619void rgb_matrix_decrease_speed(void) { rgb_matrix_decrease_speed_helper(true); } 642void rgb_matrix_decrease_speed(void) { rgb_matrix_decrease_speed_helper(true); }
620 643
621led_flags_t rgb_matrix_get_flags(void) { return rgb_effect_params.flags; } 644led_flags_t rgb_matrix_get_flags(void) { return rgb_matrix_config.flags; }
622 645
623void rgb_matrix_set_flags(led_flags_t flags) { rgb_effect_params.flags = flags; } 646void rgb_matrix_set_flags(led_flags_t flags) { rgb_matrix_config.flags = flags; }
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index bb8bcfab6..a615b8422 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -216,7 +216,6 @@ extern const rgb_matrix_driver_t rgb_matrix_driver;
216 216
217extern rgb_config_t rgb_matrix_config; 217extern rgb_config_t rgb_matrix_config;
218 218
219extern bool g_suspend_state;
220extern uint32_t g_rgb_timer; 219extern uint32_t g_rgb_timer;
221extern led_config_t g_led_config; 220extern led_config_t g_led_config;
222#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 221#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c
index 2978e7bed..896fa6d0e 100644
--- a/quantum/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix_drivers.c
@@ -41,7 +41,28 @@ static void init(void) {
41 IS31FL3731_init(DRIVER_ADDR_4); 41 IS31FL3731_init(DRIVER_ADDR_4);
42# endif 42# endif
43# elif defined(IS31FL3733) 43# elif defined(IS31FL3733)
44 IS31FL3733_init(DRIVER_ADDR_1, 0); 44# ifndef DRIVER_SYNC_1
45# define DRIVER_SYNC_1 0
46# endif
47 IS31FL3733_init(DRIVER_ADDR_1, DRIVER_SYNC_1);
48# if defined DRIVER_ADDR_2 && (DRIVER_ADDR_1 != DRIVER_ADDR_2)
49# ifndef DRIVER_SYNC_2
50# define DRIVER_SYNC_2 0
51# endif
52 IS31FL3733_init(DRIVER_ADDR_2, DRIVER_SYNC_2);
53# endif
54# ifdef DRIVER_ADDR_3
55# ifndef DRIVER_SYNC_3
56# define DRIVER_SYNC_3 0
57# endif
58 IS31FL3733_init(DRIVER_ADDR_3, DRIVER_SYNC_3);
59# endif
60# ifdef DRIVER_ADDR_4
61# ifndef DRIVER_SYNC_4
62# define DRIVER_SYNC_4 0
63# endif
64 IS31FL3733_init(DRIVER_ADDR_4, DRIVER_SYNC_4);
65# endif
45# elif defined(IS31FL3737) 66# elif defined(IS31FL3737)
46 IS31FL3737_init(DRIVER_ADDR_1); 67 IS31FL3737_init(DRIVER_ADDR_1);
47# else 68# else
@@ -74,7 +95,15 @@ static void init(void) {
74# endif 95# endif
75# elif defined(IS31FL3733) 96# elif defined(IS31FL3733)
76 IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0); 97 IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0);
98# ifdef DRIVER_ADDR_2
77 IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1); 99 IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1);
100# endif
101# ifdef DRIVER_ADDR_3
102 IS31FL3733_update_led_control_registers(DRIVER_ADDR_3, 2);
103# endif
104# ifdef DRIVER_ADDR_4
105 IS31FL3733_update_led_control_registers(DRIVER_ADDR_4, 3);
106# endif
78# elif defined(IS31FL3737) 107# elif defined(IS31FL3737)
79 IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, DRIVER_ADDR_2); 108 IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, DRIVER_ADDR_2);
80# else 109# else
@@ -105,7 +134,15 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
105# elif defined(IS31FL3733) 134# elif defined(IS31FL3733)
106static void flush(void) { 135static void flush(void) {
107 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0); 136 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0);
137# ifdef DRIVER_ADDR_2
108 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1); 138 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1);
139# endif
140# ifdef DRIVER_ADDR_3
141 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_3, 2);
142# endif
143# ifdef DRIVER_ADDR_4
144 IS31FL3733_update_pwm_buffers(DRIVER_ADDR_4, 3);
145# endif
109} 146}
110 147
111const rgb_matrix_driver_t rgb_matrix_driver = { 148const rgb_matrix_driver_t rgb_matrix_driver = {
diff --git a/quantum/rgb_matrix_types.h b/quantum/rgb_matrix_types.h
index 7b8171fb2..df575d657 100644
--- a/quantum/rgb_matrix_types.h
+++ b/quantum/rgb_matrix_types.h
@@ -62,7 +62,7 @@ typedef struct PACKED {
62typedef struct PACKED { 62typedef struct PACKED {
63 uint8_t x; 63 uint8_t x;
64 uint8_t y; 64 uint8_t y;
65} point_t; 65} led_point_t;
66 66
67#define HAS_FLAGS(bits, flags) ((bits & flags) == flags) 67#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
68#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00) 68#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00)
@@ -77,18 +77,19 @@ typedef struct PACKED {
77#define NO_LED 255 77#define NO_LED 255
78 78
79typedef struct PACKED { 79typedef struct PACKED {
80 uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS]; 80 uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS];
81 point_t point[DRIVER_LED_TOTAL]; 81 led_point_t point[DRIVER_LED_TOTAL];
82 uint8_t flags[DRIVER_LED_TOTAL]; 82 uint8_t flags[DRIVER_LED_TOTAL];
83} led_config_t; 83} led_config_t;
84 84
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/rgblight.c b/quantum/rgblight.c
index 119d3eab2..baa10ec41 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -722,23 +722,39 @@ static void rgblight_layers_write(void) {
722} 722}
723 723
724# ifdef RGBLIGHT_LAYER_BLINK 724# ifdef RGBLIGHT_LAYER_BLINK
725rgblight_layer_mask_t _blinked_layer_mask = 0; 725rgblight_layer_mask_t _blinking_layer_mask = 0;
726static uint16_t _blink_timer; 726static uint16_t _repeat_timer;
727static uint8_t _times_remaining;
728static uint16_t _dur;
729
730void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) { rgblight_blink_layer_repeat(layer, duration_ms, 1); }
731
732void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times) {
733 _times_remaining = times * 2;
734 _dur = duration_ms;
727 735
728void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) {
729 rgblight_set_layer_state(layer, true); 736 rgblight_set_layer_state(layer, true);
730 _blinked_layer_mask |= (rgblight_layer_mask_t)1 << layer; 737 _times_remaining--;
731 _blink_timer = sync_timer_read() + duration_ms; 738 _blinking_layer_mask |= (rgblight_layer_mask_t)1 << layer;
739 _repeat_timer = sync_timer_read() + duration_ms;
732} 740}
733 741
734void rgblight_unblink_layers(void) { 742void rgblight_blink_layer_repeat_helper(void) {
735 if (_blinked_layer_mask != 0 && timer_expired(sync_timer_read(), _blink_timer)) { 743 if (_blinking_layer_mask != 0 && timer_expired(sync_timer_read(), _repeat_timer)) {
736 for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) { 744 for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) {
737 if ((_blinked_layer_mask & (rgblight_layer_mask_t)1 << layer) != 0) { 745 if ((_blinking_layer_mask & (rgblight_layer_mask_t)1 << layer) != 0 && _times_remaining > 0) {
738 rgblight_set_layer_state(layer, false); 746 if (_times_remaining % 2 == 1) {
747 rgblight_set_layer_state(layer, false);
748 } else {
749 rgblight_set_layer_state(layer, true);
750 }
751 _times_remaining--;
752 _repeat_timer = sync_timer_read() + _dur;
739 } 753 }
740 } 754 }
741 _blinked_layer_mask = 0; 755 if (_times_remaining <= 0) {
756 _blinking_layer_mask = 0;
757 }
742 } 758 }
743} 759}
744# endif 760# endif
@@ -755,8 +771,8 @@ void rgblight_suspend(void) {
755 771
756# ifdef RGBLIGHT_LAYER_BLINK 772# ifdef RGBLIGHT_LAYER_BLINK
757 // make sure any layer blinks don't come back after suspend 773 // make sure any layer blinks don't come back after suspend
758 rgblight_status.enabled_layer_mask &= ~_blinked_layer_mask; 774 rgblight_status.enabled_layer_mask &= ~_blinking_layer_mask;
759 _blinked_layer_mask = 0; 775 _blinking_layer_mask = 0;
760# endif 776# endif
761 777
762 rgblight_disable_noeeprom(); 778 rgblight_disable_noeeprom();
@@ -874,7 +890,7 @@ void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) {
874 animation_status.restart = true; 890 animation_status.restart = true;
875 } 891 }
876# endif /* RGBLIGHT_SPLIT_NO_ANIMATION_SYNC */ 892# endif /* RGBLIGHT_SPLIT_NO_ANIMATION_SYNC */
877# endif /* RGBLIGHT_USE_TIMER */ 893# endif /* RGBLIGHT_USE_TIMER */
878} 894}
879#endif /* RGBLIGHT_SPLIT */ 895#endif /* RGBLIGHT_SPLIT */
880 896
@@ -1030,7 +1046,7 @@ void rgblight_task(void) {
1030 } 1046 }
1031 1047
1032# ifdef RGBLIGHT_LAYER_BLINK 1048# ifdef RGBLIGHT_LAYER_BLINK
1033 rgblight_unblink_layers(); 1049 rgblight_blink_layer_repeat_helper();
1034# endif 1050# endif
1035} 1051}
1036 1052
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 6fb3ab938..bec2c6695 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -222,6 +222,7 @@ extern const rgblight_segment_t *const *rgblight_layers;
222# ifdef RGBLIGHT_LAYER_BLINK 222# ifdef RGBLIGHT_LAYER_BLINK
223# define RGBLIGHT_USE_TIMER 223# define RGBLIGHT_USE_TIMER
224void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms); 224void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms);
225void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times);
225# endif 226# endif
226 227
227# endif 228# endif
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index d6636b886..039e7d977 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) {
@@ -129,9 +130,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
129 130
130 // Unselect row 131 // Unselect row
131 unselect_row(current_row); 132 unselect_row(current_row);
132 if (current_row + 1 < MATRIX_ROWS) { 133 matrix_output_unselect_delay(); // wait for all Col signals to go HIGH
133 matrix_output_unselect_delay(); // wait for row signal to go HIGH
134 }
135 134
136 // If the row has changed, store the row and return the changed flag. 135 // If the row has changed, store the row and return the changed flag.
137 if (current_matrix[current_row] != current_row_value) { 136 if (current_matrix[current_row] != current_row_value) {
@@ -191,9 +190,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
191 190
192 // Unselect col 191 // Unselect col
193 unselect_col(current_col); 192 unselect_col(current_col);
194 if (current_col + 1 < MATRIX_COLS) { 193 matrix_output_unselect_delay(); // wait for all Row signals to go HIGH
195 matrix_output_unselect_delay(); // wait for col signal to go HIGH
196 }
197 194
198 return matrix_changed; 195 return matrix_changed;
199} 196}
@@ -284,7 +281,7 @@ bool matrix_post_scan(void) {
284 } else { 281 } else {
285 transport_slave(matrix + thatHand, matrix + thisHand); 282 transport_slave(matrix + thatHand, matrix + thisHand);
286 283
287 matrix_slave_scan_user(); 284 matrix_slave_scan_kb();
288 } 285 }
289 286
290 return changed; 287 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..9ed0f7591 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,17 @@ 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 bool suspend_state = led_matrix_get_suspend_state();
166 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT);
167# endif
168# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
169 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT);
170 bool suspend_state = rgb_matrix_get_suspend_state();
171 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT);
172# endif
173
144# ifndef DISABLE_SYNC_TIMER 174# ifndef DISABLE_SYNC_TIMER
145 i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; 175 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); 176 i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT);
@@ -186,6 +216,15 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
186 set_oneshot_mods(i2c_buffer->oneshot_mods); 216 set_oneshot_mods(i2c_buffer->oneshot_mods);
187# endif 217# endif
188# endif 218# endif
219
220# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
221 memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix));
222 led_matrix_set_suspend_state(i2c_buffer->led_suspend_state);
223# endif
224# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
225 memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix));
226 rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state);
227# endif
189} 228}
190 229
191void transport_master_init(void) { i2c_init(); } 230void transport_master_init(void) { i2c_init(); }
@@ -201,30 +240,38 @@ typedef struct _Serial_s2m_buffer_t {
201 matrix_row_t smatrix[ROWS_PER_HAND]; 240 matrix_row_t smatrix[ROWS_PER_HAND];
202 241
203# ifdef ENCODER_ENABLE 242# ifdef ENCODER_ENABLE
204 uint8_t encoder_state[NUMBER_OF_ENCODERS]; 243 uint8_t encoder_state[NUMBER_OF_ENCODERS];
205# endif 244# endif
206 245
207} Serial_s2m_buffer_t; 246} Serial_s2m_buffer_t;
208 247
209typedef struct _Serial_m2s_buffer_t { 248typedef struct _Serial_m2s_buffer_t {
210# ifdef SPLIT_MODS_ENABLE 249# ifdef SPLIT_MODS_ENABLE
211 uint8_t real_mods; 250 uint8_t real_mods;
212 uint8_t weak_mods; 251 uint8_t weak_mods;
213# ifndef NO_ACTION_ONESHOT 252# ifndef NO_ACTION_ONESHOT
214 uint8_t oneshot_mods; 253 uint8_t oneshot_mods;
215# endif 254# endif
216# endif 255# endif
217# ifndef DISABLE_SYNC_TIMER 256# ifndef DISABLE_SYNC_TIMER
218 uint32_t sync_timer; 257 uint32_t sync_timer;
219# endif 258# endif
220# ifdef SPLIT_TRANSPORT_MIRROR 259# ifdef SPLIT_TRANSPORT_MIRROR
221 matrix_row_t mmatrix[ROWS_PER_HAND]; 260 matrix_row_t mmatrix[ROWS_PER_HAND];
222# endif 261# endif
223# ifdef BACKLIGHT_ENABLE 262# ifdef BACKLIGHT_ENABLE
224 uint8_t backlight_level; 263 uint8_t backlight_level;
225# endif 264# endif
226# ifdef WPM_ENABLE 265# ifdef WPM_ENABLE
227 uint8_t current_wpm; 266 uint8_t current_wpm;
267# endif
268# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
269 led_eeconfig_t led_matrix;
270 bool led_suspend_state;
271# endif
272# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
273 rgb_config_t rgb_matrix;
274 bool rgb_suspend_state;
228# endif 275# endif
229} Serial_m2s_buffer_t; 276} Serial_m2s_buffer_t;
230 277
@@ -316,7 +363,7 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
316 363
317 // TODO: if MATRIX_COLS > 8 change to unpack() 364 // TODO: if MATRIX_COLS > 8 change to unpack()
318 for (int i = 0; i < ROWS_PER_HAND; ++i) { 365 for (int i = 0; i < ROWS_PER_HAND; ++i) {
319 slave_matrix[i] = serial_s2m_buffer.smatrix[i]; 366 slave_matrix[i] = serial_s2m_buffer.smatrix[i];
320# ifdef SPLIT_TRANSPORT_MIRROR 367# ifdef SPLIT_TRANSPORT_MIRROR
321 serial_m2s_buffer.mmatrix[i] = master_matrix[i]; 368 serial_m2s_buffer.mmatrix[i] = master_matrix[i];
322# endif 369# endif
@@ -333,18 +380,28 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
333 380
334# ifdef WPM_ENABLE 381# ifdef WPM_ENABLE
335 // Write wpm to slave 382 // Write wpm to slave
336 serial_m2s_buffer.current_wpm = get_current_wpm(); 383 serial_m2s_buffer.current_wpm = get_current_wpm();
337# endif 384# endif
338 385
339# ifdef SPLIT_MODS_ENABLE 386# ifdef SPLIT_MODS_ENABLE
340 serial_m2s_buffer.real_mods = get_mods(); 387 serial_m2s_buffer.real_mods = get_mods();
341 serial_m2s_buffer.weak_mods = get_weak_mods(); 388 serial_m2s_buffer.weak_mods = get_weak_mods();
342# ifndef NO_ACTION_ONESHOT 389# ifndef NO_ACTION_ONESHOT
343 serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); 390 serial_m2s_buffer.oneshot_mods = get_oneshot_mods();
344# endif 391# endif
345# endif 392# endif
393
394# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
395 serial_m2s_buffer.led_matrix = led_matrix_eeconfig;
396 serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state();
397# endif
398# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
399 serial_m2s_buffer.rgb_matrix = rgb_matrix_config;
400 serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state();
401# endif
402
346# ifndef DISABLE_SYNC_TIMER 403# ifndef DISABLE_SYNC_TIMER
347 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; 404 serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET;
348# endif 405# endif
349 return true; 406 return true;
350} 407}
@@ -359,7 +416,7 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
359 for (int i = 0; i < ROWS_PER_HAND; ++i) { 416 for (int i = 0; i < ROWS_PER_HAND; ++i) {
360 serial_s2m_buffer.smatrix[i] = slave_matrix[i]; 417 serial_s2m_buffer.smatrix[i] = slave_matrix[i];
361# ifdef SPLIT_TRANSPORT_MIRROR 418# ifdef SPLIT_TRANSPORT_MIRROR
362 master_matrix[i] = serial_m2s_buffer.mmatrix[i]; 419 master_matrix[i] = serial_m2s_buffer.mmatrix[i];
363# endif 420# endif
364 } 421 }
365# ifdef BACKLIGHT_ENABLE 422# ifdef BACKLIGHT_ENABLE
@@ -381,6 +438,15 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])
381 set_oneshot_mods(serial_m2s_buffer.oneshot_mods); 438 set_oneshot_mods(serial_m2s_buffer.oneshot_mods);
382# endif 439# endif
383# endif 440# endif
441
442# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT)
443 led_matrix_eeconfig = serial_m2s_buffer.led_matrix;
444 led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state);
445# endif
446# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT)
447 rgb_matrix_config = serial_m2s_buffer.rgb_matrix;
448 rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state);
449# endif
384} 450}
385 451
386#endif 452#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);