aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/audio/audio.h3
-rw-r--r--quantum/audio/audio_avr.c5
-rw-r--r--quantum/keymap_extras/keymap_belgian.h2
-rw-r--r--quantum/keymap_extras/keymap_canadian_multilingual.h646
-rw-r--r--quantum/keymap_extras/keymap_neo2.h180
-rw-r--r--quantum/keymap_extras/sendstring_canadian_multilingual.h100
-rw-r--r--quantum/matrix.c41
-rw-r--r--quantum/process_keycode/process_rgb.c2
-rw-r--r--quantum/process_keycode/process_unicode_common.c118
-rw-r--r--quantum/process_keycode/process_unicode_common.h2
-rw-r--r--quantum/process_keycode/process_unicodemap.c3
-rw-r--r--quantum/quantum.c3
-rw-r--r--quantum/quantum_keycodes.h1
-rw-r--r--quantum/rgb_matrix.c117
-rw-r--r--quantum/rgb_matrix.h21
-rw-r--r--quantum/rgb_matrix_animations/breathing_anim.h2
-rw-r--r--quantum/rgb_matrix_animations/digital_rain_anim.h24
-rw-r--r--quantum/rgb_matrix_animations/jellybean_raindrops_anim.h2
-rw-r--r--quantum/rgb_matrix_animations/raindrops_anim.h2
-rw-r--r--quantum/rgb_matrix_animations/typing_heatmap_anim.h28
-rw-r--r--quantum/rgb_matrix_runners/effect_runner_dx_dy.h2
-rw-r--r--quantum/rgb_matrix_runners/effect_runner_dx_dy_dist.h2
-rw-r--r--quantum/rgb_matrix_runners/effect_runner_i.h2
-rw-r--r--quantum/rgb_matrix_runners/effect_runner_sin_cos_i.h2
-rw-r--r--quantum/rgb_matrix_types.h7
-rw-r--r--quantum/rgblight.c125
-rw-r--r--quantum/rgblight.h45
-rw-r--r--quantum/rgblight_modes.h8
-rw-r--r--quantum/split_common/matrix.c41
-rw-r--r--quantum/split_common/split_util.c65
-rw-r--r--quantum/stm32/halconf.h4
-rw-r--r--quantum/template/ps2avrgb/rules.mk2
32 files changed, 1099 insertions, 508 deletions
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 2bcc27b4a..805cb4f7a 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -99,9 +99,6 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat);
99// length. This works around the limitation of C's sizeof operation on pointers. 99// length. This works around the limitation of C's sizeof operation on pointers.
100// The global float array for the song must be used here. 100// The global float array for the song must be used here.
101#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) 101#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0]))))
102#define PLAY_NOTE_ARRAY(note_array, note_repeat, deprecated_arg) \
103 play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat)); \
104 _Pragma("message \"'PLAY_NOTE_ARRAY' macro is deprecated\"")
105#define PLAY_SONG(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), false) 102#define PLAY_SONG(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), false)
106#define PLAY_LOOP(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), true) 103#define PLAY_LOOP(note_array) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), true)
107 104
diff --git a/quantum/audio/audio_avr.c b/quantum/audio/audio_avr.c
index 781378788..5a96bf643 100644
--- a/quantum/audio/audio_avr.c
+++ b/quantum/audio/audio_avr.c
@@ -110,6 +110,11 @@
110# define TIMER_1_DUTY_CYCLE OCR1C 110# define TIMER_1_DUTY_CYCLE OCR1C
111# define TIMER1_AUDIO_vect TIMER1_COMPC_vect 111# define TIMER1_AUDIO_vect TIMER1_COMPC_vect
112#endif 112#endif
113
114#if !defined(BPIN_AUDIO) && !defined(CPIN_AUDIO)
115# error "Audio feature enabled, but no suitable pin selected - see docs/feature_audio.md under the AVR settings for available options."
116#endif
117
113// ----------------------------------------------------------------------------- 118// -----------------------------------------------------------------------------
114 119
115int voices = 0; 120int voices = 0;
diff --git a/quantum/keymap_extras/keymap_belgian.h b/quantum/keymap_extras/keymap_belgian.h
index c6363a437..b65db0532 100644
--- a/quantum/keymap_extras/keymap_belgian.h
+++ b/quantum/keymap_extras/keymap_belgian.h
@@ -67,7 +67,7 @@
67#define BE_F KC_F // F 67#define BE_F KC_F // F
68#define BE_G KC_G // G 68#define BE_G KC_G // G
69#define BE_H KC_H // H 69#define BE_H KC_H // H
70#define BE_J KC_K // J 70#define BE_J KC_J // J
71#define BE_K KC_K // K 71#define BE_K KC_K // K
72#define BE_L KC_L // L 72#define BE_L KC_L // L
73#define BE_M KC_SCLN // M 73#define BE_M KC_SCLN // M
diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h
index 4fc174e73..d980dc2e4 100644
--- a/quantum/keymap_extras/keymap_canadian_multilingual.h
+++ b/quantum/keymap_extras/keymap_canadian_multilingual.h
@@ -1,4 +1,4 @@
1/* Copyright 2016 Didier Loiseau 1/* Copyright 2020
2 * 2 *
3 * This program is free software: you can redistribute it and/or modify 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 4 * it under the terms of the GNU General Public License as published by
@@ -13,247 +13,421 @@
13 * You should have received a copy of the GNU General Public License 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/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifndef KEYMAP_CANADIAN_MULTILINGUAL_H
17#define KEYMAP_CANADIAN_MULTILINGUAL_H
18 16
19#include "keymap.h" 17#pragma once
20
21#ifndef GR2A
22# define GR2A(kc) RCTL(kc)
23#endif
24
25// Normal characters
26// First row
27#define CSA_SLASH KC_GRV // /
28#define CSA_SLSH CSA_SLASH
29
30// Second row
31#define CSA_DEAD_CIRCUMFLEX KC_LBRACKET // dead ^
32#define CSA_DCRC CSA_DEAD_CIRCUMFLEX
33#define CSA_C_CEDILLA KC_RBRACKET // Ç
34#define CSA_CCED CSA_C_CEDILLA
35
36// Third row
37#define CSA_E_GRAVE KC_QUOT // è
38#define CSA_EGRV CSA_E_GRAVE
39#define CSA_A_GRAVE KC_BSLASH // à
40#define CSA_AGRV CSA_A_GRAVE
41
42// Fourth row
43#define CSA_U_GRAVE KC_NONUS_BSLASH // ù
44#define CSA_UGRV CSA_U_GRAVE
45#define CSA_E_ACUTE KC_SLSH // é
46#define CSA_ECUT CSA_E_ACUTE
47
48// Shifted characters
49// First row
50#define CSA_BACKSLASH LSFT(CSA_SLASH) /* \ */
51#define CSA_BSLS CSA_BACKSLASH
52#define CSA_QUESTION LSFT(KC_6) // ?
53#define CSA_QEST CSA_QUESTION
54
55// Second row
56#define CSA_DEAD_TREMA LSFT(CSA_DEAD_CIRCUMFLEX) // dead trema/umlaut/diaresis for ä ë ï ö ü
57#define CSA_DTRM CSA_DEAD_TREMA
58
59// Third row
60// all same as US-QWERTY, or capitalised character of the non-shifted key
61
62// Fourth row
63#define CSA_APOSTROPHE LSFT(KC_COMMA) // '
64#define CSA_APOS CSA_APOSTROPHE
65#define CSA_DOUBLE_QUOTE LSFT(KC_DOT) // "
66#define CSA_DQOT CSA_DOUBLE_QUOTE
67
68// Alt Gr-ed characters
69// First row
70#define CSA_PIPE ALGR(CSA_SLASH) // |
71#define CSA_CURRENCY ALGR(KC_4) // ¤
72#define CSA_CURR CSA_CURRENCY
73#define CSA_LEFT_CURLY_BRACE ALGR(KC_7) // {
74#define CSA_LCBR CSA_LEFT_CURLY_BRACE
75#define CSA_RIGHT_CURLY_BRACE ALGR(KC_8) // }
76#define CSA_RCBR CSA_RIGHT_CURLY_BRACE
77#define CSA_LBRACKET ALGR(KC_9) // [
78#define CSA_LBRC CSA_LBRACKET
79#define CSA_RBRACKET ALGR(KC_0) // ]
80#define CSA_RBRC CSA_RBRACKET
81#define CSA_NEGATION ALGR(KC_EQUAL) // ¬
82#define CSA_NEGT CSA_NEGATION
83 18
84// Second row 19#include "keymap.h"
85// euro symbol not available on Linux? (X.org)
86#define CSA_EURO ALGR(KC_E) // €
87#define CSA_DEAD_GRAVE ALGR(CSA_DEAD_CIRCUMFLEX)
88#define CSA_DGRV CSA_DEAD_GRAVE // dead `
89#define CSA_DEAD_TILDE ALGR(CSA_C_CEDILLA) // ~
90#define CSA_DTLD CSA_DEAD_TILDE
91
92// Third row
93#define CSA_DEGREE ALGR(KC_SCOLON) // °
94#define CSA_DEGR CSA_DEGREE
95
96// Fourth row
97#define CSA_LEFT_GUILLEMET ALGR(KC_Z) // «
98#define CSA_LGIL CSA_LEFT_GUILLEMET
99#define CSA_RIGHT_GUILLEMET ALGR(KC_X) // »
100#define CSA_RGIL CSA_RIGHT_GUILLEMET
101#define CSA_LESS ALGR(KC_COMMA) // <
102#define CSA_GREATER ALGR(KC_DOT) // >
103#define CSA_GRTR CSA_GREATER
104
105// Space bar
106#define CSA_NON_BREAKING_SPACE ALGR(KC_SPACE)
107#define CSA_NBSP CSA_NON_BREAKING_SPACE
108
109// GR2A-ed characters
110// First row
111#define CSA_SUPERSCRIPT_ONE GR2A(KC_1) // ¹
112#define CSA_SUP1 CSA_SUPERSCRIPT_ONE
113#define CSA_SUPERSCRIPT_TWO GR2A(KC_2) // ²
114#define CSA_SUP2 CSA_SUPERSCRIPT_TWO
115#define CSA_SUPERSCRIPT_THREE GR2A(KC_3) // ³
116#define CSA_SUP3 CSA_SUPERSCRIPT_THREE
117#define CSA_ONE_QUARTER GR2A(KC_4) // ¼
118#define CSA_1QRT CSA_ONE_QUARTER
119#define CSA_ONE_HALF GR2A(KC_5) // ½
120#define CSA_1HLF CSA_ONE_HALF
121#define CSA_THREE_QUARTERS GR2A(KC_6) // ¾
122#define CSA_3QRT CSA_THREE_QUARTERS
123// nothing on 7-0 and -
124#define CSA_DEAD_CEDILLA GR2A(KC_EQUAL) // dead ¸
125#define CSA_DCED CSA_DEAD_CEDILLA
126
127// Second row
128#define CSA_OMEGA GR2A(KC_Q) // ω
129#define CSA_OMEG CSA_OMEGA
130#define CSA_L_STROKE GR2A(KC_W) // ł
131#define CSA_LSTK CSA_L_STROKE
132#define CSA_OE_LIGATURE GR2A(KC_E) // œ
133#define CSA_OE CSA_OE_LIGATURE
134#define CSA_PARAGRAPH GR2A(KC_R) // ¶
135#define CSA_PARG CSA_PARAGRAPH
136#define CSA_T_STROKE GR2A(KC_T) // ŧ
137#define CSA_LEFT_ARROW GR2A(KC_Y) // ←
138#define CSA_LARW CSA_LEFT_ARROW
139#define CSA_DOWN_ARROW GR2A(KC_U) // ↓
140#define CSA_DARW CSA_DOWN_ARROW
141#define CSA_RIGHT_ARROW GR2A(KC_I) // →
142#define CSA_RARW CSA_RIGHT_ARROW
143#define CSA_O_STROKE GR2A(KC_O) // ø
144#define CSA_OSTK CSA_O_STROKE
145#define CSA_THORN GR2A(KC_P) // þ
146#define CSA_THRN CSA_THORN
147// nothing on ^
148#define CSA_TILDE GR2A(CSA_C_CEDILLA) // dead ~
149#define CSA_TILD CSA_TILDE
150 20
151// Third row 21// clang-format off
152#define CSA_AE_LIGATURE GR2A(KC_A) // æ
153#define CSA_AE CSA_AE_LIGATURE
154#define CSA_SHARP_S GR2A(KC_S) // ß
155#define CSA_SRPS CSA_SHARP_S
156#define CSA_ETH GR2A(KC_D) // ð
157// nothing on F
158#define CSA_ENG GR2A(KC_G) // ŋ
159#define CSA_H_SRTOKE GR2A(KC_H) // ħ
160#define CSA_HSTK CSA_H_SRTOKE
161#define CSA_IJ_LIGATURE GR2A(KC_J) // ij
162#define CSA_IJ CSA_IJ_LIGATURE
163#define CSA_KRA GR2A(KC_K) // ĸ
164#define CSA_L_FLOWN_DOT GR2A(KC_L) // ŀ
165#define CSA_LFLD CSA_L_FLOWN_DOT
166#define CSA_DEAD_ACUTE GR2A(KC_SCLN) // dead acute accent
167#define CSA_DACT CSA_DEAD_ACUTE
168// nothing on È & À
169 22
170// Fourth row 23/*
171#define CSA_CENT GR2A(KC_C) // ¢ 24 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
172#define CSA_LEFT_DOUBLE_QUOTE GR2A(KC_V) // “ 25 * │ / │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │       │
173#define CSA_LDQT CSA_LEFT_DOUBLE_QUOTE 26 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
174#define CSA_RIGHT_DOUBLE_QUOTE GR2A(KC_B) // ” 27 * │     │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ ^ │ Ç │     │
175#define CSA_RDQT CSA_RIGHT_DOUBLE_QUOTE 28 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
176#define CSA_N_APOSTROPHE GR2A(KC_N) // ʼn (deprecated unicode codepoint) 29 * │      │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ È │ À │    │
177#define CSA_NAPO CSA_N_APOSTROPHE 30 * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
178#define CSA_MU GR2A(KC_M) // μ 31 * │    │ Ù │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ É │          │
179#define CSA_HORIZONTAL_BAR GR2A(KC_COMMA) // ― 32 * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
180#define CSA_HZBR CSA_HORIZONTAL_BAR 33 * │    │    │    │                        │    │    │    │    │
181#define CSA_DEAD_DOT_ABOVE GR2A(KC_DOT) // dead ˙ 34 * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
182#define CSA_DDTA CSA_DEAD_DOT_ABOVE 35 */
36// Row 1
37#define CA_SLSH KC_GRV // /
38#define CA_1 KC_1 // 1
39#define CA_2 KC_2 // 2
40#define CA_3 KC_3 // 3
41#define CA_4 KC_4 // 4
42#define CA_5 KC_5 // 5
43#define CA_6 KC_6 // 6
44#define CA_7 KC_7 // 7
45#define CA_8 KC_8 // 8
46#define CA_9 KC_9 // 9
47#define CA_0 KC_0 // 0
48#define CA_MINS KC_MINS // -
49#define CA_EQL KC_EQL // =
50// Row 2
51#define CA_Q KC_Q // Q
52#define CA_W KC_W // W
53#define CA_E KC_E // E
54#define CA_R KC_R // R
55#define CA_T KC_T // T
56#define CA_Y KC_Y // Y
57#define CA_U KC_U // U
58#define CA_I KC_I // I
59#define CA_O KC_O // O
60#define CA_P KC_P // P
61#define CA_CIRC KC_LBRC // ^ (dead)
62#define CA_CCED KC_RBRC // Ç
63// Row 3
64#define CA_A KC_A // A
65#define CA_S KC_S // S
66#define CA_D KC_D // D
67#define CA_F KC_F // F
68#define CA_G KC_G // G
69#define CA_H KC_H // H
70#define CA_J KC_J // J
71#define CA_K KC_K // K
72#define CA_L KC_L // L
73#define CA_SCLN KC_SCLN // ;
74#define CA_EGRV KC_QUOT // É
75#define CA_AGRV KC_NUHS // À
76// Row 4
77#define CA_UGRV KC_NUBS // Ù
78#define CA_Z KC_Z // Z
79#define CA_X KC_X // X
80#define CA_C KC_C // C
81#define CA_V KC_V // V
82#define CA_B KC_B // B
83#define CA_N KC_N // N
84#define CA_M KC_M // M
85#define CA_COMM KC_COMM // ,
86#define CA_DOT KC_DOT // .
87#define CA_EACU KC_SLSH // É
183 88
184// GR2A-shifted characters (different from capitalised GR2A-ed characters) 89/* Shifted symbols
185// First row 90 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
186#define CSA_SOFT_HYPHEN GR2A(LSFT(CSA_SLASH)) // soft-hyphen, appears as a hyphen in wrapped word 91 * │ \ │ ! │ @ │ # │ $ │ % │ ? │ & │ * │ ( │ ) │ _ │ + │       │
187#define CSA_SHYP CSA_SOFT_HYPHEN 92 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
188#define CSA_INVERTED_EXCLAIM GR2A(KC_EXCLAIM) // ¡ 93 * │     │   │   │   │   │   │   │   │   │   │   │ ¨ │   │     │
189#define CSA_IXLM CSA_INVERTED_EXCLAIM 94 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
190// nothing on 2 95 * │      │   │   │   │   │   │   │   │   │   │ : │   │   │    │
191#define CSA_POUND GR2A(LSFT(KC_3)) // £ 96 * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
192#define CSA_GBP CSA_POUND_SIGN 97 * │    │   │   │   │   │   │   │   │   │ ' │ " │   │          │
193// already on ALGR(KC_E) 98 * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
194#define CSA_EURO_BIS GR2A(LSFT(KC_4)) // € 99 * │    │    │    │                        │    │    │    │    │
195#define CSA_EURB CSA_EURO_BIS 100 * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
196#define CSA_THREE_EIGHTHS GR2A(LSFT(KC_5)) // ⅜ 101 */
197#define CSA_3ON8 CSA_THREE_EIGHTHS 102// Row 1
198#define CSA_FIVE_EIGHTHS GR2A(LSFT(KC_6)) // ⅝ 103#define CA_BSLS S(CA_SLSH) // (backslash)
199#define CSA_5ON8 CSA_FIVE_EIGHTHS 104#define CA_EXLM S(CA_1) // !
200#define CSA_SEVEN_EIGHTHS GR2A(LSFT(KC_7)) // ⅞ 105#define CA_AT S(CA_2) // @
201#define CSA_7ON8 CSA_SEVEN_EIGHTHS 106#define CA_HASH S(CA_3) // #
202#define CSA_TRADEMARK GR2A(LSFT(KC_8)) // ™ 107#define CA_DLR S(CA_4) // $
203#define CSA_TM CSA_TRADEMARK 108#define CA_PERC S(CA_5) // %
204#define CSA_PLUS_MINUS GR2A(LSFT(KC_9)) // ± 109#define CA_QUES S(CA_6) // ?
205#define CSA_PSMS CSA_PLUS_MINUS 110#define CA_AMPR S(CA_7) // &
206// nothing on 0 111#define CA_ASTR S(CA_8) // *
207#define CSA_INVERTED_QUESTION GR2A(LSFT(KC_MINUS)) // ¿ 112#define CA_LPRN S(CA_9) // (
208#define CSA_IQST CSA_INVERTED_QUESTION 113#define CA_RPRN S(CA_0) // )
209#define CSA_DEAD_OGONEK GR2A(LSFT(KC_EQUAL)) // dead ˛ 114#define CA_UNDS S(CA_MINS) // _
210#define CSA_DOGO CSA_DEAD_OGONEK 115#define CA_PLUS S(CA_EQL) // +
116// Row 2
117#define CA_DIAE S(CA_CIRC) // ¨ (dead)
118// Row 3
119#define CA_COLN S(CA_SCLN) // :
120// Row 4
121#define CA_QUOT S(CA_COMM) // '
122#define CA_DQUO S(CA_DOT) // "
211 123
212// Second row 124/* AltGr symbols
213#define CSA_REGISTERED_TRADEMARK GR2A(LSFT(KC_R)) // ® 125 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
214#define CSA_RTM CSA_REGISTERED_TRADEMARK 126 * │ | │   │   │   │ ¤ │   │   │ { │ } │ [ │ ] │   │ ¬ │       │
215#define CSA_YEN GR2A(LSFT(KC_Y)) // ¥ 127 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
216#define CSA_YUAN CSA_YEN 128 * │     │   │   │ € │   │   │   │   │   │   │   │ ` │ ~ │     │
217#define CSA_UP_ARROW LSFT(CSA_DOWN_ARROW) // ↑ 129 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
218#define CSA_DOTLESS_I GR2A(LSFT(KC_I)) // ı 130 * │      │   │   │   │   │   │   │   │   │   │ ° │   │   │    │
219#define CSA_DLSI CSA_DOTLESS_I 131 * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
220#define CSA_DEAD_RING GR2A(LSFT(CSA_DCRC)) // dead ° 132 * │    │   │ « │ » │   │   │   │   │   │ < │ > │   │          │
221#define CSA_DRNG CSA_DEAD_RING 133 * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
222#define CSA_DEAD_MACRON GR2A(LSFT(CSA_C_CEDILLA)) // dead ¯ 134 * │    │    │    │                        │    │    │    │    │
223#define CSA_DMCR CSA_DEAD_MACRON 135 * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
136 */
137// Row 1
138#define CA_PIPE ALGR(CA_SLSH) // |
139#define CA_CURR ALGR(CA_4) // ¤
140#define CA_LCBR ALGR(CA_7) // {
141#define CA_RCBR ALGR(CA_8) // }
142#define CA_LBRC ALGR(CA_9) // [
143#define CA_RBRC ALGR(CA_0) // ]
144#define CA_NOT ALGR(CA_EQL) // ¬
145// Row 2
146#define CA_EURO ALGR(CA_E) // €
147#define CA_GRV ALGR(CA_CIRC) // ` (dead)
148#define CA_DTIL ALGR(CA_CCED) // ~ (dead)
149// Row 3
150#define CA_DEG ALGR(CA_SCLN) // °
151// Row 4
152#define CA_LDAQ ALGR(CA_X) // «
153#define CA_RDAQ ALGR(CA_C) // »
154#define CA_LABK ALGR(CA_DOT) // <
155#define CA_RABK ALGR(CA_COMM) // >
224 156
225// Third row 157/* Right Ctrl symbols
226#define CSA_SECTION GR2A(LSFT(KC_S)) // § 158 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
227#define CSA_SECT CSA_SECTION 159 * │   │ ¹ │ ² │ ³ │ ¼ │ ½ │ ¾ │   │   │   │   │   │ ¸ │       │
228#define CSA_ORDINAL_INDICATOR_A GR2A(LSFT(KC_F)) // ª 160 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
229#define CSA_ORDA CSA_ORDINAL_INDICATOR_A 161 * │     │ Ω │ Ł │ Œ │ ¶ │ Ŧ │ ← │ ↓ │ → │ Ø │ Þ │   │ ~ │     │
230#define CSA_DEAD_DOUBLE_ACUTE LSFT(CSA_DEAD_ACUTE) // ˝ 162 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
231#define CSA_DDCT CSA_DEAD_DOUBLE_ACUTE 163 * │      │ Æ │ ß │ Ð │   │ Ŋ │ Ħ │ IJ │ ĸ │ Ŀ │ ´ │   │   │    │
232#define CSA_DEAD_CARON GR2A(LSFT(CSA_E_GRAVE)) // dead ˇ 164 * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
233#define CSA_DCAR CSA_DEAD_CARON 165 * │    │   │   │   │ ¢ │ “ │ ” │ ʼn │ μ │ ― │ ˙ │   │          │
234#define CSA_DEAD_BREVE GR2A(LSFT(CSA_A_GRAVE)) // dead ˘ 166 * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
235#define CSA_DBRV CSA_DEAD_BREVE 167 * │    │    │    │                        │    │    │    │    │
168 * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
169 */
170// Row 1
171#define CA_SUP1 RCTL(CA_1) // ¹
172#define CA_SUP2 RCTL(CA_2) // ²
173#define CA_SUP3 RCTL(CA_3) // ³
174#define CA_QRTR RCTL(CA_4) // ¼
175#define CA_HALF RCTL(CA_5) // ½
176#define CA_TQTR RCTL(CA_6) // ¾
177#define CA_CEDL RCTL(CA_EQL) // ¸ (dead)
178// Row 2
179#define CA_OMEG RCTL(CA_Q) // Ω
180#define CA_LSTR RCTL(CA_W) // Ł
181#define CA_OE RCTL(CA_E) // Œ
182#define CA_PARA RCTL(CA_R) // ¶
183#define CA_TSTR RCTL(CA_T) // Ŧ
184#define CA_LARR RCTL(CA_Y) // ←
185#define CA_DARR RCTL(CA_U) // ↓
186#define CA_RARR RCTL(CA_I) // →
187#define CA_OSTR RCTL(CA_O) // Ø
188#define CA_THRN RCTL(CA_P) // Þ
189#define CA_TILD RCTL(CA_CCED) // ~
190// Row 3
191#define CA_AE RCTL(CA_A) // Æ
192#define CA_SS RCTL(CA_S) // ß
193#define CA_ETH RCTL(CA_D) // Ð
194#define CA_ENG RCTL(CA_G) // Ŋ
195#define CA_HSTR RCTL(CA_H) // Ħ
196#define CA_IJ RCTL(CA_J) // IJ
197#define CA_KRA RCTL(CA_K) // ĸ
198#define CA_LMDT RCTL(CA_L) // Ŀ
199#define CA_ACUT RCTL(CA_SCLN) // ´ (dead)
200// Row 4
201#define CA_CENT RCTL(CA_C) // ¢
202#define CA_LDQU RCTL(CA_V) // “
203#define CA_RDQU RCTL(CA_B) // ”
204#define CA_APSN RCTL(CA_N) // ʼn
205#define CA_MICR RCTL(CA_M) // μ
206#define CA_HRZB RCTL(CA_COMM) // ―
207#define CA_DOTA ALGR(CA_DOT) // ˙ (dead)
236 208
237// Fourth row 209/* Shift+Right Ctrl symbols
238#define CSA_BROKEN_PIPE GR2A(LSFT(CSA_U_GRAVE)) // ¦ 210 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
239#define CSA_BPIP CSA_BROKEN_PIPE 211 * │ - │ ¡ │   │ £ │   │ ⅜ │ ⅝ │ ⅞ │ ™ │ ± │   │ ¿ │ ˛ │       │
240#define CSA_COPYRIGHT GR2A(LSFT(KC_C)) // © 212 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
241#define CSA_CPRT CSA_COPYRIGHT 213 * │     │   │   │   │ ® │   │ ¥ │ ↑ │ ı │   │   │ ° │ ¯ │     │
242#define CSA_LEFT_QUOTE GR2A(LSFT(KC_V)) // ‘ 214 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
243#define CSA_LQOT CSA_LEFT_QUOTE 215 * │      │   │ § │   │ ª │   │   │   │   │   │ ˝ │ ˇ │ ˘ │    │
244#define CSA_RIGHT_QUOTE GR2A(LSFT(KC_B)) // ’ 216 * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
245#define CSA_RQOT CSA_RIGHT_QUOTE 217 * │    │ ¦ │   │   │ © │ ‘ │ ’ │ ♪ │ º │ × │ ÷ │   │          │
246#define CSA_EIGHTH_NOTE GR2A(LSFT(KC_N)) // ♪ 218 * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
247#define CSA_8NOT CSA_EIGHTH_NOTE 219 * │    │    │    │                        │    │    │    │    │
248#define CSA_ORDINAL_INDICATOR_O GR2A(LSFT(KC_M)) // º 220 * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
249#define CSA_ORDO CSA_ORDINAL_INDICATOR_O 221 */
250#define CSA_TIMES GR2A(LSFT(KC_COMMA)) // × 222// Row 1
251#define CSA_TIMS CSA_TIMES 223#define CA_SHYP RCTL(S(CA_SLSH)) // (soft hyphen)
252#define CSA_OBELUS GR2A(LSFT(KC_DOT)) // ÷ 224#define CA_IEXL RCTL(S(CA_1)) // ¡
253#define CSA_OBEL CSA_OBELUS 225#define CA_PND RCTL(S(CA_3)) // £
254// more conventional name of the symbol 226#define CA_TEIG RCTL(S(CA_5)) // ⅜
255#define CSA_DIVISION_SIGN CSA_OBELUS 227#define CA_FEIG RCTL(S(CA_6)) // ⅝
256#define CSA_DVSN CSA_DIVISION_SIGN 228#define CA_SEIG RCTL(S(CA_7)) // ⅞
257// TODO GR2A(LSFT(CSA_E_ACUTE)) 229#define CA_TM RCTL(S(CA_8)) // ™
230#define CA_PLMN RCTL(S(CA_9)) // ±
231#define CA_IQUE RCTL(S(CA_MINS)) // ¿
232#define CA_OGON RCTL(S(CA_EQL)) // ˛ (dead)
233// Row 2
234#define CA_REGD RCTL(S(CA_R)) // ®
235#define CA_YEN RCTL(S(CA_Y)) // ¥
236#define CA_UARR RCTL(S(CA_U)) // ↑
237#define CA_DLSI RCTL(S(CA_I)) // ı
238#define CA_RNGA RCTL(S(CA_CIRC)) // ° (dead)
239#define CA_MACR RCTL(S(CA_CCED)) // ¯ (dead)
240// Row 3
241#define CA_SECT RCTL(S(CA_S)) // §
242#define CA_FORD RCTL(S(CA_F)) // ª
243#define CA_DACU RCTL(S(CA_SCLN)) // ˝ (dead)
244#define CA_CARN RCTL(S(CA_EGRV)) // ˇ (dead)
245#define CA_BREV RCTL(S(CA_AGRV)) // ˘ (dead)
246// Row 4
247#define CA_BRKP RCTL(S(CA_UGRV)) // ¦
248#define CA_COPY RCTL(S(CA_C)) // ©
249#define CA_LSQU RCTL(S(CA_V)) // ‘
250#define CA_RSQU RCTL(S(CA_B)) // ’
251#define CA_ENOT RCTL(S(CA_N)) // ♪
252#define CA_MORD RCTL(S(CA_M)) // º
253#define CA_MUL RCTL(S(CA_COMM)) // ×
254#define CA_DIV RCTL(S(CA_DOT)) // ÷
258 255
259#endif 256// DEPRECATED
257#define GR2A(kc) RCTL(kc)
258#define CSA_SLASH CA_SLSH
259#define CSA_SLSH CA_SLSH
260#define CSA_DEAD_CIRCUMFLEX CA_CIRC
261#define CSA_DCRC CA_CIRC
262#define CSA_C_CEDILLA CA_CCED
263#define CSA_CCED CA_CCED
264#define CSA_E_GRAVE CA_EGRV
265#define CSA_EGRV CA_EGRV
266#define CSA_A_GRAVE CA_AGRV
267#define CSA_AGRV CA_AGRV
268#define CSA_U_GRAVE CA_UGRV
269#define CSA_UGRV CA_UGRV
270#define CSA_E_ACUTE CA_EACU
271#define CSA_ECUT CA_EACU
272#define CSA_BACKSLASH CA_BSLS
273#define CSA_BSLS CA_BSLS
274#define CSA_QUESTION CA_QUES
275#define CSA_QEST CA_QUES
276#define CSA_DEAD_TREMA CA_DIAE
277#define CSA_DTRM CA_DIAE
278#define CSA_APOSTROPHE CA_QUOT
279#define CSA_APOS CA_QUOT
280#define CSA_DOUBLE_QUOTE CA_DQUO
281#define CSA_DQOT CA_DQUO
282#define CSA_PIPE CA_PIPE
283#define CSA_CURRENCY CA_CURR
284#define CSA_CURR CA_CURR
285#define CSA_LEFT_CURLY_BRACE CA_LCBR
286#define CSA_LCBR CA_LCBR
287#define CSA_RIGHT_CURLY_BRACE CA_RCBR
288#define CSA_RCBR CA_RCBR
289#define CSA_LBRACKET CA_LBRC
290#define CSA_LBRC CA_LBRC
291#define CSA_RBRACKET CA_RBRC
292#define CSA_RBRC CA_RBRC
293#define CSA_NEGATION CA_NOT
294#define CSA_NEGT CA_NOT
295#define CSA_EURO CA_EURO
296#define CSA_DEAD_GRAVE CA_GRV
297#define CSA_DGRV CA_GRV
298#define CSA_DEAD_TILDE CA_DTIL
299#define CSA_DTLD CA_DTIL
300#define CSA_DEGREE CA_DEG
301#define CSA_DEGR CA_DEG
302#define CSA_LEFT_GUILLEMET CA_LDAQ
303#define CSA_LGIL CA_LDAQ
304#define CSA_RIGHT_GUILLEMET CA_RDAQ
305#define CSA_RGIL CA_RDAQ
306#define CSA_LESS CA_LABK
307#define CSA_GREATER CA_RABK
308#define CSA_GRTR CA_RABK
309#define CSA_NON_BREAKING_SPACE ALGR(KC_SPC)
310#define CSA_NBSP ALGR(KC_SPC)
311#define CSA_SUPERSCRIPT_ONE CA_SUP1
312#define CSA_SUP1 CA_SUP1
313#define CSA_SUPERSCRIPT_TWO CA_SUP2
314#define CSA_SUP2 CA_SUP2
315#define CSA_SUPERSCRIPT_THREE CA_SUP3
316#define CSA_SUP3 CA_SUP3
317#define CSA_ONE_QUARTER CA_QRTR
318#define CSA_1QRT CA_QRTR
319#define CSA_ONE_HALF CA_HALF
320#define CSA_1HLF CA_HALF
321#define CSA_THREE_QUARTERS CA_TQTR
322#define CSA_3QRT CA_TQTR
323#define CSA_DEAD_CEDILLA CA_CEDL
324#define CSA_DCED CA_CEDL
325#define CSA_OMEGA CA_OMEG
326#define CSA_OMEG CA_OMEG
327#define CSA_L_STROKE CA_LSTR
328#define CSA_LSTK CA_LSTR
329#define CSA_OE_LIGATURE CA_OE
330#define CSA_OE CA_OE
331#define CSA_PARAGRAPH CA_PARA
332#define CSA_PARG CA_PARA
333#define CSA_T_STROKE CA_TSTR
334#define CSA_LEFT_ARROW CA_LARR
335#define CSA_LARW CA_LARR
336#define CSA_DOWN_ARROW CA_DARR
337#define CSA_DARW CA_DARR
338#define CSA_RIGHT_ARROW CA_RARR
339#define CSA_RARW CA_RARR
340#define CSA_O_STROKE CA_OSTR
341#define CSA_OSTK CA_OSTR
342#define CSA_THORN CA_THRN
343#define CSA_THRN CA_THRN
344#define CSA_TILDE CA_TILD
345#define CSA_TILD CA_TILD
346#define CSA_AE_LIGATURE CA_AE
347#define CSA_AE CA_AE
348#define CSA_SHARP_S CA_SS
349#define CSA_SRPS CA_SS
350#define CSA_ETH CA_ETH
351#define CSA_ENG CA_ENG
352#define CSA_H_SRTOKE CA_HSTR
353#define CSA_HSTK CA_HSTR
354#define CSA_IJ_LIGATURE CA_IJ
355#define CSA_IJ CA_IJ
356#define CSA_KRA CA_KRA
357#define CSA_L_FLOWN_DOT CA_LMDT
358#define CSA_LFLD CA_LMDT
359#define CSA_DEAD_ACUTE CA_ACUT
360#define CSA_DACT CA_ACUT
361#define CSA_CENT CA_CENT
362#define CSA_LEFT_DOUBLE_QUOTE CA_LDQU
363#define CSA_LDQT CA_LDQU
364#define CSA_RIGHT_DOUBLE_QUOTE CA_RDQU
365#define CSA_RDQT CA_RDQU
366#define CSA_N_APOSTROPHE CA_APSN
367#define CSA_NAPO CA_APSN
368#define CSA_MU CA_MICR
369#define CSA_HORIZONTAL_BAR CA_HRZB
370#define CSA_HZBR CA_HRZB
371#define CSA_DEAD_DOT_ABOVE CA_DOTA
372#define CSA_DDTA CA_DOTA
373#define CSA_SOFT_HYPHEN CA_SHYP
374#define CSA_SHYP CA_SHYP
375#define CSA_INVERTED_EXCLAIM CA_IEXL
376#define CSA_IXLM CA_IEXL
377#define CSA_POUND CA_PND
378#define CSA_GBP CA_PND
379#define CSA_EURO_BIS CA_EURO
380#define CSA_EURB CA_EURO
381#define CSA_THREE_EIGHTHS CA_TEIG
382#define CSA_3ON8 CA_TEIG
383#define CSA_FIVE_EIGHTHS CA_FEIG
384#define CSA_5ON8 CA_FEIG
385#define CSA_SEVEN_EIGHTHS CA_SEIG
386#define CSA_7ON8 CA_SEIG
387#define CSA_TRADEMARK CA_TM
388#define CSA_TM CA_TM
389#define CSA_PLUS_MINUS CA_PLMN
390#define CSA_PSMS CA_PLMN
391#define CSA_INVERTED_QUESTION CA_IQUE
392#define CSA_IQST CA_IQUE
393#define CSA_DEAD_OGONEK CA_OGON
394#define CSA_DOGO CA_OGON
395#define CSA_REGISTERED_TRADEMARK CA_REGD
396#define CSA_RTM CA_REGD
397#define CSA_YEN CA_YEN
398#define CSA_YUAN CA_YEN
399#define CSA_UP_ARROW CA_UARR
400#define CSA_DOTLESS_I CA_DLSI
401#define CSA_DLSI CA_DLSI
402#define CSA_DEAD_RING CA_RNGA
403#define CSA_DRNG CA_RNGA
404#define CSA_DEAD_MACRON CA_MACR
405#define CSA_DMCR CA_MACR
406#define CSA_SECTION CA_SECT
407#define CSA_SECT CA_SECT
408#define CSA_ORDINAL_INDICATOR_A CA_FORD
409#define CSA_ORDA CA_FORD
410#define CSA_DEAD_DOUBLE_ACUTE CA_DACU
411#define CSA_DDCT CA_DACU
412#define CSA_DEAD_CARON CA_CARN
413#define CSA_DCAR CA_CARN
414#define CSA_DEAD_BREVE CA_BREV
415#define CSA_DBRV CA_BREV
416#define CSA_BROKEN_PIPE CA_BRKP
417#define CSA_BPIP CA_BRKP
418#define CSA_COPYRIGHT CA_COPY
419#define CSA_CPRT CA_COPY
420#define CSA_LEFT_QUOTE CA_LSQU
421#define CSA_LQOT CA_LSQU
422#define CSA_RIGHT_QUOTE CA_RSQU
423#define CSA_RQOT CA_RSQU
424#define CSA_EIGHTH_NOTE CA_ENOT
425#define CSA_8NOT CA_ENOT
426#define CSA_ORDINAL_INDICATOR_O CA_MORD
427#define CSA_ORDO CA_MORD
428#define CSA_TIMES CA_MUL
429#define CSA_TIMS CA_MUL
430#define CSA_OBELUS CA_DIV
431#define CSA_OBEL CA_DIV
432#define CSA_DIVISION_SIGN CA_DIV
433#define CSA_DVSN CA_DIV
diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h
index 818a739c7..8e6e2b77a 100644
--- a/quantum/keymap_extras/keymap_neo2.h
+++ b/quantum/keymap_extras/keymap_neo2.h
@@ -13,66 +13,130 @@
13 * You should have received a copy of the GNU General Public License 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/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16#ifndef KEYMAP_NEO2
17#define KEYMAP_NEO2
18 16
19#include "keymap.h" 17#pragma once
20#include "keymap_german.h"
21
22#define NEO_A KC_D
23#define NEO_B KC_N
24#define NEO_C KC_R
25#define NEO_D DE_OE
26#define NEO_E KC_F
27#define NEO_F KC_O
28#define NEO_G KC_I
29#define NEO_H KC_U
30#define NEO_I KC_S
31#define NEO_J DE_MINS
32#define NEO_K DE_Z
33#define NEO_L KC_E
34#define NEO_M KC_M
35#define NEO_N KC_J
36#define NEO_O KC_G
37#define NEO_P KC_V
38#define NEO_Q KC_P
39#define NEO_R KC_K
40#define NEO_S KC_H
41#define NEO_T KC_L
42#define NEO_U KC_A
43#define NEO_V KC_W
44#define NEO_W KC_T
45#define NEO_X KC_Q
46#define NEO_Y DE_AE
47#define NEO_Z KC_B
48#define NEO_AE KC_C
49#define NEO_OE KC_X
50#define NEO_UE DE_Y
51#define NEO_SS DE_UE
52
53#define NEO_DOT DE_DOT
54#define NEO_COMM DE_COMM
55 18
56#define NEO_1 DE_1 19#include "keymap.h"
57#define NEO_2 DE_2
58#define NEO_3 DE_3
59#define NEO_4 DE_4
60#define NEO_5 DE_5
61#define NEO_6 DE_6
62#define NEO_7 DE_7
63#define NEO_8 DE_8
64#define NEO_9 DE_9
65#define NEO_0 DE_0
66#define NEO_MINS DE_SS
67
68#define NEO_ACUT DE_PLUS
69#define NEO_GRV DE_ACUT
70#define NEO_CIRC DE_CIRC
71 20
72#define NEO_L1_L KC_CAPS 21// clang-format off
73#define NEO_L1_R DE_HASH
74 22
75#define NEO_L2_L DE_LESS 23/*
76#define NEO_L2_R KC_ALGR 24 * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐
25 * │ ^ │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ ` │       │
26 * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤
27 * │     │ X │ V │ L │ C │ W │ K │ H │ G │ F │ Q │ ß │ ´ │     │
28 * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐    │
29 * │  L3  │ U │ I │ A │ E │ O │ S │ N │ R │ T │ D │ Y │ L3│    │
30 * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤
31 * │    │L4 │ Ü │ Ö │ Ä │ P │ Z │ B │ M │ , │ . │ J │          │
32 * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤
33 * │    │    │    │                        │    │ L4 │    │    │
34 * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘
35 */
36// Row 1
37#define NE_CIRC KC_GRV // ^ (dead)
38#define NE_1 KC_1 // 1
39#define NE_2 KC_2 // 2
40#define NE_3 KC_3 // 3
41#define NE_4 KC_4 // 4
42#define NE_5 KC_5 // 5
43#define NE_6 KC_6 // 6
44#define NE_7 KC_7 // 7
45#define NE_8 KC_8 // 8
46#define NE_9 KC_9 // 9
47#define NE_0 KC_0 // 0
48#define NE_MINS KC_MINS // -
49#define NE_GRV KC_EQL // ` (dead)
50// Row 2
51#define NE_X KC_Q // X
52#define NE_V KC_W // V
53#define NE_L KC_E // L
54#define NE_C KC_R // C
55#define NE_W KC_T // W
56#define NE_K KC_Y // K
57#define NE_H KC_U // H
58#define NE_H KC_I // G
59#define NE_F KC_O // F
60#define NE_Q KC_P // Q
61#define NE_SS KC_LBRC // ß
62#define NE_ACUT KC_RBRC // ´ (dead)
63// Row 3
64#define NE_L3L KC_CAPS // (layer 3)
65#define NE_U KC_A // U
66#define NE_I KC_S // I
67#define NE_A KC_D // A
68#define NE_E KC_F // E
69#define NE_O KC_G // O
70#define NE_S KC_H // S
71#define NE_N KC_J // N
72#define NE_R KC_K // R
73#define NE_T KC_L // T
74#define NE_D KC_SCLN // D
75#define NE_Y KC_QUOT // Y
76#define NE_L3R KC_NUHS // (layer 3)
77// Row 4
78#define NE_L4L KC_NUBS // (layer 4)
79#define NE_UDIA KC_Z // Ü
80#define NE_ODIA KC_X // Ö
81#define NE_ADIA KC_C // Ä
82#define NE_P KC_V // P
83#define NE_Z KC_B // Z
84#define NE_B KC_N // B
85#define NE_M KC_M // M
86#define NE_COMM KC_COMM // ,
87#define NE_DOT KC_DOT // .
88#define NE_J KC_SLSH // J
89// Row 5
90#define NE_L4R KC_ALGR // (layer 4)
77 91
78#endif 92// DEPRECATED
93#define NEO_A NE_A
94#define NEO_B NE_B
95#define NEO_C NE_C
96#define NEO_D NE_D
97#define NEO_E NE_E
98#define NEO_F NE_F
99#define NEO_G NE_G
100#define NEO_H NE_H
101#define NEO_I NE_I
102#define NEO_J NE_J
103#define NEO_K NE_K
104#define NEO_L NE_L
105#define NEO_M NE_M
106#define NEO_N NE_N
107#define NEO_O NE_O
108#define NEO_P NE_P
109#define NEO_Q NE_Q
110#define NEO_R NE_R
111#define NEO_S NE_S
112#define NEO_T NE_T
113#define NEO_U NE_U
114#define NEO_V NE_V
115#define NEO_W NE_W
116#define NEO_X NE_X
117#define NEO_Y NE_Y
118#define NEO_Z NE_Z
119#define NEO_AE NE_ADIA
120#define NEO_OE NE_ODIA
121#define NEO_UE NE_UDIA
122#define NEO_SS NE_SS
123#define NEO_DOT NE_DOT
124#define NEO_COMM NE_COMM
125#define NEO_1 NE_1
126#define NEO_2 NE_2
127#define NEO_3 NE_3
128#define NEO_4 NE_4
129#define NEO_5 NE_5
130#define NEO_6 NE_6
131#define NEO_7 NE_7
132#define NEO_8 NE_8
133#define NEO_9 NE_9
134#define NEO_0 NE_0
135#define NEO_MINS NE_MINS
136#define NEO_ACUT NE_ACUT
137#define NEO_GRV NE_GRV
138#define NEO_CIRC NE_CIRC
139#define NEO_L1_L NE_L3L
140#define NEO_L1_R NE_L3R
141#define NEO_L2_L NE_L4L
142#define NEO_L2_R NE_L4R
diff --git a/quantum/keymap_extras/sendstring_canadian_multilingual.h b/quantum/keymap_extras/sendstring_canadian_multilingual.h
new file mode 100644
index 000000000..c3fcc62c3
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_canadian_multilingual.h
@@ -0,0 +1,100 @@
1/* Copyright 2020
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 2 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// Sendstring lookup tables for Canadian Multilingual layouts
18
19#pragma once
20
21#include "keymap_canadian_multilingual.h"
22#include "quantum.h"
23
24// clang-format off
25
26const uint8_t ascii_to_shift_lut[16] PROGMEM = {
27 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
28 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
29 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
30 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
31
32 KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
33 KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0),
34 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
35 KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 1),
36 KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
37 KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
38 KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
39 KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 1),
40 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
41 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
42 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
43 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
44};
45
46const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
47 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
48 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
49 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
50 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
51
52 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
53 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
54 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
55 KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0),
56 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
57 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
58 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
59 KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0),
60 KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
61 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
62 KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
63 KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0)
64};
65
66const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
67 // NUL SOH STX ETX EOT ENQ ACK BEL
68 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
69 // BS TAB LF VT FF CR SO SI
70 KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
71 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
72 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
73 // CAN EM SUB ESC FS GS RS US
74 XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
75
76 // ! " # $ % & '
77 KC_SPC, CA_1, CA_DOT, CA_3, CA_4, CA_5, CA_7, CA_COMM,
78 // ( ) * + , - . /
79 CA_9, CA_0, CA_8, CA_EQL, CA_COMM, CA_MINS, CA_DOT, CA_SLSH,
80 // 0 1 2 3 4 5 6 7
81 CA_0, CA_1, CA_2, CA_3, CA_4, CA_5, CA_6, CA_7,
82 // 8 9 : ; < = > ?
83 CA_8, CA_9, CA_SCLN, CA_SCLN, CA_DOT, CA_EQL, CA_COMM, CA_6,
84 // @ A B C D E F G
85 CA_2, CA_A, CA_B, CA_C, CA_D, CA_E, CA_F, CA_G,
86 // H I J K L M N O
87 CA_H, CA_I, CA_J, CA_K, CA_L, CA_M, CA_N, CA_O,
88 // P Q R S T U V W
89 CA_P, CA_Q, CA_R, CA_S, CA_T, CA_U, CA_V, CA_W,
90 // X Y Z [ \ ] ^ _
91 CA_X, CA_Y, CA_Z, CA_9, CA_SLSH, CA_0, CA_CIRC, CA_MINS,
92 // ` a b c d e f g
93 CA_CIRC, CA_A, CA_B, CA_C, CA_D, CA_E, CA_F, CA_G,
94 // h i j k l m n o
95 CA_H, CA_I, CA_J, CA_K, CA_L, CA_M, CA_N, CA_O,
96 // p q r s t u v w
97 CA_P, CA_Q, CA_R, CA_S, CA_T, CA_U, CA_V, CA_W,
98 // x y z { | } ~ DEL
99 CA_X, CA_Y, CA_Z, CA_7, CA_SLSH, CA_8, CA_CCED, KC_DEL
100};
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 67d8af6ee..c68c56cac 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -48,17 +48,22 @@ static void init_pins(void) {
48} 48}
49 49
50static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 50static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
51 matrix_row_t last_row_value = current_matrix[current_row]; 51 // Start with a clear matrix row
52 current_matrix[current_row] = 0; 52 matrix_row_t current_row_value = 0;
53 53
54 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 54 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
55 pin_t pin = direct_pins[current_row][col_index]; 55 pin_t pin = direct_pins[current_row][col_index];
56 if (pin != NO_PIN) { 56 if (pin != NO_PIN) {
57 current_matrix[current_row] |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index); 57 current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
58 } 58 }
59 } 59 }
60 60
61 return (last_row_value != current_matrix[current_row]); 61 // If the row has changed, store the row and return the changed flag.
62 if (current_matrix[current_row] != current_row_value) {
63 current_matrix[current_row] = current_row_value;
64 return true;
65 }
66 return false;
62} 67}
63 68
64#elif defined(DIODE_DIRECTION) 69#elif defined(DIODE_DIRECTION)
@@ -85,11 +90,8 @@ static void init_pins(void) {
85} 90}
86 91
87static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 92static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
88 // Store last value of row prior to reading 93 // Start with a clear matrix row
89 matrix_row_t last_row_value = current_matrix[current_row]; 94 matrix_row_t current_row_value = 0;
90
91 // Clear data in matrix row
92 current_matrix[current_row] = 0;
93 95
94 // Select row and wait for row selecton to stabilize 96 // Select row and wait for row selecton to stabilize
95 select_row(current_row); 97 select_row(current_row);
@@ -101,13 +103,18 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
101 uint8_t pin_state = readPin(col_pins[col_index]); 103 uint8_t pin_state = readPin(col_pins[col_index]);
102 104
103 // Populate the matrix row with the state of the col pin 105 // Populate the matrix row with the state of the col pin
104 current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); 106 current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
105 } 107 }
106 108
107 // Unselect row 109 // Unselect row
108 unselect_row(current_row); 110 unselect_row(current_row);
109 111
110 return (last_row_value != current_matrix[current_row]); 112 // If the row has changed, store the row and return the changed flag.
113 if (current_matrix[current_row] != current_row_value) {
114 current_matrix[current_row] = current_row_value;
115 return true;
116 }
117 return false;
111} 118}
112 119
113# elif (DIODE_DIRECTION == ROW2COL) 120# elif (DIODE_DIRECTION == ROW2COL)
@@ -142,20 +149,22 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
142 // For each row... 149 // For each row...
143 for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { 150 for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
144 // Store last value of row prior to reading 151 // Store last value of row prior to reading
145 matrix_row_t last_row_value = current_matrix[row_index]; 152 matrix_row_t last_row_value = current_matrix[row_index];
153 matrix_row_t current_row_value = last_row_value;
146 154
147 // Check row pin state 155 // Check row pin state
148 if (readPin(row_pins[row_index]) == 0) { 156 if (readPin(row_pins[row_index]) == 0) {
149 // Pin LO, set col bit 157 // Pin LO, set col bit
150 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); 158 current_row_value |= (MATRIX_ROW_SHIFTER << current_col);
151 } else { 159 } else {
152 // Pin HI, clear col bit 160 // Pin HI, clear col bit
153 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); 161 current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col);
154 } 162 }
155 163
156 // Determine if the matrix changed state 164 // Determine if the matrix changed state
157 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { 165 if ((last_row_value != current_row_value)) {
158 matrix_changed = true; 166 matrix_changed |= true;
167 current_matrix[row_index] = current_row_value;
159 } 168 }
160 } 169 }
161 170
diff --git a/quantum/process_keycode/process_rgb.c b/quantum/process_keycode/process_rgb.c
index 627e5986f..21164b8f9 100644
--- a/quantum/process_keycode/process_rgb.c
+++ b/quantum/process_keycode/process_rgb.c
@@ -56,7 +56,7 @@ bool process_rgb(const uint16_t keycode, const keyrecord_t *record) {
56 // Split keyboards need to trigger on key-up for edge-case issue 56 // Split keyboards need to trigger on key-up for edge-case issue
57 if (!record->event.pressed) { 57 if (!record->event.pressed) {
58#endif 58#endif
59 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)); 59 uint8_t shifted = get_mods() & MOD_MASK_SHIFT;
60 switch (keycode) { 60 switch (keycode) {
61 case RGB_TOG: 61 case RGB_TOG:
62 rgblight_toggle(); 62 rgblight_toggle();
diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c
index 48ce3961a..fb5021501 100644
--- a/quantum/process_keycode/process_unicode_common.c
+++ b/quantum/process_keycode/process_unicode_common.c
@@ -24,8 +24,8 @@ uint8_t unicode_saved_mods;
24 24
25#if UNICODE_SELECTED_MODES != -1 25#if UNICODE_SELECTED_MODES != -1
26static uint8_t selected[] = {UNICODE_SELECTED_MODES}; 26static uint8_t selected[] = {UNICODE_SELECTED_MODES};
27static uint8_t selected_count = sizeof selected / sizeof *selected; 27static int8_t selected_count = sizeof selected / sizeof *selected;
28static uint8_t selected_index; 28static int8_t selected_index;
29#endif 29#endif
30 30
31void unicode_input_mode_init(void) { 31void unicode_input_mode_init(void) {
@@ -33,7 +33,7 @@ void unicode_input_mode_init(void) {
33#if UNICODE_SELECTED_MODES != -1 33#if UNICODE_SELECTED_MODES != -1
34# if UNICODE_CYCLE_PERSIST 34# if UNICODE_CYCLE_PERSIST
35 // Find input_mode in selected modes 35 // Find input_mode in selected modes
36 uint8_t i; 36 int8_t i;
37 for (i = 0; i < selected_count; i++) { 37 for (i = 0; i < selected_count; i++) {
38 if (selected[i] == unicode_config.input_mode) { 38 if (selected[i] == unicode_config.input_mode) {
39 selected_index = i; 39 selected_index = i;
@@ -60,9 +60,12 @@ void set_unicode_input_mode(uint8_t mode) {
60 dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode); 60 dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode);
61} 61}
62 62
63void cycle_unicode_input_mode(uint8_t offset) { 63void cycle_unicode_input_mode(int8_t offset) {
64#if UNICODE_SELECTED_MODES != -1 64#if UNICODE_SELECTED_MODES != -1
65 selected_index = (selected_index + offset) % selected_count; 65 selected_index = (selected_index + offset) % selected_count;
66 if (selected_index < 0) {
67 selected_index += selected_count;
68 }
66 unicode_config.input_mode = selected[selected_index]; 69 unicode_config.input_mode = selected[selected_index];
67# if UNICODE_CYCLE_PERSIST 70# if UNICODE_CYCLE_PERSIST
68 persist_unicode_input_mode(); 71 persist_unicode_input_mode();
@@ -168,6 +171,8 @@ void register_hex32(uint32_t hex) {
168 } 171 }
169} 172}
170 173
174// clang-format off
175
171void send_unicode_hex_string(const char *str) { 176void send_unicode_hex_string(const char *str) {
172 if (!str) { 177 if (!str) {
173 return; 178 return;
@@ -175,12 +180,11 @@ void send_unicode_hex_string(const char *str) {
175 180
176 while (*str) { 181 while (*str) {
177 // Find the next code point (token) in the string 182 // Find the next code point (token) in the string
178 for (; *str == ' '; str++) 183 for (; *str == ' '; str++); // Skip leading spaces
179 ;
180 size_t n = strcspn(str, " "); // Length of the current token 184 size_t n = strcspn(str, " "); // Length of the current token
181 char code_point[n + 1]; 185 char code_point[n+1];
182 strncpy(code_point, str, n); 186 strncpy(code_point, str, n); // Copy token into buffer
183 code_point[n] = '\0'; // Make sure it's null-terminated 187 code_point[n] = '\0'; // Make sure it's null-terminated
184 188
185 // Normalize the code point: make all hex digits lowercase 189 // Normalize the code point: make all hex digits lowercase
186 for (char *p = code_point; *p; p++) { 190 for (char *p = code_point; *p; p++) {
@@ -196,8 +200,10 @@ void send_unicode_hex_string(const char *str) {
196 } 200 }
197} 201}
198 202
203// clang-format on
204
199// Borrowed from https://nullprogram.com/blog/2017/10/06/ 205// Borrowed from https://nullprogram.com/blog/2017/10/06/
200const char *decode_utf8(const char *str, int32_t *code_point) { 206static const char *decode_utf8(const char *str, int32_t *code_point) {
201 const char *next; 207 const char *next;
202 208
203 if (str[0] < 0x80) { // U+0000-007F 209 if (str[0] < 0x80) { // U+0000-007F
@@ -231,7 +237,6 @@ void send_unicode_string(const char *str) {
231 } 237 }
232 238
233 int32_t code_point = 0; 239 int32_t code_point = 0;
234
235 while (*str) { 240 while (*str) {
236 str = decode_utf8(str, &code_point); 241 str = decode_utf8(str, &code_point);
237 242
@@ -243,53 +248,70 @@ void send_unicode_string(const char *str) {
243 } 248 }
244} 249}
245 250
251// clang-format off
252
253static void audio_helper(void) {
254#ifdef AUDIO_ENABLE
255 switch (get_unicode_input_mode()) {
256# ifdef UNICODE_SONG_MAC
257 static float song_mac[][2] = UNICODE_SONG_MAC;
258 case UC_MAC:
259 PLAY_SONG(song_mac);
260 break;
261# endif
262# ifdef UNICODE_SONG_LNX
263 static float song_lnx[][2] = UNICODE_SONG_LNX;
264 case UC_LNX:
265 PLAY_SONG(song_lnx);
266 break;
267# endif
268# ifdef UNICODE_SONG_WIN
269 static float song_win[][2] = UNICODE_SONG_WIN;
270 case UC_WIN:
271 PLAY_SONG(song_win);
272 break;
273# endif
274# ifdef UNICODE_SONG_BSD
275 static float song_bsd[][2] = UNICODE_SONG_BSD;
276 case UC_BSD:
277 PLAY_SONG(song_bsd);
278 break;
279# endif
280# ifdef UNICODE_SONG_WINC
281 static float song_winc[][2] = UNICODE_SONG_WINC;
282 case UC_WINC:
283 PLAY_SONG(song_winc);
284 break;
285# endif
286 }
287#endif
288}
289
290// clang-format on
291
246bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { 292bool process_unicode_common(uint16_t keycode, keyrecord_t *record) {
247 if (record->event.pressed) { 293 if (record->event.pressed) {
294 bool shifted = get_mods() & MOD_MASK_SHIFT;
248 switch (keycode) { 295 switch (keycode) {
249 case UNICODE_MODE_FORWARD: 296 case UNICODE_MODE_FORWARD:
250 cycle_unicode_input_mode(+1); 297 cycle_unicode_input_mode(shifted ? -1 : +1);
298 audio_helper();
251 break; 299 break;
252 case UNICODE_MODE_REVERSE: 300 case UNICODE_MODE_REVERSE:
253 cycle_unicode_input_mode(-1); 301 cycle_unicode_input_mode(shifted ? +1 : -1);
302 audio_helper();
254 break; 303 break;
255 304
256 case UNICODE_MODE_MAC: 305 case UNICODE_MODE_MAC ... UNICODE_MODE_WINC: {
257 set_unicode_input_mode(UC_MAC); 306 // Keycodes and input modes follow the same ordering
258#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_MAC) 307 uint8_t delta = keycode - UNICODE_MODE_MAC;
259 static float song_mac[][2] = UNICODE_SONG_MAC; 308 set_unicode_input_mode(UC_MAC + delta);
260 PLAY_SONG(song_mac); 309 audio_helper();
261#endif
262 break;
263 case UNICODE_MODE_LNX:
264 set_unicode_input_mode(UC_LNX);
265#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_LNX)
266 static float song_lnx[][2] = UNICODE_SONG_LNX;
267 PLAY_SONG(song_lnx);
268#endif
269 break;
270 case UNICODE_MODE_WIN:
271 set_unicode_input_mode(UC_WIN);
272#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WIN)
273 static float song_win[][2] = UNICODE_SONG_WIN;
274 PLAY_SONG(song_win);
275#endif
276 break;
277 case UNICODE_MODE_BSD:
278 set_unicode_input_mode(UC_BSD);
279#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_BSD)
280 static float song_bsd[][2] = UNICODE_SONG_BSD;
281 PLAY_SONG(song_bsd);
282#endif
283 break;
284 case UNICODE_MODE_WINC:
285 set_unicode_input_mode(UC_WINC);
286#if defined(AUDIO_ENABLE) && defined(UNICODE_SONG_WINC)
287 static float song_winc[][2] = UNICODE_SONG_WINC;
288 PLAY_SONG(song_winc);
289#endif
290 break; 310 break;
311 }
291 } 312 }
292 } 313 }
314
293#if defined(UNICODE_ENABLE) 315#if defined(UNICODE_ENABLE)
294 return process_unicode(keycode, record); 316 return process_unicode(keycode, record);
295#elif defined(UNICODEMAP_ENABLE) 317#elif defined(UNICODEMAP_ENABLE)
diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h
index 5421c28c7..4579fde8d 100644
--- a/quantum/process_keycode/process_unicode_common.h
+++ b/quantum/process_keycode/process_unicode_common.h
@@ -80,7 +80,7 @@ extern uint8_t unicode_saved_mods;
80void unicode_input_mode_init(void); 80void unicode_input_mode_init(void);
81uint8_t get_unicode_input_mode(void); 81uint8_t get_unicode_input_mode(void);
82void set_unicode_input_mode(uint8_t mode); 82void set_unicode_input_mode(uint8_t mode);
83void cycle_unicode_input_mode(uint8_t offset); 83void cycle_unicode_input_mode(int8_t offset);
84void persist_unicode_input_mode(void); 84void persist_unicode_input_mode(void);
85 85
86void unicode_input_start(void); 86void unicode_input_start(void);
diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c
index 5445cde12..2f402a2fd 100644
--- a/quantum/process_keycode/process_unicodemap.c
+++ b/quantum/process_keycode/process_unicodemap.c
@@ -21,7 +21,8 @@ __attribute__((weak)) uint16_t unicodemap_index(uint16_t keycode) {
21 // Keycode is a pair: extract index based on Shift / Caps Lock state 21 // Keycode is a pair: extract index based on Shift / Caps Lock state
22 uint16_t index = keycode - QK_UNICODEMAP_PAIR; 22 uint16_t index = keycode - QK_UNICODEMAP_PAIR;
23 23
24 bool shift = unicode_saved_mods & MOD_MASK_SHIFT, caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK); 24 bool shift = unicode_saved_mods & MOD_MASK_SHIFT;
25 bool caps = IS_HOST_LED_ON(USB_LED_CAPS_LOCK);
25 if (shift ^ caps) { 26 if (shift ^ caps) {
26 index >>= 7; 27 index >>= 7;
27 } 28 }
diff --git a/quantum/quantum.c b/quantum/quantum.c
index a780ed43d..75df357d3 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -623,9 +623,6 @@ void matrix_init_quantum() {
623#ifdef OUTPUT_AUTO_ENABLE 623#ifdef OUTPUT_AUTO_ENABLE
624 set_output(OUTPUT_AUTO); 624 set_output(OUTPUT_AUTO);
625#endif 625#endif
626#ifdef DIP_SWITCH_ENABLE
627 dip_switch_init();
628#endif
629 626
630 matrix_init_kb(); 627 matrix_init_kb();
631} 628}
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 0958c4f4e..d8f1fa4bb 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -794,6 +794,7 @@ enum quantum_keycodes {
794# define SH_T(kc) (QK_SWAP_HANDS | (kc)) 794# define SH_T(kc) (QK_SWAP_HANDS | (kc))
795# define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) 795# define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE)
796# define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) 796# define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE)
797# define SH_OS (QK_SWAP_HANDS | OP_SH_ONESHOT)
797# define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF) 798# define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF)
798# define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON) 799# define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON)
799# define SH_ON (QK_SWAP_HANDS | OP_SH_ON) 800# define SH_ON (QK_SWAP_HANDS | OP_SH_ON)
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index 3fae9d737..f3da0ab0f 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -57,8 +57,12 @@ const point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;
57// -----End rgb effect includes macros------- 57// -----End rgb effect includes macros-------
58// ------------------------------------------ 58// ------------------------------------------
59 59
60#ifndef RGB_DISABLE_AFTER_TIMEOUT 60#if defined(RGB_DISABLE_AFTER_TIMEOUT) && !defined(RGB_DISABLE_TIMEOUT)
61# define RGB_DISABLE_AFTER_TIMEOUT 0 61# define RGB_DISABLE_TIMEOUT (RGB_DISABLE_AFTER_TIMEOUT * 1200)
62#endif
63
64#ifndef RGB_DISABLE_TIMEOUT
65# define RGB_DISABLE_TIMEOUT 0
62#endif 66#endif
63 67
64#ifndef RGB_DISABLE_WHEN_USB_SUSPENDED 68#ifndef RGB_DISABLE_WHEN_USB_SUSPENDED
@@ -111,19 +115,29 @@ const point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;
111# define RGB_MATRIX_STARTUP_SPD UINT8_MAX / 2 115# define RGB_MATRIX_STARTUP_SPD UINT8_MAX / 2
112#endif 116#endif
113 117
114bool g_suspend_state = false; 118// globals
115 119bool g_suspend_state = false;
116rgb_config_t rgb_matrix_config; 120rgb_config_t rgb_matrix_config; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr
117 121uint32_t g_rgb_timer;
118rgb_counters_t g_rgb_counters;
119static uint32_t rgb_counters_buffer;
120
121#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS 122#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
122uint8_t rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}}; 123uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}};
123#endif 124#endif // RGB_MATRIX_FRAMEBUFFER_EFFECTS
125#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
126last_hit_t g_last_hit_tracker;
127#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
124 128
129// internals
130static uint8_t rgb_last_enable = UINT8_MAX;
131static uint8_t rgb_last_effect = UINT8_MAX;
132static effect_params_t rgb_effect_params = {0, 0xFF};
133static rgb_task_states rgb_task_state = SYNCING;
134#if RGB_DISABLE_TIMEOUT > 0
135static uint32_t rgb_anykey_timer;
136#endif // RGB_DISABLE_TIMEOUT > 0
137
138// double buffers
139static uint32_t rgb_timer_buffer;
125#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 140#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
126last_hit_t g_last_hit_tracker;
127static last_hit_t last_hit_buffer; 141static last_hit_t last_hit_buffer;
128#endif // RGB_MATRIX_KEYREACTIVE_ENABLED 142#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
129 143
@@ -169,21 +183,24 @@ void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
169void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { rgb_matrix_driver.set_color_all(red, green, blue); } 183void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { rgb_matrix_driver.set_color_all(red, green, blue); }
170 184
171bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) { 185bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
186#if RGB_DISABLE_TIMEOUT > 0
187 if (record->event.pressed) {
188 rgb_anykey_timer = 0;
189 }
190#endif // RGB_DISABLE_TIMEOUT > 0
191
172#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 192#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
173 uint8_t led[LED_HITS_TO_REMEMBER]; 193 uint8_t led[LED_HITS_TO_REMEMBER];
174 uint8_t led_count = 0; 194 uint8_t led_count = 0;
175 195
176# if defined(RGB_MATRIX_KEYRELEASES) 196# if defined(RGB_MATRIX_KEYRELEASES)
177 if (!record->event.pressed) { 197 if (!record->event.pressed)
178 led_count = rgb_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led);
179 g_rgb_counters.any_key_hit = 0;
180 }
181# elif defined(RGB_MATRIX_KEYPRESSES) 198# elif defined(RGB_MATRIX_KEYPRESSES)
182 if (record->event.pressed) { 199 if (record->event.pressed)
183 led_count = rgb_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led);
184 g_rgb_counters.any_key_hit = 0;
185 }
186# endif // defined(RGB_MATRIX_KEYRELEASES) 200# endif // defined(RGB_MATRIX_KEYRELEASES)
201 {
202 led_count = rgb_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led);
203 }
187 204
188 if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) { 205 if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) {
189 memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count); 206 memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count);
@@ -216,7 +233,7 @@ void rgb_matrix_test(void) {
216 // Mask out bits 4 and 5 233 // Mask out bits 4 and 5
217 // Increase the factor to make the test animation slower (and reduce to make it faster) 234 // Increase the factor to make the test animation slower (and reduce to make it faster)
218 uint8_t factor = 10; 235 uint8_t factor = 10;
219 switch ((g_rgb_counters.tick & (0b11 << factor)) >> factor) { 236 switch ((g_rgb_timer & (0b11 << factor)) >> factor) {
220 case 0: { 237 case 0: {
221 rgb_matrix_set_color_all(20, 0, 0); 238 rgb_matrix_set_color_all(20, 0, 0);
222 break; 239 break;
@@ -241,29 +258,26 @@ static bool rgb_matrix_none(effect_params_t *params) {
241 return false; 258 return false;
242 } 259 }
243 260
244 RGB_MATRIX_USE_LIMITS(led_min, led_max); 261 rgb_matrix_set_color_all(0, 0, 0);
245 for (uint8_t i = led_min; i < led_max; i++) { 262 return false;
246 rgb_matrix_set_color(i, 0, 0, 0);
247 }
248 return led_max < DRIVER_LED_TOTAL;
249} 263}
250 264
251static uint8_t rgb_last_enable = UINT8_MAX;
252static uint8_t rgb_last_effect = UINT8_MAX;
253static effect_params_t rgb_effect_params = {0, 0xFF};
254static rgb_task_states rgb_task_state = SYNCING;
255
256static void rgb_task_timers(void) { 265static void rgb_task_timers(void) {
266#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_DISABLE_TIMEOUT > 0
267 uint32_t deltaTime = timer_elapsed32(rgb_timer_buffer);
268#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_DISABLE_TIMEOUT > 0
269 rgb_timer_buffer = timer_read32();
270
257 // Update double buffer timers 271 // Update double buffer timers
258 uint16_t deltaTime = timer_elapsed32(rgb_counters_buffer); 272#if RGB_DISABLE_TIMEOUT > 0
259 rgb_counters_buffer = timer_read32(); 273 if (rgb_anykey_timer < UINT32_MAX) {
260 if (g_rgb_counters.any_key_hit < UINT32_MAX) { 274 if (UINT32_MAX - deltaTime < rgb_anykey_timer) {
261 if (UINT32_MAX - deltaTime < g_rgb_counters.any_key_hit) { 275 rgb_anykey_timer = UINT32_MAX;
262 g_rgb_counters.any_key_hit = UINT32_MAX;
263 } else { 276 } else {
264 g_rgb_counters.any_key_hit += deltaTime; 277 rgb_anykey_timer += deltaTime;
265 } 278 }
266 } 279 }
280#endif // RGB_DISABLE_TIMEOUT > 0
267 281
268 // Update double buffer last hit timers 282 // Update double buffer last hit timers
269#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 283#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
@@ -280,7 +294,7 @@ static void rgb_task_timers(void) {
280 294
281static void rgb_task_sync(void) { 295static void rgb_task_sync(void) {
282 // next task 296 // next task
283 if (timer_elapsed32(g_rgb_counters.tick) >= RGB_MATRIX_LED_FLUSH_LIMIT) rgb_task_state = STARTING; 297 if (timer_elapsed32(g_rgb_timer) >= RGB_MATRIX_LED_FLUSH_LIMIT) rgb_task_state = STARTING;
284} 298}
285 299
286static void rgb_task_start(void) { 300static void rgb_task_start(void) {
@@ -288,7 +302,7 @@ static void rgb_task_start(void) {
288 rgb_effect_params.iter = 0; 302 rgb_effect_params.iter = 0;
289 303
290 // update double buffers 304 // update double buffers
291 g_rgb_counters.tick = rgb_counters_buffer; 305 g_rgb_timer = rgb_timer_buffer;
292#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 306#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
293 g_last_hit_tracker = last_hit_buffer; 307 g_last_hit_tracker = last_hit_buffer;
294#endif // RGB_MATRIX_KEYREACTIVE_ENABLED 308#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
@@ -370,8 +384,16 @@ void rgb_matrix_task(void) {
370 384
371 // Ideally we would also stop sending zeros to the LED driver PWM buffers 385 // Ideally we would also stop sending zeros to the LED driver PWM buffers
372 // while suspended and just do a software shutdown. This is a cheap hack for now. 386 // while suspended and just do a software shutdown. This is a cheap hack for now.
373 bool suspend_backlight = ((g_suspend_state && RGB_DISABLE_WHEN_USB_SUSPENDED) || (RGB_DISABLE_AFTER_TIMEOUT > 0 && g_rgb_counters.any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20)); 387 bool suspend_backlight =
374 uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode; 388#if RGB_DISABLE_WHEN_USB_SUSPENDED == true
389 g_suspend_state ||
390#endif // RGB_DISABLE_WHEN_USB_SUSPENDED == true
391#if RGB_DISABLE_TIMEOUT > 0
392 (rgb_anykey_timer > (uint32_t)RGB_DISABLE_TIMEOUT) ||
393#endif // RGB_DISABLE_TIMEOUT > 0
394 false;
395
396 uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode;
375 397
376 switch (rgb_task_state) { 398 switch (rgb_task_state) {
377 case STARTING: 399 case STARTING:
@@ -405,8 +427,6 @@ __attribute__((weak)) void rgb_matrix_indicators_user(void) {}
405void rgb_matrix_init(void) { 427void rgb_matrix_init(void) {
406 rgb_matrix_driver.init(); 428 rgb_matrix_driver.init();
407 429
408 // TODO: put the 1 second startup delay here?
409
410#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 430#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
411 g_last_hit_tracker.count = 0; 431 g_last_hit_tracker.count = 0;
412 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { 432 for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) {
@@ -440,6 +460,8 @@ void rgb_matrix_set_suspend_state(bool state) {
440 g_suspend_state = state; 460 g_suspend_state = state;
441} 461}
442 462
463bool rgb_matrix_get_suspend_state(void) { return g_suspend_state; }
464
443void rgb_matrix_toggle(void) { 465void rgb_matrix_toggle(void) {
444 rgb_matrix_config.enable ^= 1; 466 rgb_matrix_config.enable ^= 1;
445 rgb_task_state = STARTING; 467 rgb_task_state = STARTING;
@@ -466,6 +488,8 @@ void rgb_matrix_disable_noeeprom(void) {
466 rgb_matrix_config.enable = 0; 488 rgb_matrix_config.enable = 0;
467} 489}
468 490
491uint8_t rgb_matrix_is_enabled(void) { return rgb_matrix_config.enable; }
492
469void rgb_matrix_step(void) { 493void rgb_matrix_step(void) {
470 rgb_matrix_config.mode++; 494 rgb_matrix_config.mode++;
471 if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX) rgb_matrix_config.mode = 1; 495 if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX) rgb_matrix_config.mode = 1;
@@ -521,6 +545,8 @@ void rgb_matrix_decrease_speed(void) {
521 eeconfig_update_rgb_matrix(); 545 eeconfig_update_rgb_matrix();
522} 546}
523 547
548uint8_t rgb_matrix_get_speed(void) { return rgb_matrix_config.speed; }
549
524led_flags_t rgb_matrix_get_flags(void) { return rgb_effect_params.flags; } 550led_flags_t rgb_matrix_get_flags(void) { return rgb_effect_params.flags; }
525 551
526void rgb_matrix_set_flags(led_flags_t flags) { rgb_effect_params.flags = flags; } 552void rgb_matrix_set_flags(led_flags_t flags) { rgb_effect_params.flags = flags; }
@@ -546,3 +572,8 @@ void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) {
546 rgb_matrix_config.hsv.v = val; 572 rgb_matrix_config.hsv.v = val;
547 if (rgb_matrix_config.hsv.v > RGB_MATRIX_MAXIMUM_BRIGHTNESS) rgb_matrix_config.hsv.v = RGB_MATRIX_MAXIMUM_BRIGHTNESS; 573 if (rgb_matrix_config.hsv.v > RGB_MATRIX_MAXIMUM_BRIGHTNESS) rgb_matrix_config.hsv.v = RGB_MATRIX_MAXIMUM_BRIGHTNESS;
548} 574}
575
576HSV rgb_matrix_get_hsv(void) { return rgb_matrix_config.hsv; }
577uint8_t rgb_matrix_get_hue(void) { return rgb_matrix_config.hsv.h; }
578uint8_t rgb_matrix_get_sat(void) { return rgb_matrix_config.hsv.s; }
579uint8_t rgb_matrix_get_val(void) { return rgb_matrix_config.hsv.v; }
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index 96494836e..d9ce39106 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -104,11 +104,13 @@ void rgb_matrix_indicators_user(void);
104void rgb_matrix_init(void); 104void rgb_matrix_init(void);
105 105
106void rgb_matrix_set_suspend_state(bool state); 106void rgb_matrix_set_suspend_state(bool state);
107bool rgb_matrix_get_suspend_state(void);
107void rgb_matrix_toggle(void); 108void rgb_matrix_toggle(void);
108void rgb_matrix_enable(void); 109void rgb_matrix_enable(void);
109void rgb_matrix_enable_noeeprom(void); 110void rgb_matrix_enable_noeeprom(void);
110void rgb_matrix_disable(void); 111void rgb_matrix_disable(void);
111void rgb_matrix_disable_noeeprom(void); 112void rgb_matrix_disable_noeeprom(void);
113uint8_t rgb_matrix_is_enabled(void);
112void rgb_matrix_step(void); 114void rgb_matrix_step(void);
113void rgb_matrix_step_reverse(void); 115void rgb_matrix_step_reverse(void);
114void rgb_matrix_increase_hue(void); 116void rgb_matrix_increase_hue(void);
@@ -119,6 +121,7 @@ void rgb_matrix_increase_val(void);
119void rgb_matrix_decrease_val(void); 121void rgb_matrix_decrease_val(void);
120void rgb_matrix_increase_speed(void); 122void rgb_matrix_increase_speed(void);
121void rgb_matrix_decrease_speed(void); 123void rgb_matrix_decrease_speed(void);
124uint8_t rgb_matrix_get_speed(void);
122led_flags_t rgb_matrix_get_flags(void); 125led_flags_t rgb_matrix_get_flags(void);
123void rgb_matrix_set_flags(led_flags_t flags); 126void rgb_matrix_set_flags(led_flags_t flags);
124void rgb_matrix_mode(uint8_t mode); 127void rgb_matrix_mode(uint8_t mode);
@@ -126,6 +129,10 @@ void rgb_matrix_mode_noeeprom(uint8_t mode);
126uint8_t rgb_matrix_get_mode(void); 129uint8_t rgb_matrix_get_mode(void);
127void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val); 130void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val);
128void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); 131void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
132HSV rgb_matrix_get_hsv(void);
133uint8_t rgb_matrix_get_hue(void);
134uint8_t rgb_matrix_get_sat(void);
135uint8_t rgb_matrix_get_val(void);
129 136
130#ifndef RGBLIGHT_ENABLE 137#ifndef RGBLIGHT_ENABLE
131# define rgblight_toggle rgb_matrix_toggle 138# define rgblight_toggle rgb_matrix_toggle
@@ -133,6 +140,7 @@ void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
133# define rgblight_enable_noeeprom rgb_matrix_enable_noeeprom 140# define rgblight_enable_noeeprom rgb_matrix_enable_noeeprom
134# define rgblight_disable rgb_matrix_disable 141# define rgblight_disable rgb_matrix_disable
135# define rgblight_disable_noeeprom rgb_matrix_disable_noeeprom 142# define rgblight_disable_noeeprom rgb_matrix_disable_noeeprom
143# define rgblight_is_enabled rgb_matrix_is_enabled
136# define rgblight_step rgb_matrix_step 144# define rgblight_step rgb_matrix_step
137# define rgblight_sethsv rgb_matrix_sethsv 145# define rgblight_sethsv rgb_matrix_sethsv
138# define rgblight_sethsv_noeeprom rgb_matrix_sethsv_noeeprom 146# define rgblight_sethsv_noeeprom rgb_matrix_sethsv_noeeprom
@@ -145,9 +153,14 @@ void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
145# define rgblight_decrease_val rgb_matrix_decrease_val 153# define rgblight_decrease_val rgb_matrix_decrease_val
146# define rgblight_increase_speed rgb_matrix_increase_speed 154# define rgblight_increase_speed rgb_matrix_increase_speed
147# define rgblight_decrease_speed rgb_matrix_decrease_speed 155# define rgblight_decrease_speed rgb_matrix_decrease_speed
156# define rgblight_get_speed rgb_matrix_get_speed
148# define rgblight_mode rgb_matrix_mode 157# define rgblight_mode rgb_matrix_mode
149# define rgblight_mode_noeeprom rgb_matrix_mode_noeeprom 158# define rgblight_mode_noeeprom rgb_matrix_mode_noeeprom
150# define rgblight_get_mode rgb_matrix_get_mode 159# define rgblight_get_mode rgb_matrix_get_mode
160# define rgblight_get_hue rgb_matrix_get_hue
161# define rgblight_get_sat rgb_matrix_get_sat
162# define rgblight_get_val rgb_matrix_get_val
163# define rgblight_get_hsv rgb_matrix_get_hsv
151#endif 164#endif
152 165
153typedef struct { 166typedef struct {
@@ -165,14 +178,14 @@ extern const rgb_matrix_driver_t rgb_matrix_driver;
165 178
166extern rgb_config_t rgb_matrix_config; 179extern rgb_config_t rgb_matrix_config;
167 180
168extern bool g_suspend_state; 181extern bool g_suspend_state;
169extern rgb_counters_t g_rgb_counters; 182extern uint32_t g_rgb_timer;
170extern led_config_t g_led_config; 183extern led_config_t g_led_config;
171#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED 184#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
172extern last_hit_t g_last_hit_tracker; 185extern last_hit_t g_last_hit_tracker;
173#endif 186#endif
174#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS 187#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS
175extern uint8_t rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS]; 188extern uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS];
176#endif 189#endif
177 190
178#endif 191#endif
diff --git a/quantum/rgb_matrix_animations/breathing_anim.h b/quantum/rgb_matrix_animations/breathing_anim.h
index 92431555e..887425f9d 100644
--- a/quantum/rgb_matrix_animations/breathing_anim.h
+++ b/quantum/rgb_matrix_animations/breathing_anim.h
@@ -6,7 +6,7 @@ bool BREATHING(effect_params_t* params) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max); 6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7 7
8 HSV hsv = rgb_matrix_config.hsv; 8 HSV hsv = rgb_matrix_config.hsv;
9 uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 8); 9 uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
10 hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v); 10 hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
11 RGB rgb = hsv_to_rgb(hsv); 11 RGB rgb = hsv_to_rgb(hsv);
12 for (uint8_t i = led_min; i < led_max; i++) { 12 for (uint8_t i = led_min; i < led_max; i++) {
diff --git a/quantum/rgb_matrix_animations/digital_rain_anim.h b/quantum/rgb_matrix_animations/digital_rain_anim.h
index 7a4a52db1..1de45f8e8 100644
--- a/quantum/rgb_matrix_animations/digital_rain_anim.h
+++ b/quantum/rgb_matrix_animations/digital_rain_anim.h
@@ -18,7 +18,7 @@ bool DIGITAL_RAIN(effect_params_t* params) {
18 18
19 if (params->init) { 19 if (params->init) {
20 rgb_matrix_set_color_all(0, 0, 0); 20 rgb_matrix_set_color_all(0, 0, 0);
21 memset(rgb_frame_buffer, 0, sizeof(rgb_frame_buffer)); 21 memset(g_rgb_frame_buffer, 0, sizeof(g_rgb_frame_buffer));
22 drop = 0; 22 drop = 0;
23 } 23 }
24 24
@@ -27,10 +27,10 @@ bool DIGITAL_RAIN(effect_params_t* params) {
27 if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) { 27 if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
28 // top row, pixels have just fallen and we're 28 // top row, pixels have just fallen and we're
29 // making a new rain drop in this column 29 // making a new rain drop in this column
30 rgb_frame_buffer[row][col] = max_intensity; 30 g_rgb_frame_buffer[row][col] = max_intensity;
31 } else if (rgb_frame_buffer[row][col] > 0 && rgb_frame_buffer[row][col] < max_intensity) { 31 } else if (g_rgb_frame_buffer[row][col] > 0 && g_rgb_frame_buffer[row][col] < max_intensity) {
32 // neither fully bright nor dark, decay it 32 // neither fully bright nor dark, decay it
33 rgb_frame_buffer[row][col]--; 33 g_rgb_frame_buffer[row][col]--;
34 } 34 }
35 // set the pixel colour 35 // set the pixel colour
36 uint8_t led[LED_HITS_TO_REMEMBER]; 36 uint8_t led[LED_HITS_TO_REMEMBER];
@@ -38,11 +38,11 @@ bool DIGITAL_RAIN(effect_params_t* params) {
38 38
39 // TODO: multiple leds are supported mapped to the same row/column 39 // TODO: multiple leds are supported mapped to the same row/column
40 if (led_count > 0) { 40 if (led_count > 0) {
41 if (rgb_frame_buffer[row][col] > pure_green_intensity) { 41 if (g_rgb_frame_buffer[row][col] > pure_green_intensity) {
42 const uint8_t boost = (uint8_t)((uint16_t)max_brightness_boost * (rgb_frame_buffer[row][col] - pure_green_intensity) / (max_intensity - pure_green_intensity)); 42 const uint8_t boost = (uint8_t)((uint16_t)max_brightness_boost * (g_rgb_frame_buffer[row][col] - pure_green_intensity) / (max_intensity - pure_green_intensity));
43 rgb_matrix_set_color(led[0], boost, max_intensity, boost); 43 rgb_matrix_set_color(led[0], boost, max_intensity, boost);
44 } else { 44 } else {
45 const uint8_t green = (uint8_t)((uint16_t)max_intensity * rgb_frame_buffer[row][col] / pure_green_intensity); 45 const uint8_t green = (uint8_t)((uint16_t)max_intensity * g_rgb_frame_buffer[row][col] / pure_green_intensity);
46 rgb_matrix_set_color(led[0], 0, green, 0); 46 rgb_matrix_set_color(led[0], 0, green, 0);
47 } 47 }
48 } 48 }
@@ -55,15 +55,15 @@ bool DIGITAL_RAIN(effect_params_t* params) {
55 for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) { 55 for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
56 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 56 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
57 // if ths is on the bottom row and bright allow decay 57 // if ths is on the bottom row and bright allow decay
58 if (row == MATRIX_ROWS - 1 && rgb_frame_buffer[row][col] == max_intensity) { 58 if (row == MATRIX_ROWS - 1 && g_rgb_frame_buffer[row][col] == max_intensity) {
59 rgb_frame_buffer[row][col]--; 59 g_rgb_frame_buffer[row][col]--;
60 } 60 }
61 // check if the pixel above is bright 61 // check if the pixel above is bright
62 if (rgb_frame_buffer[row - 1][col] == max_intensity) { 62 if (g_rgb_frame_buffer[row - 1][col] == max_intensity) {
63 // allow old bright pixel to decay 63 // allow old bright pixel to decay
64 rgb_frame_buffer[row - 1][col]--; 64 g_rgb_frame_buffer[row - 1][col]--;
65 // make this pixel bright 65 // make this pixel bright
66 rgb_frame_buffer[row][col] = max_intensity; 66 g_rgb_frame_buffer[row][col] = max_intensity;
67 } 67 }
68 } 68 }
69 } 69 }
diff --git a/quantum/rgb_matrix_animations/jellybean_raindrops_anim.h b/quantum/rgb_matrix_animations/jellybean_raindrops_anim.h
index 5596146a3..ef2d1500b 100644
--- a/quantum/rgb_matrix_animations/jellybean_raindrops_anim.h
+++ b/quantum/rgb_matrix_animations/jellybean_raindrops_anim.h
@@ -12,7 +12,7 @@ static void jellybean_raindrops_set_color(int i, effect_params_t* params) {
12bool JELLYBEAN_RAINDROPS(effect_params_t* params) { 12bool JELLYBEAN_RAINDROPS(effect_params_t* params) {
13 if (!params->init) { 13 if (!params->init) {
14 // Change one LED every tick, make sure speed is not 0 14 // Change one LED every tick, make sure speed is not 0
15 if (scale16by8(g_rgb_counters.tick, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) { 15 if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) {
16 jellybean_raindrops_set_color(rand() % DRIVER_LED_TOTAL, params); 16 jellybean_raindrops_set_color(rand() % DRIVER_LED_TOTAL, params);
17 } 17 }
18 return false; 18 return false;
diff --git a/quantum/rgb_matrix_animations/raindrops_anim.h b/quantum/rgb_matrix_animations/raindrops_anim.h
index 9f839a1bc..6e1b5acb0 100644
--- a/quantum/rgb_matrix_animations/raindrops_anim.h
+++ b/quantum/rgb_matrix_animations/raindrops_anim.h
@@ -22,7 +22,7 @@ static void raindrops_set_color(int i, effect_params_t* params) {
22bool RAINDROPS(effect_params_t* params) { 22bool RAINDROPS(effect_params_t* params) {
23 if (!params->init) { 23 if (!params->init) {
24 // Change one LED every tick, make sure speed is not 0 24 // Change one LED every tick, make sure speed is not 0
25 if (scale16by8(g_rgb_counters.tick, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) { 25 if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) {
26 raindrops_set_color(rand() % DRIVER_LED_TOTAL, params); 26 raindrops_set_color(rand() % DRIVER_LED_TOTAL, params);
27 } 27 }
28 return false; 28 return false;
diff --git a/quantum/rgb_matrix_animations/typing_heatmap_anim.h b/quantum/rgb_matrix_animations/typing_heatmap_anim.h
index dd313f16a..e82c1b49e 100644
--- a/quantum/rgb_matrix_animations/typing_heatmap_anim.h
+++ b/quantum/rgb_matrix_animations/typing_heatmap_anim.h
@@ -10,20 +10,20 @@ void process_rgb_matrix_typing_heatmap(keyrecord_t* record) {
10 uint8_t m_col = col - 1; 10 uint8_t m_col = col - 1;
11 uint8_t p_col = col + 1; 11 uint8_t p_col = col + 1;
12 12
13 if (m_col < col) rgb_frame_buffer[row][m_col] = qadd8(rgb_frame_buffer[row][m_col], 16); 13 if (m_col < col) g_rgb_frame_buffer[row][m_col] = qadd8(g_rgb_frame_buffer[row][m_col], 16);
14 rgb_frame_buffer[row][col] = qadd8(rgb_frame_buffer[row][col], 32); 14 g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], 32);
15 if (p_col < MATRIX_COLS) rgb_frame_buffer[row][p_col] = qadd8(rgb_frame_buffer[row][p_col], 16); 15 if (p_col < MATRIX_COLS) g_rgb_frame_buffer[row][p_col] = qadd8(g_rgb_frame_buffer[row][p_col], 16);
16 16
17 if (p_row < MATRIX_ROWS) { 17 if (p_row < MATRIX_ROWS) {
18 if (m_col < col) rgb_frame_buffer[p_row][m_col] = qadd8(rgb_frame_buffer[p_row][m_col], 13); 18 if (m_col < col) g_rgb_frame_buffer[p_row][m_col] = qadd8(g_rgb_frame_buffer[p_row][m_col], 13);
19 rgb_frame_buffer[p_row][col] = qadd8(rgb_frame_buffer[p_row][col], 16); 19 g_rgb_frame_buffer[p_row][col] = qadd8(g_rgb_frame_buffer[p_row][col], 16);
20 if (p_col < MATRIX_COLS) rgb_frame_buffer[p_row][p_col] = qadd8(rgb_frame_buffer[p_row][p_col], 13); 20 if (p_col < MATRIX_COLS) g_rgb_frame_buffer[p_row][p_col] = qadd8(g_rgb_frame_buffer[p_row][p_col], 13);
21 } 21 }
22 22
23 if (m_row < row) { 23 if (m_row < row) {
24 if (m_col < col) rgb_frame_buffer[m_row][m_col] = qadd8(rgb_frame_buffer[m_row][m_col], 13); 24 if (m_col < col) g_rgb_frame_buffer[m_row][m_col] = qadd8(g_rgb_frame_buffer[m_row][m_col], 13);
25 rgb_frame_buffer[m_row][col] = qadd8(rgb_frame_buffer[m_row][col], 16); 25 g_rgb_frame_buffer[m_row][col] = qadd8(g_rgb_frame_buffer[m_row][col], 16);
26 if (p_col < MATRIX_COLS) rgb_frame_buffer[m_row][p_col] = qadd8(rgb_frame_buffer[m_row][p_col], 13); 26 if (p_col < MATRIX_COLS) g_rgb_frame_buffer[m_row][p_col] = qadd8(g_rgb_frame_buffer[m_row][p_col], 13);
27 } 27 }
28} 28}
29 29
@@ -31,18 +31,18 @@ bool TYPING_HEATMAP(effect_params_t* params) {
31 // Modified version of RGB_MATRIX_USE_LIMITS to work off of matrix row / col size 31 // Modified version of RGB_MATRIX_USE_LIMITS to work off of matrix row / col size
32 uint8_t led_min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter; 32 uint8_t led_min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter;
33 uint8_t led_max = led_min + RGB_MATRIX_LED_PROCESS_LIMIT; 33 uint8_t led_max = led_min + RGB_MATRIX_LED_PROCESS_LIMIT;
34 if (led_max > sizeof(rgb_frame_buffer)) led_max = sizeof(rgb_frame_buffer); 34 if (led_max > sizeof(g_rgb_frame_buffer)) led_max = sizeof(g_rgb_frame_buffer);
35 35
36 if (params->init) { 36 if (params->init) {
37 rgb_matrix_set_color_all(0, 0, 0); 37 rgb_matrix_set_color_all(0, 0, 0);
38 memset(rgb_frame_buffer, 0, sizeof rgb_frame_buffer); 38 memset(g_rgb_frame_buffer, 0, sizeof g_rgb_frame_buffer);
39 } 39 }
40 40
41 // Render heatmap & decrease 41 // Render heatmap & decrease
42 for (int i = led_min; i < led_max; i++) { 42 for (int i = led_min; i < led_max; i++) {
43 uint8_t row = i % MATRIX_ROWS; 43 uint8_t row = i % MATRIX_ROWS;
44 uint8_t col = i / MATRIX_ROWS; 44 uint8_t col = i / MATRIX_ROWS;
45 uint8_t val = rgb_frame_buffer[row][col]; 45 uint8_t val = g_rgb_frame_buffer[row][col];
46 46
47 // set the pixel colour 47 // set the pixel colour
48 uint8_t led[LED_HITS_TO_REMEMBER]; 48 uint8_t led[LED_HITS_TO_REMEMBER];
@@ -55,10 +55,10 @@ bool TYPING_HEATMAP(effect_params_t* params) {
55 rgb_matrix_set_color(led[j], rgb.r, rgb.g, rgb.b); 55 rgb_matrix_set_color(led[j], rgb.r, rgb.g, rgb.b);
56 } 56 }
57 57
58 rgb_frame_buffer[row][col] = qsub8(val, 1); 58 g_rgb_frame_buffer[row][col] = qsub8(val, 1);
59 } 59 }
60 60
61 return led_max < sizeof(rgb_frame_buffer); 61 return led_max < sizeof(g_rgb_frame_buffer);
62} 62}
63 63
64# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS 64# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
diff --git a/quantum/rgb_matrix_runners/effect_runner_dx_dy.h b/quantum/rgb_matrix_runners/effect_runner_dx_dy.h
index 3d312190a..9d0c9fab1 100644
--- a/quantum/rgb_matrix_runners/effect_runner_dx_dy.h
+++ b/quantum/rgb_matrix_runners/effect_runner_dx_dy.h
@@ -5,7 +5,7 @@ typedef HSV (*dx_dy_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t time);
5bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) { 5bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max); 6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7 7
8 uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2); 8 uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 2);
9 for (uint8_t i = led_min; i < led_max; i++) { 9 for (uint8_t i = led_min; i < led_max; i++) {
10 RGB_MATRIX_TEST_LED_FLAGS(); 10 RGB_MATRIX_TEST_LED_FLAGS();
11 int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x; 11 int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x;
diff --git a/quantum/rgb_matrix_runners/effect_runner_dx_dy_dist.h b/quantum/rgb_matrix_runners/effect_runner_dx_dy_dist.h
index 1f4767e32..2824c8252 100644
--- a/quantum/rgb_matrix_runners/effect_runner_dx_dy_dist.h
+++ b/quantum/rgb_matrix_runners/effect_runner_dx_dy_dist.h
@@ -5,7 +5,7 @@ typedef HSV (*dx_dy_dist_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8
5bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) { 5bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max); 6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7 7
8 uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 2); 8 uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 2);
9 for (uint8_t i = led_min; i < led_max; i++) { 9 for (uint8_t i = led_min; i < led_max; i++) {
10 RGB_MATRIX_TEST_LED_FLAGS(); 10 RGB_MATRIX_TEST_LED_FLAGS();
11 int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x; 11 int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x;
diff --git a/quantum/rgb_matrix_runners/effect_runner_i.h b/quantum/rgb_matrix_runners/effect_runner_i.h
index eebfb78c0..5e6bf5daa 100644
--- a/quantum/rgb_matrix_runners/effect_runner_i.h
+++ b/quantum/rgb_matrix_runners/effect_runner_i.h
@@ -5,7 +5,7 @@ typedef HSV (*i_f)(HSV hsv, uint8_t i, uint8_t time);
5bool effect_runner_i(effect_params_t* params, i_f effect_func) { 5bool effect_runner_i(effect_params_t* params, i_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max); 6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7 7
8 uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4); 8 uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 4);
9 for (uint8_t i = led_min; i < led_max; i++) { 9 for (uint8_t i = led_min; i < led_max; i++) {
10 RGB_MATRIX_TEST_LED_FLAGS(); 10 RGB_MATRIX_TEST_LED_FLAGS();
11 RGB rgb = hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time)); 11 RGB rgb = hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time));
diff --git a/quantum/rgb_matrix_runners/effect_runner_sin_cos_i.h b/quantum/rgb_matrix_runners/effect_runner_sin_cos_i.h
index c02352b86..3fb7d4805 100644
--- a/quantum/rgb_matrix_runners/effect_runner_sin_cos_i.h
+++ b/quantum/rgb_matrix_runners/effect_runner_sin_cos_i.h
@@ -5,7 +5,7 @@ typedef HSV (*sin_cos_i_f)(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t t
5bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) { 5bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max); 6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7 7
8 uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4); 8 uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 4);
9 int8_t cos_value = cos8(time) - 128; 9 int8_t cos_value = cos8(time) - 128;
10 int8_t sin_value = sin8(time) - 128; 10 int8_t sin_value = sin8(time) - 128;
11 for (uint8_t i = led_min; i < led_max; i++) { 11 for (uint8_t i = led_min; i < led_max; i++) {
diff --git a/quantum/rgb_matrix_types.h b/quantum/rgb_matrix_types.h
index fc23f55d0..f447ac9c5 100644
--- a/quantum/rgb_matrix_types.h
+++ b/quantum/rgb_matrix_types.h
@@ -44,13 +44,6 @@ typedef struct PACKED {
44} effect_params_t; 44} effect_params_t;
45 45
46typedef struct PACKED { 46typedef struct PACKED {
47 // Global tick at 20 Hz
48 uint32_t tick;
49 // Ticks since this key was last hit.
50 uint32_t any_key_hit;
51} rgb_counters_t;
52
53typedef struct PACKED {
54 uint8_t x; 47 uint8_t x;
55 uint8_t y; 48 uint8_t y;
56} point_t; 49} point_t;
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 26cb41a96..d33484ccf 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -15,6 +15,7 @@
15 */ 15 */
16#include <math.h> 16#include <math.h>
17#include <string.h> 17#include <string.h>
18#include <stdlib.h>
18#ifdef __AVR__ 19#ifdef __AVR__
19# include <avr/eeprom.h> 20# include <avr/eeprom.h>
20# include <avr/interrupt.h> 21# include <avr/interrupt.h>
@@ -367,6 +368,8 @@ void rgblight_disable_noeeprom(void) {
367 rgblight_set(); 368 rgblight_set();
368} 369}
369 370
371bool rgblight_is_enabled(void) { return rgblight_config.enable; }
372
370void rgblight_increase_hue_helper(bool write_to_eeprom) { 373void rgblight_increase_hue_helper(bool write_to_eeprom) {
371 uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP; 374 uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP;
372 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom); 375 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
@@ -521,6 +524,8 @@ uint8_t rgblight_get_sat(void) { return rgblight_config.sat; }
521 524
522uint8_t rgblight_get_val(void) { return rgblight_config.val; } 525uint8_t rgblight_get_val(void) { return rgblight_config.val; }
523 526
527HSV rgblight_get_hsv(void) { return (HSV){rgblight_config.hue, rgblight_config.sat, rgblight_config.val}; }
528
524void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { 529void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
525 if (!rgblight_config.enable) { 530 if (!rgblight_config.enable) {
526 return; 531 return;
@@ -561,7 +566,7 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
561 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); 566 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
562} 567}
563 568
564#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) 569#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE)
565 570
566static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) { 571static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
567 return 572 return
@@ -612,7 +617,7 @@ void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_set
612 617
613#ifdef RGBLIGHT_LAYERS 618#ifdef RGBLIGHT_LAYERS
614void rgblight_set_layer_state(uint8_t layer, bool enabled) { 619void rgblight_set_layer_state(uint8_t layer, bool enabled) {
615 uint8_t mask = 1 << layer; 620 rgblight_layer_mask_t mask = 1 << layer;
616 if (enabled) { 621 if (enabled) {
617 rgblight_status.enabled_layer_mask |= mask; 622 rgblight_status.enabled_layer_mask |= mask;
618 } else { 623 } else {
@@ -623,10 +628,17 @@ void rgblight_set_layer_state(uint8_t layer, bool enabled) {
623 if (rgblight_status.timer_enabled == false) { 628 if (rgblight_status.timer_enabled == false) {
624 rgblight_mode_noeeprom(rgblight_config.mode); 629 rgblight_mode_noeeprom(rgblight_config.mode);
625 } 630 }
631
632# ifdef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF
633 // If not enabled, then nothing else will actually set the LEDs...
634 if (!rgblight_config.enable) {
635 rgblight_set();
636 }
637# endif
626} 638}
627 639
628bool rgblight_get_layer_state(uint8_t layer) { 640bool rgblight_get_layer_state(uint8_t layer) {
629 uint8_t mask = 1 << layer; 641 rgblight_layer_mask_t mask = 1 << layer;
630 return (rgblight_status.enabled_layer_mask & mask) != 0; 642 return (rgblight_status.enabled_layer_mask & mask) != 0;
631} 643}
632 644
@@ -658,21 +670,41 @@ static void rgblight_layers_write(void) {
658 } 670 }
659 } 671 }
660} 672}
673
674# ifdef RGBLIGHT_LAYER_BLINK
675rgblight_layer_mask_t _blinked_layer_mask = 0;
676uint16_t _blink_duration = 0;
677static uint16_t _blink_timer;
678
679void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) {
680 rgblight_set_layer_state(layer, true);
681 _blinked_layer_mask |= 1 << layer;
682 _blink_timer = timer_read();
683 _blink_duration = duration_ms;
684}
685
686void rgblight_unblink_layers(void) {
687 if (_blinked_layer_mask != 0 && timer_elapsed(_blink_timer) > _blink_duration) {
688 for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) {
689 if ((_blinked_layer_mask & 1 << layer) != 0) {
690 rgblight_set_layer_state(layer, false);
691 }
692 }
693 _blinked_layer_mask = 0;
694 }
695}
696# endif
697
661#endif 698#endif
662 699
663__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); } 700__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); }
664 701
665#ifndef RGBLIGHT_CUSTOM_DRIVER 702#ifndef RGBLIGHT_CUSTOM_DRIVER
703
666void rgblight_set(void) { 704void rgblight_set(void) {
667 LED_TYPE *start_led; 705 LED_TYPE *start_led;
668 uint8_t num_leds = rgblight_ranges.clipping_num_leds; 706 uint8_t num_leds = rgblight_ranges.clipping_num_leds;
669 707
670# ifdef RGBLIGHT_LAYERS
671 if (rgblight_layers != NULL) {
672 rgblight_layers_write();
673 }
674# endif
675
676 if (!rgblight_config.enable) { 708 if (!rgblight_config.enable) {
677 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { 709 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
678 led[i].r = 0; 710 led[i].r = 0;
@@ -684,6 +716,16 @@ void rgblight_set(void) {
684 } 716 }
685 } 717 }
686 718
719# ifdef RGBLIGHT_LAYERS
720 if (rgblight_layers != NULL
721# ifndef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF
722 && rgblight_config.enable
723# endif
724 ) {
725 rgblight_layers_write();
726 }
727# endif
728
687# ifdef RGBLIGHT_LED_MAP 729# ifdef RGBLIGHT_LED_MAP
688 LED_TYPE led0[RGBLED_NUM]; 730 LED_TYPE led0[RGBLED_NUM];
689 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 731 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
@@ -880,6 +922,12 @@ void rgblight_task(void) {
880 effect_func = (effect_func_t)rgblight_effect_alternating; 922 effect_func = (effect_func_t)rgblight_effect_alternating;
881 } 923 }
882# endif 924# endif
925# ifdef RGBLIGHT_EFFECT_TWINKLE
926 else if (rgblight_status.base_mode == RGBLIGHT_MODE_TWINKLE) {
927 interval_time = get_interval_time(&RGBLED_TWINKLE_INTERVALS[delta % 3], 5, 50);
928 effect_func = (effect_func_t)rgblight_effect_twinkle;
929 }
930# endif
883 if (animation_status.restart) { 931 if (animation_status.restart) {
884 animation_status.restart = false; 932 animation_status.restart = false;
885 animation_status.last_timer = timer_read() - interval_time - 1; 933 animation_status.last_timer = timer_read() - interval_time - 1;
@@ -909,6 +957,10 @@ void rgblight_task(void) {
909# endif 957# endif
910 } 958 }
911 } 959 }
960
961# ifdef RGBLIGHT_LAYER_BLINK
962 rgblight_unblink_layers();
963# endif
912} 964}
913 965
914#endif /* RGBLIGHT_USE_TIMER */ 966#endif /* RGBLIGHT_USE_TIMER */
@@ -1160,3 +1212,58 @@ void rgblight_effect_alternating(animation_status_t *anim) {
1160 anim->pos = (anim->pos + 1) % 2; 1212 anim->pos = (anim->pos + 1) % 2;
1161} 1213}
1162#endif 1214#endif
1215
1216#ifdef RGBLIGHT_EFFECT_TWINKLE
1217__attribute__((weak)) const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {50, 25, 10};
1218
1219typedef struct PACKED {
1220 HSV hsv;
1221 uint8_t life;
1222 bool up;
1223} TwinkleState;
1224
1225static TwinkleState led_twinkle_state[RGBLED_NUM];
1226
1227void rgblight_effect_twinkle(animation_status_t *anim) {
1228 bool random_color = anim->delta / 3;
1229 bool restart = anim->pos == 0;
1230 anim->pos = 1;
1231
1232 for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1233 TwinkleState *t = &(led_twinkle_state[i]);
1234 HSV * c = &(t->hsv);
1235 if (restart) {
1236 // Restart
1237 t->life = 0;
1238 t->hsv.v = 0;
1239 } else if (t->life) {
1240 // This LED is already on, either brightening or dimming
1241 t->life--;
1242 uint8_t on = t->up ? RGBLIGHT_EFFECT_TWINKLE_LIFE - t->life : t->life;
1243 c->v = (uint16_t)rgblight_config.val * on / RGBLIGHT_EFFECT_TWINKLE_LIFE;
1244 if (t->life == 0 && t->up) {
1245 t->up = false;
1246 t->life = RGBLIGHT_EFFECT_TWINKLE_LIFE;
1247 }
1248 if (!random_color) {
1249 c->h = rgblight_config.hue;
1250 c->s = rgblight_config.sat;
1251 }
1252 } else if (rand() < RAND_MAX * RGBLIGHT_EFFECT_TWINKLE_PROBABILITY) {
1253 // This LED is off, but was randomly selected to start brightening
1254 c->h = random_color ? rand() % 0xFF : rgblight_config.hue;
1255 c->s = random_color ? (rand() % (rgblight_config.sat / 2)) + (rgblight_config.sat / 2) : rgblight_config.sat;
1256 c->v = 0;
1257 t->life = RGBLIGHT_EFFECT_TWINKLE_LIFE;
1258 t->up = true;
1259 } else {
1260 // This LED is off, and was NOT selected to start brightening
1261 }
1262
1263 LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos;
1264 sethsv(c->h, c->s, c->v, ledp);
1265 }
1266
1267 rgblight_set();
1268}
1269#endif
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index b1585b158..c36b328a3 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -59,6 +59,12 @@
59| 34 | RGBLIGHT_MODE_STATIC_GRADIENT + 9 | 59| 34 | RGBLIGHT_MODE_STATIC_GRADIENT + 9 |
60| 35 | RGBLIGHT_MODE_RGB_TEST | 60| 35 | RGBLIGHT_MODE_RGB_TEST |
61| 36 | RGBLIGHT_MODE_ALTERNATING | 61| 36 | RGBLIGHT_MODE_ALTERNATING |
62| 37 | RGBLIGHT_MODE_TWINKLE |
63| 38 | RGBLIGHT_MODE_TWINKLE + 1 |
64| 39 | RGBLIGHT_MODE_TWINKLE + 2 |
65| 40 | RGBLIGHT_MODE_TWINKLE + 3 |
66| 41 | RGBLIGHT_MODE_TWINKLE + 4 |
67| 42 | RGBLIGHT_MODE_TWINKLE + 5 |
62|-----------------|-----------------------------------| 68|-----------------|-----------------------------------|
63 *****/ 69 *****/
64 70
@@ -73,6 +79,7 @@
73# define RGBLIGHT_EFFECT_STATIC_GRADIENT 79# define RGBLIGHT_EFFECT_STATIC_GRADIENT
74# define RGBLIGHT_EFFECT_RGB_TEST 80# define RGBLIGHT_EFFECT_RGB_TEST
75# define RGBLIGHT_EFFECT_ALTERNATING 81# define RGBLIGHT_EFFECT_ALTERNATING
82# define RGBLIGHT_EFFECT_TWINKLE
76#endif 83#endif
77 84
78#ifdef RGBLIGHT_STATIC_PATTERNS 85#ifdef RGBLIGHT_STATIC_PATTERNS
@@ -89,7 +96,8 @@
89 || defined(RGBLIGHT_EFFECT_KNIGHT) \ 96 || defined(RGBLIGHT_EFFECT_KNIGHT) \
90 || defined(RGBLIGHT_EFFECT_CHRISTMAS) \ 97 || defined(RGBLIGHT_EFFECT_CHRISTMAS) \
91 || defined(RGBLIGHT_EFFECT_RGB_TEST) \ 98 || defined(RGBLIGHT_EFFECT_RGB_TEST) \
92 || defined(RGBLIGHT_EFFECT_ALTERNATING) 99 || defined(RGBLIGHT_EFFECT_ALTERNATING) \
100 || defined(RGBLIGHT_EFFECT_TWINKLE)
93# define RGBLIGHT_USE_TIMER 101# define RGBLIGHT_USE_TIMER
94#endif 102#endif
95 103
@@ -141,6 +149,14 @@ enum RGBLIGHT_EFFECT_MODE {
141# define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2 149# define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2
142# endif 150# endif
143 151
152# ifndef RGBLIGHT_EFFECT_TWINKLE_LIFE
153# define RGBLIGHT_EFFECT_TWINKLE_LIFE 75
154# endif
155
156# ifndef RGBLIGHT_EFFECT_TWINKLE_PROBABILITY
157# define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1 / 127
158# endif
159
144# ifndef RGBLIGHT_HUE_STEP 160# ifndef RGBLIGHT_HUE_STEP
145# define RGBLIGHT_HUE_STEP 8 161# define RGBLIGHT_HUE_STEP 8
146# endif 162# endif
@@ -180,7 +196,20 @@ typedef struct {
180# define RGBLIGHT_END_SEGMENT_INDEX (255) 196# define RGBLIGHT_END_SEGMENT_INDEX (255)
181# define RGBLIGHT_END_SEGMENTS \ 197# define RGBLIGHT_END_SEGMENTS \
182 { RGBLIGHT_END_SEGMENT_INDEX, 0, 0, 0 } 198 { RGBLIGHT_END_SEGMENT_INDEX, 0, 0, 0 }
183# define RGBLIGHT_MAX_LAYERS 8 199# ifndef RGBLIGHT_MAX_LAYERS
200# define RGBLIGHT_MAX_LAYERS 8
201# endif
202# if RGBLIGHT_MAX_LAYERS <= 0
203# error invalid RGBLIGHT_MAX_LAYERS value (must be >= 1)
204# elif RGBLIGHT_MAX_LAYERS <= 8
205typedef uint8_t rgblight_layer_mask_t;
206# elif RGBLIGHT_MAX_LAYERS <= 16
207typedef uint16_t rgblight_layer_mask_t;
208# elif RGBLIGHT_MAX_LAYERS <= 32
209typedef uint32_t rgblight_layer_mask_t;
210# else
211# error invalid RGBLIGHT_MAX_LAYERS value (must be <= 32)
212# endif
184# define RGBLIGHT_LAYER_SEGMENTS(...) \ 213# define RGBLIGHT_LAYER_SEGMENTS(...) \
185 { __VA_ARGS__, RGBLIGHT_END_SEGMENTS } 214 { __VA_ARGS__, RGBLIGHT_END_SEGMENTS }
186# define RGBLIGHT_LAYERS_LIST(...) \ 215# define RGBLIGHT_LAYERS_LIST(...) \
@@ -192,6 +221,12 @@ bool rgblight_get_layer_state(uint8_t layer);
192 221
193// Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers 222// Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers
194extern const rgblight_segment_t *const *rgblight_layers; 223extern const rgblight_segment_t *const *rgblight_layers;
224
225# ifdef RGBLIGHT_LAYER_BLINK
226# define RGBLIGHT_USE_TIMER
227void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms);
228# endif
229
195# endif 230# endif
196 231
197extern LED_TYPE led[RGBLED_NUM]; 232extern LED_TYPE led[RGBLED_NUM];
@@ -202,6 +237,7 @@ extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
202extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM; 237extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM;
203extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM; 238extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM;
204extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM; 239extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM;
240extern const uint8_t RGBLED_TWINKLE_INTERVALS[3] PROGMEM;
205extern bool is_rgblight_initialized; 241extern bool is_rgblight_initialized;
206 242
207// Should stay in sycn with rgb matrix config as we reuse eeprom storage for both (for now) 243// Should stay in sycn with rgb matrix config as we reuse eeprom storage for both (for now)
@@ -224,7 +260,7 @@ typedef struct _rgblight_status_t {
224 uint8_t change_flags; 260 uint8_t change_flags;
225# endif 261# endif
226# ifdef RGBLIGHT_LAYERS 262# ifdef RGBLIGHT_LAYERS
227 uint8_t enabled_layer_mask; 263 rgblight_layer_mask_t enabled_layer_mask;
228# endif 264# endif
229} rgblight_status_t; 265} rgblight_status_t;
230 266
@@ -314,6 +350,8 @@ uint8_t rgblight_get_mode(void);
314uint8_t rgblight_get_hue(void); 350uint8_t rgblight_get_hue(void);
315uint8_t rgblight_get_sat(void); 351uint8_t rgblight_get_sat(void);
316uint8_t rgblight_get_val(void); 352uint8_t rgblight_get_val(void);
353bool rgblight_is_enabled(void);
354HSV rgblight_get_hsv(void);
317 355
318/* === qmk_firmware (core)internal Functions === */ 356/* === qmk_firmware (core)internal Functions === */
319void rgblight_init(void); 357void rgblight_init(void);
@@ -392,6 +430,7 @@ void rgblight_effect_knight(animation_status_t *anim);
392void rgblight_effect_christmas(animation_status_t *anim); 430void rgblight_effect_christmas(animation_status_t *anim);
393void rgblight_effect_rgbtest(animation_status_t *anim); 431void rgblight_effect_rgbtest(animation_status_t *anim);
394void rgblight_effect_alternating(animation_status_t *anim); 432void rgblight_effect_alternating(animation_status_t *anim);
433void rgblight_effect_twinkle(animation_status_t *anim);
395 434
396# endif 435# endif
397 436
diff --git a/quantum/rgblight_modes.h b/quantum/rgblight_modes.h
index 40c9ce498..7abdb87bc 100644
--- a/quantum/rgblight_modes.h
+++ b/quantum/rgblight_modes.h
@@ -53,6 +53,14 @@ _RGBM_SINGLE_DYNAMIC(RGB_TEST)
53# ifdef RGBLIGHT_EFFECT_ALTERNATING 53# ifdef RGBLIGHT_EFFECT_ALTERNATING
54_RGBM_SINGLE_DYNAMIC(ALTERNATING) 54_RGBM_SINGLE_DYNAMIC(ALTERNATING)
55# endif 55# endif
56# ifdef RGBLIGHT_EFFECT_TWINKLE
57_RGBM_MULTI_DYNAMIC(TWINKLE)
58_RGBM_TMP_DYNAMIC(twinkle_38, TWINKLE)
59_RGBM_TMP_DYNAMIC(twinkle_39, TWINKLE)
60_RGBM_TMP_DYNAMIC(twinkle_40, TWINKLE)
61_RGBM_TMP_DYNAMIC(twinkle_41, TWINKLE)
62_RGBM_TMP_DYNAMIC(TWINKLE_end, TWINKLE)
63# endif
56//// Add a new mode here. 64//// Add a new mode here.
57// #ifdef RGBLIGHT_EFFECT_<name> 65// #ifdef RGBLIGHT_EFFECT_<name>
58// _RGBM_<SINGLE|MULTI>_<STATIC|DYNAMIC>( <name> ) 66// _RGBM_<SINGLE|MULTI>_<STATIC|DYNAMIC>( <name> )
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 95ee2433a..5bad9db08 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -61,17 +61,22 @@ static void init_pins(void) {
61} 61}
62 62
63static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 63static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
64 matrix_row_t last_row_value = current_matrix[current_row]; 64 // Start with a clear matrix row
65 current_matrix[current_row] = 0; 65 matrix_row_t current_row_value = 0;
66 66
67 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 67 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
68 pin_t pin = direct_pins[current_row][col_index]; 68 pin_t pin = direct_pins[current_row][col_index];
69 if (pin != NO_PIN) { 69 if (pin != NO_PIN) {
70 current_matrix[current_row] |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index); 70 current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
71 } 71 }
72 } 72 }
73 73
74 return (last_row_value != current_matrix[current_row]); 74 // If the row has changed, store the row and return the changed flag.
75 if (current_matrix[current_row] != current_row_value) {
76 current_matrix[current_row] = current_row_value;
77 return true;
78 }
79 return false;
75} 80}
76 81
77#elif defined(DIODE_DIRECTION) 82#elif defined(DIODE_DIRECTION)
@@ -98,11 +103,8 @@ static void init_pins(void) {
98} 103}
99 104
100static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { 105static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
101 // Store last value of row prior to reading 106 // Start with a clear matrix row
102 matrix_row_t last_row_value = current_matrix[current_row]; 107 matrix_row_t current_row_value = 0;
103
104 // Clear data in matrix row
105 current_matrix[current_row] = 0;
106 108
107 // Select row and wait for row selecton to stabilize 109 // Select row and wait for row selecton to stabilize
108 select_row(current_row); 110 select_row(current_row);
@@ -114,13 +116,18 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
114 uint8_t pin_state = readPin(col_pins[col_index]); 116 uint8_t pin_state = readPin(col_pins[col_index]);
115 117
116 // Populate the matrix row with the state of the col pin 118 // Populate the matrix row with the state of the col pin
117 current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); 119 current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
118 } 120 }
119 121
120 // Unselect row 122 // Unselect row
121 unselect_row(current_row); 123 unselect_row(current_row);
122 124
123 return (last_row_value != current_matrix[current_row]); 125 // If the row has changed, store the row and return the changed flag.
126 if (current_matrix[current_row] != current_row_value) {
127 current_matrix[current_row] = current_row_value;
128 return true;
129 }
130 return false;
124} 131}
125 132
126# elif (DIODE_DIRECTION == ROW2COL) 133# elif (DIODE_DIRECTION == ROW2COL)
@@ -155,20 +162,22 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
155 // For each row... 162 // For each row...
156 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { 163 for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
157 // Store last value of row prior to reading 164 // Store last value of row prior to reading
158 matrix_row_t last_row_value = current_matrix[row_index]; 165 matrix_row_t last_row_value = current_matrix[row_index];
166 matrix_row_t current_row_value = last_row_value;
159 167
160 // Check row pin state 168 // Check row pin state
161 if (readPin(row_pins[row_index]) == 0) { 169 if (readPin(row_pins[row_index]) == 0) {
162 // Pin LO, set col bit 170 // Pin LO, set col bit
163 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); 171 current_row_value |= (MATRIX_ROW_SHIFTER << current_col);
164 } else { 172 } else {
165 // Pin HI, clear col bit 173 // Pin HI, clear col bit
166 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); 174 current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col);
167 } 175 }
168 176
169 // Determine if the matrix changed state 177 // Determine if the matrix changed state
170 if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) { 178 if ((last_row_value != current_row_value)) {
171 matrix_changed = true; 179 matrix_changed |= true;
180 current_matrix[row_index] = current_row_value;
172 } 181 }
173 } 182 }
174 183
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index fb6a3b85a..dfd06f5f9 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -6,6 +6,14 @@
6#include "transport.h" 6#include "transport.h"
7#include "quantum.h" 7#include "quantum.h"
8 8
9#ifdef PROTOCOL_LUFA
10# include <LUFA/Drivers/USB/USB.h>
11#endif
12
13#ifdef PROTOCOL_VUSB
14# include "usbdrv.h"
15#endif
16
9#ifdef EE_HANDS 17#ifdef EE_HANDS
10# include "eeconfig.h" 18# include "eeconfig.h"
11#endif 19#endif
@@ -22,30 +30,54 @@
22# define SPLIT_USB_TIMEOUT_POLL 10 30# define SPLIT_USB_TIMEOUT_POLL 10
23#endif 31#endif
24 32
33#ifdef PROTOCOL_CHIBIOS
34# define SPLIT_USB_DETECT // Force this on for now
35#endif
36
25volatile bool isLeftHand = true; 37volatile bool isLeftHand = true;
26 38
27bool waitForUsb(void) { 39#if defined(SPLIT_USB_DETECT)
40# if defined(PROTOCOL_LUFA)
41static inline bool usbHasActiveConnection(void) { return USB_Device_IsAddressSet(); }
42static inline void usbDisable(void) { USB_Disable(); }
43# elif defined(PROTOCOL_CHIBIOS)
44static inline bool usbHasActiveConnection(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; }
45static inline void usbDisable(void) { usbStop(&USBD1); }
46# elif defined(PROTOCOL_VUSB)
47static inline bool usbHasActiveConnection(void) {
48 usbPoll();
49 return usbConfiguration;
50}
51static inline void usbDisable(void) { usbDeviceDisconnect(); }
52# else
53static inline bool usbHasActiveConnection(void) { return true; }
54static inline void usbDisable(void) {}
55# endif
56
57bool usbIsActive(void) {
28 for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) { 58 for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
29 // This will return true if a USB connection has been established 59 // This will return true if a USB connection has been established
30#if defined(__AVR__) 60 if (usbHasActiveConnection()) {
31 if (UDADDR & _BV(ADDEN)) {
32#else
33 if (usbGetDriverStateI(&USBD1) == USB_ACTIVE) {
34#endif
35 return true; 61 return true;
36 } 62 }
37 wait_ms(SPLIT_USB_TIMEOUT_POLL); 63 wait_ms(SPLIT_USB_TIMEOUT_POLL);
38 } 64 }
39 65
40 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow 66 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
41#if defined(__AVR__) 67 usbDisable();
42 (USBCON &= ~(_BV(USBE) | _BV(OTGPADE)));
43#else
44 usbStop(&USBD1);
45#endif
46 68
47 return false; 69 return false;
48} 70}
71#elif defined(PROTOCOL_LUFA)
72static inline bool usbIsActive(void) {
73 USB_OTGPAD_On(); // enables VBUS pad
74 wait_us(5);
75
76 return USB_VBUS_GetStatus(); // checks state of VBUS
77}
78#else
79static inline bool usbIsActive(void) { return true; }
80#endif
49 81
50__attribute__((weak)) bool is_keyboard_left(void) { 82__attribute__((weak)) bool is_keyboard_left(void) {
51#if defined(SPLIT_HAND_PIN) 83#if defined(SPLIT_HAND_PIN)
@@ -66,16 +98,7 @@ __attribute__((weak)) bool is_keyboard_master(void) {
66 98
67 // only check once, as this is called often 99 // only check once, as this is called often
68 if (usbstate == UNKNOWN) { 100 if (usbstate == UNKNOWN) {
69#if defined(SPLIT_USB_DETECT) || defined(PROTOCOL_CHIBIOS) 101 usbstate = usbIsActive() ? MASTER : SLAVE;
70 usbstate = waitForUsb() ? MASTER : SLAVE;
71#elif defined(__AVR__)
72 USBCON |= (1 << OTGPADE); // enables VBUS pad
73 wait_us(5);
74
75 usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS
76#else
77 usbstate = MASTER;
78#endif
79 } 102 }
80 103
81 return (usbstate == MASTER); 104 return (usbstate == MASTER);
diff --git a/quantum/stm32/halconf.h b/quantum/stm32/halconf.h
index 533803a25..b6c7b392c 100644
--- a/quantum/stm32/halconf.h
+++ b/quantum/stm32/halconf.h
@@ -203,7 +203,7 @@
203 * @note Disabling this option saves both code and data space. 203 * @note Disabling this option saves both code and data space.
204 */ 204 */
205# if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__) 205# if !defined(PAL_USE_CALLBACKS) || defined(__DOXYGEN__)
206# define PAL_USE_CALLBACKS FALSE 206# define PAL_USE_CALLBACKS TRUE
207# endif 207# endif
208 208
209/** 209/**
@@ -211,7 +211,7 @@
211 * @note Disabling this option saves both code and data space. 211 * @note Disabling this option saves both code and data space.
212 */ 212 */
213# if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__) 213# if !defined(PAL_USE_WAIT) || defined(__DOXYGEN__)
214# define PAL_USE_WAIT FALSE 214# define PAL_USE_WAIT TRUE
215# endif 215# endif
216 216
217/*===========================================================================*/ 217/*===========================================================================*/
diff --git a/quantum/template/ps2avrgb/rules.mk b/quantum/template/ps2avrgb/rules.mk
index b9b81a675..9e18b3382 100644
--- a/quantum/template/ps2avrgb/rules.mk
+++ b/quantum/template/ps2avrgb/rules.mk
@@ -22,5 +22,3 @@ COMMAND_ENABLE = yes # Commands for debug and configuration
22BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality 22BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
23RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow 23RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
24WS2812_DRIVER = i2c 24WS2812_DRIVER = i2c
25
26OPT_DEFS = -DDEBUG_LEVEL=0