aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/backlight/backlight.c21
-rw-r--r--quantum/backlight/backlight.h23
-rw-r--r--quantum/backlight/backlight_arm.c29
-rw-r--r--quantum/backlight/backlight_avr.c35
-rw-r--r--quantum/backlight/backlight_soft.c37
-rw-r--r--quantum/color.c14
-rw-r--r--quantum/color.h4
-rw-r--r--quantum/dynamic_keymap.c55
-rw-r--r--quantum/encoder.c26
-rw-r--r--quantum/keymap_common.c14
-rw-r--r--quantum/matrix.c88
-rw-r--r--quantum/matrix_common.c107
-rw-r--r--quantum/mcu_selection.mk123
-rw-r--r--quantum/process_keycode/process_magic.c178
-rw-r--r--quantum/process_keycode/process_magic.h20
-rw-r--r--quantum/process_keycode/process_rgb.c141
-rw-r--r--quantum/process_keycode/process_rgb.h20
-rw-r--r--quantum/process_keycode/process_steno.c4
-rw-r--r--quantum/process_keycode/process_steno.h4
-rw-r--r--quantum/process_keycode/process_terminal.c2
-rw-r--r--quantum/quantum.c470
-rw-r--r--quantum/quantum.h65
-rw-r--r--quantum/quantum_keycodes.h35
-rw-r--r--quantum/rgb_matrix.c28
-rw-r--r--quantum/rgb_matrix.h40
-rw-r--r--quantum/rgb_matrix_animations/gradient_left_right_anim.h22
-rw-r--r--quantum/rgb_matrix_animations/rgb_matrix_effects.inc1
-rw-r--r--quantum/rgb_matrix_drivers.c2
-rw-r--r--quantum/rgblight.c9
-rw-r--r--quantum/send_string_keycodes.h575
-rw-r--r--quantum/split_common/matrix.c124
-rw-r--r--quantum/split_common/matrix.h3
-rw-r--r--quantum/split_common/post_config.h2
-rw-r--r--quantum/split_common/split_util.c6
-rw-r--r--quantum/split_common/transport.c2
-rw-r--r--quantum/stm32/proton_c.mk4
-rw-r--r--quantum/template/base/keymaps/default/keymap.c2
-rw-r--r--quantum/via.c400
-rw-r--r--quantum/via.h151
39 files changed, 1886 insertions, 1000 deletions
diff --git a/quantum/backlight/backlight.c b/quantum/backlight/backlight.c
index 708022f68..e57b31d10 100644
--- a/quantum/backlight/backlight.c
+++ b/quantum/backlight/backlight.c
@@ -21,6 +21,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21
22backlight_config_t backlight_config; 22backlight_config_t backlight_config;
23 23
24// TODO: migrate to backlight_config_t
25static uint8_t breathing_period = BREATHING_PERIOD;
26
24/** \brief Backlight initialization 27/** \brief Backlight initialization
25 * 28 *
26 * FIXME: needs doc 29 * FIXME: needs doc
@@ -191,3 +194,21 @@ void backlight_disable_breathing(void) {
191 */ 194 */
192bool is_backlight_breathing(void) { return backlight_config.breathing; } 195bool is_backlight_breathing(void) { return backlight_config.breathing; }
193#endif 196#endif
197
198// following are marked as weak purely for backwards compatibility
199__attribute__((weak)) void breathing_period_set(uint8_t value) { breathing_period = value ? value : 1; }
200
201__attribute__((weak)) uint8_t get_breathing_period(void) { return breathing_period; }
202
203__attribute__((weak)) void breathing_period_default(void) { breathing_period_set(BREATHING_PERIOD); }
204
205__attribute__((weak)) void breathing_period_inc(void) { breathing_period_set(breathing_period + 1); }
206
207__attribute__((weak)) void breathing_period_dec(void) { breathing_period_set(breathing_period - 1); }
208
209// defaults for backlight api
210__attribute__((weak)) void backlight_init_ports(void) {}
211
212__attribute__((weak)) void backlight_set(uint8_t level) {}
213
214__attribute__((weak)) void backlight_task(void) {}
diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h
index 1e581055d..9f0a5e81d 100644
--- a/quantum/backlight/backlight.h
+++ b/quantum/backlight/backlight.h
@@ -41,22 +41,39 @@ typedef union {
41} backlight_config_t; 41} backlight_config_t;
42 42
43void backlight_init(void); 43void backlight_init(void);
44void backlight_increase(void);
45void backlight_decrease(void);
46void backlight_toggle(void); 44void backlight_toggle(void);
47void backlight_enable(void); 45void backlight_enable(void);
48void backlight_disable(void); 46void backlight_disable(void);
49bool is_backlight_enabled(void); 47bool is_backlight_enabled(void);
50void backlight_step(void); 48void backlight_step(void);
51void backlight_set(uint8_t level); 49void backlight_increase(void);
50void backlight_decrease(void);
52void backlight_level(uint8_t level); 51void backlight_level(uint8_t level);
53uint8_t get_backlight_level(void); 52uint8_t get_backlight_level(void);
54 53
54// implementation specific
55void backlight_init_ports(void);
56void backlight_set(uint8_t level);
57void backlight_task(void);
58
55#ifdef BACKLIGHT_BREATHING 59#ifdef BACKLIGHT_BREATHING
60
56void backlight_toggle_breathing(void); 61void backlight_toggle_breathing(void);
57void backlight_enable_breathing(void); 62void backlight_enable_breathing(void);
58void backlight_disable_breathing(void); 63void backlight_disable_breathing(void);
59bool is_backlight_breathing(void); 64bool is_backlight_breathing(void);
65
66void breathing_period_set(uint8_t value);
67uint8_t get_breathing_period(void);
68void breathing_period_default(void);
69void breathing_period_inc(void);
70void breathing_period_dec(void);
71
72// implementation specific
60void breathing_enable(void); 73void breathing_enable(void);
61void breathing_disable(void); 74void breathing_disable(void);
75void breathing_toggle(void);
76bool is_breathing(void);
77void breathing_pulse(void);
78void breathing_task(void);
62#endif 79#endif
diff --git a/quantum/backlight/backlight_arm.c b/quantum/backlight/backlight_arm.c
index 3f94ccef8..f7065906f 100644
--- a/quantum/backlight/backlight_arm.c
+++ b/quantum/backlight/backlight_arm.c
@@ -10,10 +10,6 @@
10# error "Backlight support for STMF072 is not available. Please disable." 10# error "Backlight support for STMF072 is not available. Please disable."
11# endif 11# endif
12 12
13# if defined(STM32F1XX) || defined(STM32F1xx)
14# define USE_GPIOV1
15# endif
16
17// GPIOV2 && GPIOV3 13// GPIOV2 && GPIOV3
18# ifndef BACKLIGHT_PAL_MODE 14# ifndef BACKLIGHT_PAL_MODE
19# define BACKLIGHT_PAL_MODE 2 15# define BACKLIGHT_PAL_MODE 2
@@ -110,7 +106,6 @@ void backlight_task(void) {}
110# define BREATHING_HALT_ON 2 106# define BREATHING_HALT_ON 2
111# define BREATHING_STEPS 128 107# define BREATHING_STEPS 128
112 108
113static uint8_t breathing_period = BREATHING_PERIOD;
114static uint8_t breathing_halt = BREATHING_NO_HALT; 109static uint8_t breathing_halt = BREATHING_NO_HALT;
115static uint16_t breathing_counter = 0; 110static uint16_t breathing_counter = 0;
116 111
@@ -118,7 +113,7 @@ bool is_breathing(void) { return BACKLIGHT_PWM_DRIVER.config == &pwmCFG_breathin
118 113
119static inline void breathing_min(void) { breathing_counter = 0; } 114static inline void breathing_min(void) { breathing_counter = 0; }
120 115
121static inline void breathing_max(void) { breathing_counter = breathing_period * 256 / 2; } 116static inline void breathing_max(void) { breathing_counter = get_breathing_period() * 256 / 2; }
122 117
123void breathing_interrupt_enable(void) { 118void breathing_interrupt_enable(void) {
124 pwmStop(&BACKLIGHT_PWM_DRIVER); 119 pwmStop(&BACKLIGHT_PWM_DRIVER);
@@ -170,17 +165,6 @@ void breathing_toggle(void) {
170 breathing_enable(); 165 breathing_enable();
171} 166}
172 167
173void breathing_period_set(uint8_t value) {
174 if (!value) value = 1;
175 breathing_period = value;
176}
177
178void breathing_period_default(void) { breathing_period_set(BREATHING_PERIOD); }
179
180void breathing_period_inc(void) { breathing_period_set(breathing_period + 1); }
181
182void breathing_period_dec(void) { breathing_period_set(breathing_period - 1); }
183
184/* To generate breathing curve in python: 168/* To generate breathing curve in python:
185 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] 169 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
186 */ 170 */
@@ -191,7 +175,8 @@ static inline uint16_t scale_backlight(uint16_t v) { return v / BACKLIGHT_LEVELS
191 175
192static void breathing_callback(PWMDriver *pwmp) { 176static void breathing_callback(PWMDriver *pwmp) {
193 (void)pwmp; 177 (void)pwmp;
194 uint16_t interval = (uint16_t)breathing_period * 256 / BREATHING_STEPS; 178 uint8_t breathing_period = get_breathing_period();
179 uint16_t interval = (uint16_t)breathing_period * 256 / BREATHING_STEPS;
195 // resetting after one period to prevent ugly reset at overflow. 180 // resetting after one period to prevent ugly reset at overflow.
196 breathing_counter = (breathing_counter + 1) % (breathing_period * 256); 181 breathing_counter = (breathing_counter + 1) % (breathing_period * 256);
197 uint8_t index = breathing_counter / interval % BREATHING_STEPS; 182 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
@@ -207,12 +192,4 @@ static void breathing_callback(PWMDriver *pwmp) {
207 chSysUnlockFromISR(); 192 chSysUnlockFromISR();
208} 193}
209 194
210#else
211
212__attribute__((weak)) void backlight_init_ports(void) {}
213
214__attribute__((weak)) void backlight_set(uint8_t level) {}
215
216__attribute__((weak)) void backlight_task(void) {}
217
218#endif 195#endif
diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c
index edda6ea0b..7cf1e0fb3 100644
--- a/quantum/backlight/backlight_avr.c
+++ b/quantum/backlight/backlight_avr.c
@@ -206,7 +206,7 @@ static const pin_t backlight_pin = BACKLIGHT_PIN;
206# endif 206# endif
207 207
208# ifdef NO_HARDWARE_PWM 208# ifdef NO_HARDWARE_PWM
209__attribute__((weak)) void backlight_init_ports(void) { 209void backlight_init_ports(void) {
210 // Setup backlight pin as output and output to on state. 210 // Setup backlight pin as output and output to on state.
211 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);) 211 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);)
212 212
@@ -217,8 +217,6 @@ __attribute__((weak)) void backlight_init_ports(void) {
217# endif 217# endif
218} 218}
219 219
220__attribute__((weak)) void backlight_set(uint8_t level) {}
221
222uint8_t backlight_tick = 0; 220uint8_t backlight_tick = 0;
223 221
224# ifndef BACKLIGHT_CUSTOM_DRIVER 222# ifndef BACKLIGHT_CUSTOM_DRIVER
@@ -303,7 +301,7 @@ static uint16_t cie_lightness(uint16_t v) {
303static inline void set_pwm(uint16_t val) { OCRxx = val; } 301static inline void set_pwm(uint16_t val) { OCRxx = val; }
304 302
305# ifndef BACKLIGHT_CUSTOM_DRIVER 303# ifndef BACKLIGHT_CUSTOM_DRIVER
306__attribute__((weak)) void backlight_set(uint8_t level) { 304void backlight_set(uint8_t level) {
307 if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS; 305 if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS;
308 306
309 if (level == 0) { 307 if (level == 0) {
@@ -342,7 +340,6 @@ void backlight_task(void) {}
342# define BREATHING_HALT_ON 2 340# define BREATHING_HALT_ON 2
343# define BREATHING_STEPS 128 341# define BREATHING_STEPS 128
344 342
345static uint8_t breathing_period = BREATHING_PERIOD;
346static uint8_t breathing_halt = BREATHING_NO_HALT; 343static uint8_t breathing_halt = BREATHING_NO_HALT;
347static uint16_t breathing_counter = 0; 344static uint16_t breathing_counter = 0;
348 345
@@ -377,9 +374,9 @@ bool is_breathing(void) { return !!(TIMSKx & _BV(TOIEx)); }
377 do { \ 374 do { \
378 breathing_counter = 0; \ 375 breathing_counter = 0; \
379 } while (0) 376 } while (0)
380# define breathing_max() \ 377# define breathing_max() \
381 do { \ 378 do { \
382 breathing_counter = breathing_period * 244 / 2; \ 379 breathing_counter = get_breathing_period() * 244 / 2; \
383 } while (0) 380 } while (0)
384 381
385void breathing_enable(void) { 382void breathing_enable(void) {
@@ -417,17 +414,6 @@ void breathing_toggle(void) {
417 breathing_enable(); 414 breathing_enable();
418} 415}
419 416
420void breathing_period_set(uint8_t value) {
421 if (!value) value = 1;
422 breathing_period = value;
423}
424
425void breathing_period_default(void) { breathing_period_set(BREATHING_PERIOD); }
426
427void breathing_period_inc(void) { breathing_period_set(breathing_period + 1); }
428
429void breathing_period_dec(void) { breathing_period_set(breathing_period - 1); }
430
431/* To generate breathing curve in python: 417/* To generate breathing curve in python:
432 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] 418 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
433 */ 419 */
@@ -445,6 +431,7 @@ void breathing_task(void)
445ISR(TIMERx_OVF_vect) 431ISR(TIMERx_OVF_vect)
446# endif 432# endif
447{ 433{
434 uint8_t breathing_period = get_breathing_period();
448 uint16_t interval = (uint16_t)breathing_period * 244 / BREATHING_STEPS; 435 uint16_t interval = (uint16_t)breathing_period * 244 / BREATHING_STEPS;
449 // resetting after one period to prevent ugly reset at overflow. 436 // resetting after one period to prevent ugly reset at overflow.
450 breathing_counter = (breathing_counter + 1) % (breathing_period * 244); 437 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
@@ -459,7 +446,7 @@ ISR(TIMERx_OVF_vect)
459 446
460# endif // BACKLIGHT_BREATHING 447# endif // BACKLIGHT_BREATHING
461 448
462__attribute__((weak)) void backlight_init_ports(void) { 449void backlight_init_ports(void) {
463 // Setup backlight pin as output and output to on state. 450 // Setup backlight pin as output and output to on state.
464 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);) 451 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);)
465 452
@@ -500,10 +487,4 @@ __attribute__((weak)) void backlight_init_ports(void) {
500 487
501# endif // hardware backlight 488# endif // hardware backlight
502 489
503#else // no backlight 490#endif // backlight
504
505__attribute__((weak)) void backlight_init_ports(void) {}
506
507__attribute__((weak)) void backlight_set(uint8_t level) {}
508
509#endif // backlight \ No newline at end of file
diff --git a/quantum/backlight/backlight_soft.c b/quantum/backlight/backlight_soft.c
index a6aba7782..096b41d91 100644
--- a/quantum/backlight/backlight_soft.c
+++ b/quantum/backlight/backlight_soft.c
@@ -10,7 +10,7 @@
10#endif 10#endif
11 11
12#ifndef BACKLIGHT_ON_STATE 12#ifndef BACKLIGHT_ON_STATE
13# define BACKLIGHT_ON_STATE 0 13# define BACKLIGHT_ON_STATE 1
14#endif 14#endif
15 15
16#ifdef BACKLIGHT_PINS 16#ifdef BACKLIGHT_PINS
@@ -20,6 +20,7 @@
20 { BACKLIGHT_PIN } 20 { BACKLIGHT_PIN }
21#endif 21#endif
22 22
23static uint16_t s_duty_pattern = 0;
23static const pin_t backlight_pins[] = BACKLIGHT_PIN_INIT; 24static const pin_t backlight_pins[] = BACKLIGHT_PIN_INIT;
24#define BACKLIGHT_LED_COUNT (sizeof(backlight_pins) / sizeof(pin_t)) 25#define BACKLIGHT_LED_COUNT (sizeof(backlight_pins) / sizeof(pin_t))
25 26
@@ -46,14 +47,38 @@ void backlight_off(pin_t backlight_pin) {
46} 47}
47 48
48void backlight_init_ports(void) { 49void backlight_init_ports(void) {
49 // Setup backlight pin as output and output to on state. 50 // Setup backlight pin as output and output to off state.
50 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);) 51 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_off(backlight_pin);)
51} 52}
52 53
54// clang-format off
55
56/** \brief PWM duty patterns
57 *
58 * We scale the current backlight level to an index within this array. This allows
59 * backlight_task to focus on just switching LEDs on/off, and we can predict the duty pattern
60 */
61static uint16_t backlight_duty_table[] = {
62 0b0000000000000000,
63 0b1000000000000000,
64 0b1000000010000000,
65 0b1000001000010000,
66 0b1000100010001000,
67 0b1001001001001000,
68 0b1010101010101010,
69 0b1110111011101110,
70 0b1111111111111111,
71};
72#define backlight_duty_table_size (sizeof(backlight_duty_table) / sizeof(backlight_duty_table[0]))
73
74// clang-format on
75
76static uint8_t scale_backlight(uint8_t v) { return v * (backlight_duty_table_size - 1) / BACKLIGHT_LEVELS; }
77
53void backlight_task(void) { 78void backlight_task(void) {
54 static uint8_t backlight_tick = 0; 79 static uint8_t backlight_tick = 0;
55 80
56 if ((0xFFFF >> (get_backlight_level() * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { 81 if (s_duty_pattern & ((uint16_t)1 << backlight_tick)) {
57 FOR_EACH_LED(backlight_on(backlight_pin);) 82 FOR_EACH_LED(backlight_on(backlight_pin);)
58 } else { 83 } else {
59 FOR_EACH_LED(backlight_off(backlight_pin);) 84 FOR_EACH_LED(backlight_off(backlight_pin);)
@@ -61,6 +86,4 @@ void backlight_task(void) {
61 backlight_tick = (backlight_tick + 1) % 16; 86 backlight_tick = (backlight_tick + 1) % 16;
62} 87}
63 88
64void backlight_set(uint8_t level) { 89void backlight_set(uint8_t level) { s_duty_pattern = backlight_duty_table[scale_backlight(level)]; }
65 // noop as backlight_task uses get_backlight_level()
66}
diff --git a/quantum/color.c b/quantum/color.c
index 1f398e240..8bd52444f 100644
--- a/quantum/color.c
+++ b/quantum/color.c
@@ -85,3 +85,17 @@ RGB hsv_to_rgb(HSV hsv) {
85 85
86 return rgb; 86 return rgb;
87} 87}
88
89#ifdef RGBW
90#ifndef MIN
91# define MIN(a, b) ((a) < (b) ? (a) : (b))
92#endif
93void convert_rgb_to_rgbw(LED_TYPE *led) {
94 // Determine lowest value in all three colors, put that into
95 // the white channel and then shift all colors by that amount
96 led->w = MIN(led->r, MIN(led->g, led->b));
97 led->r -= led->w;
98 led->g -= led->w;
99 led->b -= led->w;
100}
101#endif
diff --git a/quantum/color.h b/quantum/color.h
index 678164662..58d4f0407 100644
--- a/quantum/color.h
+++ b/quantum/color.h
@@ -64,5 +64,7 @@ typedef struct PACKED {
64#endif 64#endif
65 65
66RGB hsv_to_rgb(HSV hsv); 66RGB hsv_to_rgb(HSV hsv);
67 67#ifdef RGBW
68void convert_rgb_to_rgbw(LED_TYPE *led);
69#endif
68#endif // COLOR_H 70#endif // COLOR_H
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index ca056f630..11d28592d 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -20,28 +20,37 @@
20#include "progmem.h" // to read default from flash 20#include "progmem.h" // to read default from flash
21#include "quantum.h" // for send_string() 21#include "quantum.h" // for send_string()
22#include "dynamic_keymap.h" 22#include "dynamic_keymap.h"
23 23#include "via.h" // for default VIA_EEPROM_ADDR_END
24#ifdef DYNAMIC_KEYMAP_ENABLE 24
25 25#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
26# ifndef DYNAMIC_KEYMAP_EEPROM_ADDR 26# define DYNAMIC_KEYMAP_LAYER_COUNT 4
27# error DYNAMIC_KEYMAP_EEPROM_ADDR not defined 27#endif
28# endif 28
29 29#ifndef DYNAMIC_KEYMAP_MACRO_COUNT
30# ifndef DYNAMIC_KEYMAP_LAYER_COUNT 30# define DYNAMIC_KEYMAP_MACRO_COUNT 16
31# error DYNAMIC_KEYMAP_LAYER_COUNT not defined 31#endif
32# endif 32
33 33// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
34# ifndef DYNAMIC_KEYMAP_MACRO_COUNT 34// default it start after VIA_EEPROM_CUSTOM_ADDR+VIA_EEPROM_CUSTOM_SIZE
35# error DYNAMIC_KEYMAP_MACRO_COUNT not defined 35#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
36# endif 36# ifdef VIA_EEPROM_CUSTOM_CONFIG_ADDR
37 37# define DYNAMIC_KEYMAP_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR+VIA_EEPROM_CUSTOM_CONFIG_SIZE)
38# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 38# else
39# error DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR not defined 39# error DYNAMIC_KEYMAP_EEPROM_ADDR not defined
40# endif 40# endif
41 41#endif
42# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 42
43# error DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE not defined 43// Dynamic macro starts after dynamic keymaps
44# endif 44#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
45# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR+(DYNAMIC_KEYMAP_LAYER_COUNT*MATRIX_ROWS*MATRIX_COLS*2))
46#endif
47
48// Dynamic macro uses up all remaining memory
49// Assumes 1K EEPROM on ATMega32U4
50// Override for anything different
51#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE
52# define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (1024-DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR)
53#endif
45 54
46uint8_t dynamic_keymap_get_layer_count(void) { return DYNAMIC_KEYMAP_LAYER_COUNT; } 55uint8_t dynamic_keymap_get_layer_count(void) { return DYNAMIC_KEYMAP_LAYER_COUNT; }
47 56
@@ -208,5 +217,3 @@ void dynamic_keymap_macro_send(uint8_t id) {
208 send_string(data); 217 send_string(data);
209 } 218 }
210} 219}
211
212#endif // DYNAMIC_KEYMAP_ENABLE
diff --git a/quantum/encoder.c b/quantum/encoder.c
index 4aeb3d0cd..c41b89f49 100644
--- a/quantum/encoder.c
+++ b/quantum/encoder.c
@@ -37,8 +37,8 @@ static pin_t encoders_pad_b[] = ENCODERS_PAD_B;
37 37
38static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; 38static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
39 39
40static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; 40static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0};
41static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0}; 41static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0};
42 42
43#ifdef SPLIT_KEYBOARD 43#ifdef SPLIT_KEYBOARD
44// right half encoders come over as second set of encoders 44// right half encoders come over as second set of encoders
@@ -79,27 +79,27 @@ void encoder_init(void) {
79} 79}
80 80
81static void encoder_update(int8_t index, uint8_t state) { 81static void encoder_update(int8_t index, uint8_t state) {
82 encoder_pulses[index] += encoder_LUT[state & 0xF]; 82 uint8_t i = index;
83 if (encoder_pulses[index] >= ENCODER_RESOLUTION) { 83#ifdef SPLIT_KEYBOARD
84 index += thisHand;
85#endif
86 encoder_pulses[i] += encoder_LUT[state & 0xF];
87 if (encoder_pulses[i] >= ENCODER_RESOLUTION) {
84 encoder_value[index]++; 88 encoder_value[index]++;
85 encoder_update_kb(index, true); 89 encoder_update_kb(index, true);
86 } 90 }
87 if (encoder_pulses[index] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise 91 if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
88 encoder_value[index]--; 92 encoder_value[index]--;
89 encoder_update_kb(index, false); 93 encoder_update_kb(index, false);
90 } 94 }
91 encoder_pulses[index] %= ENCODER_RESOLUTION; 95 encoder_pulses[i] %= ENCODER_RESOLUTION;
92} 96}
93 97
94void encoder_read(void) { 98void encoder_read(void) {
95 for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { 99 for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
96 encoder_state[i] <<= 2; 100 encoder_state[i] <<= 2;
97 encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); 101 encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1);
98#if SPLIT_KEYBOARD
99 encoder_update(i + thisHand, encoder_state[i]);
100#else
101 encoder_update(i, encoder_state[i]); 102 encoder_update(i, encoder_state[i]);
102#endif
103 } 103 }
104} 104}
105 105
@@ -107,9 +107,9 @@ void encoder_read(void) {
107void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } 107void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); }
108 108
109void encoder_update_raw(uint8_t* slave_state) { 109void encoder_update_raw(uint8_t* slave_state) {
110 for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { 110 for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {
111 uint8_t index = i + thatHand; 111 uint8_t index = i + thatHand;
112 int8_t delta = slave_state[i] - encoder_value[index]; 112 int8_t delta = slave_state[i] - encoder_value[index];
113 while (delta > 0) { 113 while (delta > 0) {
114 delta--; 114 delta--;
115 encoder_value[index]++; 115 encoder_value[index]++;
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 4fa45ac37..c82c44639 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -48,13 +48,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) {
48 // keycode remapping 48 // keycode remapping
49 keycode = keycode_config(keycode); 49 keycode = keycode_config(keycode);
50 50
51 action_t action; 51 action_t action = {};
52 uint8_t action_layer, when, mod; 52 uint8_t action_layer, when, mod;
53 53
54 switch (keycode) { 54 switch (keycode) {
55 case KC_FN0 ... KC_FN31:
56 action.code = keymap_function_id_to_action(FN_INDEX(keycode));
57 break;
58 case KC_A ... KC_EXSEL: 55 case KC_A ... KC_EXSEL:
59 case KC_LCTRL ... KC_RGUI: 56 case KC_LCTRL ... KC_RGUI:
60 action.code = ACTION_KEY(keycode); 57 action.code = ACTION_KEY(keycode);
@@ -65,9 +62,11 @@ action_t action_for_key(uint8_t layer, keypos_t key) {
65 case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN: 62 case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN:
66 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); 63 action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
67 break; 64 break;
65#ifdef MOUSEKEY_ENABLE
68 case KC_MS_UP ... KC_MS_ACCEL2: 66 case KC_MS_UP ... KC_MS_ACCEL2:
69 action.code = ACTION_MOUSEKEY(keycode); 67 action.code = ACTION_MOUSEKEY(keycode);
70 break; 68 break;
69#endif
71 case KC_TRNS: 70 case KC_TRNS:
72 action.code = ACTION_TRANSPARENT; 71 action.code = ACTION_TRANSPARENT;
73 break; 72 break;
@@ -76,17 +75,24 @@ action_t action_for_key(uint8_t layer, keypos_t key) {
76 // Split it up 75 // Split it up
77 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key 76 action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF); // adds modifier to key
78 break; 77 break;
78#ifndef NO_ACTION_FUNCTION
79 case KC_FN0 ... KC_FN31:
80 action.code = keymap_function_id_to_action(FN_INDEX(keycode));
81 break;
79 case QK_FUNCTION ... QK_FUNCTION_MAX:; 82 case QK_FUNCTION ... QK_FUNCTION_MAX:;
80 // Is a shortcut for function action_layer, pull last 12bits 83 // Is a shortcut for function action_layer, pull last 12bits
81 // This means we have 4,096 FN macros at our disposal 84 // This means we have 4,096 FN macros at our disposal
82 action.code = keymap_function_id_to_action((int)keycode & 0xFFF); 85 action.code = keymap_function_id_to_action((int)keycode & 0xFFF);
83 break; 86 break;
87#endif
88#ifndef NO_ACTION_MACRO
84 case QK_MACRO ... QK_MACRO_MAX: 89 case QK_MACRO ... QK_MACRO_MAX:
85 if (keycode & 0x800) // tap macros have upper bit set 90 if (keycode & 0x800) // tap macros have upper bit set
86 action.code = ACTION_MACRO_TAP(keycode & 0xFF); 91 action.code = ACTION_MACRO_TAP(keycode & 0xFF);
87 else 92 else
88 action.code = ACTION_MACRO(keycode & 0xFF); 93 action.code = ACTION_MACRO(keycode & 0xFF);
89 break; 94 break;
95#endif
90 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: 96 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
91 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); 97 action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF);
92 break; 98 break;
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 907492a0f..1675f2477 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -17,34 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
17#include <stdint.h> 17#include <stdint.h>
18#include <stdbool.h> 18#include <stdbool.h>
19#include "wait.h" 19#include "wait.h"
20#include "print.h"
21#include "debug.h"
22#include "util.h" 20#include "util.h"
23#include "matrix.h" 21#include "matrix.h"
24#include "debounce.h" 22#include "debounce.h"
25#include "quantum.h" 23#include "quantum.h"
26 24
27#if (MATRIX_COLS <= 8)
28# define print_matrix_header() print("\nr/c 01234567\n")
29# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
30# define matrix_bitpop(i) bitpop(matrix[i])
31# define ROW_SHIFTER ((uint8_t)1)
32#elif (MATRIX_COLS <= 16)
33# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
34# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
35# define matrix_bitpop(i) bitpop16(matrix[i])
36# define ROW_SHIFTER ((uint16_t)1)
37#elif (MATRIX_COLS <= 32)
38# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
39# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
40# define matrix_bitpop(i) bitpop32(matrix[i])
41# define ROW_SHIFTER ((uint32_t)1)
42#endif
43
44#ifdef MATRIX_MASKED
45extern const matrix_row_t matrix_mask[];
46#endif
47
48#ifdef DIRECT_PINS 25#ifdef DIRECT_PINS
49static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; 26static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
50#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) 27#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
@@ -53,61 +30,10 @@ static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
53#endif 30#endif
54 31
55/* matrix state(1:on, 0:off) */ 32/* matrix state(1:on, 0:off) */
56static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values 33extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
57static matrix_row_t matrix[MATRIX_ROWS]; // debounced values 34extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
58
59__attribute__((weak)) void matrix_init_quantum(void) { matrix_init_kb(); }
60
61__attribute__((weak)) void matrix_scan_quantum(void) { matrix_scan_kb(); }
62
63__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
64 35
65__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } 36// matrix code
66
67__attribute__((weak)) void matrix_init_user(void) {}
68
69__attribute__((weak)) void matrix_scan_user(void) {}
70
71inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
72
73inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
74
75// Deprecated.
76bool matrix_is_modified(void) {
77 if (debounce_active()) return false;
78 return true;
79}
80
81inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
82
83inline matrix_row_t matrix_get_row(uint8_t row) {
84 // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
85 // switch blocker installed and the switch is always pressed.
86#ifdef MATRIX_MASKED
87 return matrix[row] & matrix_mask[row];
88#else
89 return matrix[row];
90#endif
91}
92
93void matrix_print(void) {
94 print_matrix_header();
95
96 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
97 phex(row);
98 print(": ");
99 print_matrix_row(row);
100 print("\n");
101 }
102}
103
104uint8_t matrix_key_count(void) {
105 uint8_t count = 0;
106 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
107 count += matrix_bitpop(i);
108 }
109 return count;
110}
111 37
112#ifdef DIRECT_PINS 38#ifdef DIRECT_PINS
113 39
@@ -129,7 +55,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
129 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 55 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
130 pin_t pin = direct_pins[current_row][col_index]; 56 pin_t pin = direct_pins[current_row][col_index];
131 if (pin != NO_PIN) { 57 if (pin != NO_PIN) {
132 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index); 58 current_matrix[current_row] |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
133 } 59 }
134 } 60 }
135 61
@@ -175,7 +101,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
175 uint8_t pin_state = readPin(col_pins[col_index]); 101 uint8_t pin_state = readPin(col_pins[col_index]);
176 102
177 // Populate the matrix row with the state of the col pin 103 // Populate the matrix row with the state of the col pin
178 current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); 104 current_matrix[current_row] |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index);
179 } 105 }
180 106
181 // Unselect row 107 // Unselect row
@@ -221,10 +147,10 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
221 // Check row pin state 147 // Check row pin state
222 if (readPin(row_pins[row_index]) == 0) { 148 if (readPin(row_pins[row_index]) == 0) {
223 // Pin LO, set col bit 149 // Pin LO, set col bit
224 current_matrix[row_index] |= (ROW_SHIFTER << current_col); 150 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
225 } else { 151 } else {
226 // Pin HI, clear col bit 152 // Pin HI, clear col bit
227 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); 153 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
228 } 154 }
229 155
230 // Determine if the matrix changed state 156 // Determine if the matrix changed state
diff --git a/quantum/matrix_common.c b/quantum/matrix_common.c
new file mode 100644
index 000000000..c326e59ca
--- /dev/null
+++ b/quantum/matrix_common.c
@@ -0,0 +1,107 @@
1#include "matrix.h"
2#include "debounce.h"
3#include "print.h"
4#include "debug.h"
5
6/* matrix state(1:on, 0:off) */
7matrix_row_t raw_matrix[MATRIX_ROWS];
8matrix_row_t matrix[MATRIX_ROWS];
9
10#ifdef MATRIX_MASKED
11extern const matrix_row_t matrix_mask[];
12#endif
13
14// user-defined overridable functions
15
16__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
17
18__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
19
20__attribute__((weak)) void matrix_init_user(void) {}
21
22__attribute__((weak)) void matrix_scan_user(void) {}
23
24// helper functions
25
26inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
27
28inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
29
30inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
31
32inline matrix_row_t matrix_get_row(uint8_t row) {
33 // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
34 // switch blocker installed and the switch is always pressed.
35#ifdef MATRIX_MASKED
36 return matrix[row] & matrix_mask[row];
37#else
38 return matrix[row];
39#endif
40}
41
42// Deprecated.
43bool matrix_is_modified(void) {
44 if (debounce_active()) return false;
45 return true;
46}
47
48#if (MATRIX_COLS <= 8)
49# define print_matrix_header() print("\nr/c 01234567\n")
50# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
51# define matrix_bitpop(row) bitpop(matrix_get_row(row))
52#elif (MATRIX_COLS <= 16)
53# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
54# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
55# define matrix_bitpop(row) bitpop16(matrix_get_row(row))
56#elif (MATRIX_COLS <= 32)
57# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
58# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
59# define matrix_bitpop(row) bitpop32(matrix_get_row(row))
60#endif
61
62void matrix_print(void) {
63 print_matrix_header();
64
65 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
66 phex(row);
67 print(": ");
68 print_matrix_row(row);
69 print("\n");
70 }
71}
72
73uint8_t matrix_key_count(void) {
74 uint8_t count = 0;
75 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
76 count += matrix_bitpop(i);
77 }
78 return count;
79}
80
81// CUSTOM MATRIX 'LITE'
82__attribute__((weak)) void matrix_init_custom(void) {}
83
84__attribute__((weak)) bool matrix_scan_custom(matrix_row_t current_matrix[]) { return true; }
85
86__attribute__((weak)) void matrix_init(void) {
87 matrix_init_custom();
88
89 // initialize matrix state: all keys off
90 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
91 raw_matrix[i] = 0;
92 matrix[i] = 0;
93 }
94
95 debounce_init(MATRIX_ROWS);
96
97 matrix_init_quantum();
98}
99
100__attribute__((weak)) uint8_t matrix_scan(void) {
101 bool changed = matrix_scan_custom(raw_matrix);
102
103 debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
104
105 matrix_scan_quantum();
106 return changed;
107}
diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk
index 6815a0d8a..bddafa6a4 100644
--- a/quantum/mcu_selection.mk
+++ b/quantum/mcu_selection.mk
@@ -1,9 +1,15 @@
1ifneq ($(findstring STM32F303, $(MCU)),) 1ifneq ($(findstring STM32F303, $(MCU)),)
2 # Cortex version
3 MCU = cortex-m4
4
5 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
6 ARMV = 7
7
2 ## chip/board settings 8 ## chip/board settings
3 # - the next two should match the directories in 9 # - the next two should match the directories in
4 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) 10 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
5 MCU_FAMILY ?= STM32 11 MCU_FAMILY = STM32
6 MCU_SERIES ?= STM32F3xx 12 MCU_SERIES = STM32F3xx
7 13
8 # Linker script to use 14 # Linker script to use
9 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ 15 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
@@ -18,22 +24,110 @@ ifneq ($(findstring STM32F303, $(MCU)),)
18 # <keyboard_dir>/boards/, or drivers/boards/ 24 # <keyboard_dir>/boards/, or drivers/boards/
19 BOARD ?= GENERIC_STM32_F303XC 25 BOARD ?= GENERIC_STM32_F303XC
20 26
27 USE_FPU ?= yes
28
29 # Options to pass to dfu-util when flashing
30 DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
31 DFU_SUFFIX_ARGS ?= -v 0483 -p df11
32endif
33
34ifneq ($(findstring STM32F072, $(MCU)),)
21 # Cortex version 35 # Cortex version
22 MCU = cortex-m4 36 MCU = cortex-m0
23 37
24 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 38 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
25 ARMV ?= 7 39 ARMV = 6
26 40
27 USE_FPU = yes 41 ## chip/board settings
42 # - the next two should match the directories in
43 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
44 MCU_FAMILY = STM32
45 MCU_SERIES = STM32F0xx
28 46
29 # Vector table for application 47 # Linker script to use
30 # 0x00000000-0x00001000 area is occupied by bootloader.*/ 48 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
31 # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB 49 # or <keyboard_dir>/ld/
32 # OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000 50 MCU_LDSCRIPT ?= STM32F072xB
51
52 # Startup code to use
53 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
54 MCU_STARTUP ?= stm32f0xx
55
56 # Board: it should exist either in <chibios>/os/hal/boards/,
57 # <keyboard_dir>/boards/, or drivers/boards/
58 BOARD ?= ST_STM32F072B_DISCOVERY
59
60 USE_FPU ?= no
33 61
34 # Options to pass to dfu-util when flashing 62 # Options to pass to dfu-util when flashing
35 DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave 63 DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
36 DFU_SUFFIX_ARGS = -p DF11 -v 0483 64 DFU_SUFFIX_ARGS ?= -v 0483 -p df11
65endif
66
67ifneq ($(findstring STM32F042, $(MCU)),)
68 # Cortex version
69 MCU = cortex-m0
70
71 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
72 ARMV = 6
73
74 ## chip/board settings
75 # - the next two should match the directories in
76 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
77 MCU_FAMILY = STM32
78 MCU_SERIES = STM32F0xx
79
80 # Linker script to use
81 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
82 # or <keyboard_dir>/ld/
83 MCU_LDSCRIPT ?= STM32F042x6
84
85 # Startup code to use
86 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
87 MCU_STARTUP ?= stm32f0xx
88
89 # Board: it should exist either in <chibios>/os/hal/boards/,
90 # <keyboard_dir>/boards/, or drivers/boards/
91 BOARD ?= GENERIC_STM32_F042X6
92
93 USE_FPU ?= no
94
95 # Options to pass to dfu-util when flashing
96 DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
97 DFU_SUFFIX_ARGS ?= -v 0483 -p df11
98endif
99
100ifneq ($(findstring STM32F103, $(MCU)),)
101 # Cortex version
102 MCU = cortex-m3
103
104 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
105 ARMV = 7
106
107 ## chip/board settings
108 # - the next two should match the directories in
109 # <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
110 MCU_FAMILY = STM32
111 MCU_SERIES = STM32F1xx
112
113 # Linker script to use
114 # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
115 # or <keyboard_dir>/ld/
116 MCU_LDSCRIPT ?= STM32F103x8
117
118 # Startup code to use
119 # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
120 MCU_STARTUP ?= stm32f1xx
121
122 # Board: it should exist either in <chibios>/os/hal/boards/,
123 # <keyboard_dir>/boards/, or drivers/boards/
124 BOARD ?= GENERIC_STM32_F103
125
126 USE_FPU ?= no
127
128 # Options to pass to dfu-util when flashing
129 DFU_ARGS ?= -d 0483:df11 -a 0 -s 0x08000000:leave
130 DFU_SUFFIX_ARGS ?= -v 0483 -p df11
37endif 131endif
38 132
39ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb1286)) 133ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb1286))
@@ -75,6 +169,9 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a
75endif 169endif
76 170
77ifneq (,$(filter $(MCU),atmega32a)) 171ifneq (,$(filter $(MCU),atmega32a))
172 # MCU name for avrdude
173 AVRDUDE_MCU = m32
174
78 PROTOCOL = VUSB 175 PROTOCOL = VUSB
79 176
80 # Processor frequency. 177 # Processor frequency.
@@ -87,12 +184,12 @@ ifneq (,$(filter $(MCU),atmega32a))
87 # unsupported features for now 184 # unsupported features for now
88 NO_UART ?= yes 185 NO_UART ?= yes
89 NO_SUSPEND_POWER_DOWN ?= yes 186 NO_SUSPEND_POWER_DOWN ?= yes
90
91 # Programming options
92 PROGRAM_CMD ?= ./util/atmega32a_program.py $(TARGET).hex
93endif 187endif
94 188
95ifneq (,$(filter $(MCU),atmega328p)) 189ifneq (,$(filter $(MCU),atmega328p))
190 # MCU name for avrdude
191 AVRDUDE_MCU = m328p
192
96 PROTOCOL = VUSB 193 PROTOCOL = VUSB
97 194
98 # Processor frequency. 195 # Processor frequency.
diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c
new file mode 100644
index 000000000..44dd5f057
--- /dev/null
+++ b/quantum/process_keycode/process_magic.c
@@ -0,0 +1,178 @@
1/* Copyright 2019 Jack Humbert
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#include "process_magic.h"
17
18#ifdef AUDIO_ENABLE
19# ifndef AG_NORM_SONG
20# define AG_NORM_SONG SONG(AG_NORM_SOUND)
21# endif
22# ifndef AG_SWAP_SONG
23# define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
24# endif
25# ifndef CG_NORM_SONG
26# define CG_NORM_SONG SONG(AG_NORM_SOUND)
27# endif
28# ifndef CG_SWAP_SONG
29# define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
30# endif
31float ag_norm_song[][2] = AG_NORM_SONG;
32float ag_swap_song[][2] = AG_SWAP_SONG;
33float cg_norm_song[][2] = CG_NORM_SONG;
34float cg_swap_song[][2] = CG_SWAP_SONG;
35#endif
36
37/**
38 * MAGIC actions (BOOTMAGIC without the boot)
39 */
40bool process_magic(uint16_t keycode, keyrecord_t *record) {
41 // skip anything that isn't a keyup
42 if (record->event.pressed) {
43 switch (keycode) {
44 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI:
45 case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT:
46 /* keymap config */
47 keymap_config.raw = eeconfig_read_keymap();
48 switch (keycode) {
49 case MAGIC_SWAP_CONTROL_CAPSLOCK:
50 keymap_config.swap_control_capslock = true;
51 break;
52 case MAGIC_CAPSLOCK_TO_CONTROL:
53 keymap_config.capslock_to_control = true;
54 break;
55 case MAGIC_SWAP_LALT_LGUI:
56 keymap_config.swap_lalt_lgui = true;
57 break;
58 case MAGIC_SWAP_RALT_RGUI:
59 keymap_config.swap_ralt_rgui = true;
60 break;
61 case MAGIC_SWAP_LCTL_LGUI:
62 keymap_config.swap_lctl_lgui = true;
63 break;
64 case MAGIC_SWAP_RCTL_RGUI:
65 keymap_config.swap_rctl_rgui = true;
66 break;
67 case MAGIC_NO_GUI:
68 keymap_config.no_gui = true;
69 break;
70 case MAGIC_SWAP_GRAVE_ESC:
71 keymap_config.swap_grave_esc = true;
72 break;
73 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
74 keymap_config.swap_backslash_backspace = true;
75 break;
76 case MAGIC_HOST_NKRO:
77 clear_keyboard(); // clear first buffer to prevent stuck keys
78 keymap_config.nkro = true;
79 break;
80 case MAGIC_SWAP_ALT_GUI:
81 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
82#ifdef AUDIO_ENABLE
83 PLAY_SONG(ag_swap_song);
84#endif
85 break;
86 case MAGIC_SWAP_CTL_GUI:
87 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
88#ifdef AUDIO_ENABLE
89 PLAY_SONG(cg_swap_song);
90#endif
91 break;
92 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
93 keymap_config.swap_control_capslock = false;
94 break;
95 case MAGIC_UNCAPSLOCK_TO_CONTROL:
96 keymap_config.capslock_to_control = false;
97 break;
98 case MAGIC_UNSWAP_LALT_LGUI:
99 keymap_config.swap_lalt_lgui = false;
100 break;
101 case MAGIC_UNSWAP_RALT_RGUI:
102 keymap_config.swap_ralt_rgui = false;
103 break;
104 case MAGIC_UNSWAP_LCTL_LGUI:
105 keymap_config.swap_lctl_lgui = false;
106 break;
107 case MAGIC_UNSWAP_RCTL_RGUI:
108 keymap_config.swap_rctl_rgui = false;
109 break;
110 case MAGIC_UNNO_GUI:
111 keymap_config.no_gui = false;
112 break;
113 case MAGIC_UNSWAP_GRAVE_ESC:
114 keymap_config.swap_grave_esc = false;
115 break;
116 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
117 keymap_config.swap_backslash_backspace = false;
118 break;
119 case MAGIC_UNHOST_NKRO:
120 clear_keyboard(); // clear first buffer to prevent stuck keys
121 keymap_config.nkro = false;
122 break;
123 case MAGIC_UNSWAP_ALT_GUI:
124 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
125#ifdef AUDIO_ENABLE
126 PLAY_SONG(ag_norm_song);
127#endif
128 break;
129 case MAGIC_UNSWAP_CTL_GUI:
130 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
131#ifdef AUDIO_ENABLE
132 PLAY_SONG(cg_norm_song);
133#endif
134 break;
135 case MAGIC_TOGGLE_ALT_GUI:
136 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
137 keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui;
138#ifdef AUDIO_ENABLE
139 if (keymap_config.swap_ralt_rgui) {
140 PLAY_SONG(ag_swap_song);
141 } else {
142 PLAY_SONG(ag_norm_song);
143 }
144#endif
145 break;
146 case MAGIC_TOGGLE_CTL_GUI:
147 keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui;
148 keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui;
149#ifdef AUDIO_ENABLE
150 if (keymap_config.swap_rctl_rgui) {
151 PLAY_SONG(cg_swap_song);
152 } else {
153 PLAY_SONG(cg_norm_song);
154 }
155#endif
156 break;
157 case MAGIC_TOGGLE_NKRO:
158 clear_keyboard(); // clear first buffer to prevent stuck keys
159 keymap_config.nkro = !keymap_config.nkro;
160 break;
161 case MAGIC_EE_HANDS_LEFT:
162 eeconfig_update_handedness(true);
163 break;
164 case MAGIC_EE_HANDS_RIGHT:
165 eeconfig_update_handedness(false);
166 break;
167 }
168
169 eeconfig_update_keymap(keymap_config.raw);
170 clear_keyboard(); // clear to prevent stuck keys
171
172 return false;
173 }
174 }
175
176 // Not a magic keycode so continue processing
177 return true;
178}
diff --git a/quantum/process_keycode/process_magic.h b/quantum/process_keycode/process_magic.h
new file mode 100644
index 000000000..1eb39f145
--- /dev/null
+++ b/quantum/process_keycode/process_magic.h
@@ -0,0 +1,20 @@
1/* Copyright 2019
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#pragma once
17
18#include "quantum.h"
19
20bool process_magic(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_rgb.c b/quantum/process_keycode/process_rgb.c
new file mode 100644
index 000000000..c76166342
--- /dev/null
+++ b/quantum/process_keycode/process_rgb.c
@@ -0,0 +1,141 @@
1/* Copyright 2019
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#include "process_rgb.h"
17#include "rgb.h"
18
19typedef void (*rgb_func_pointer)(void);
20
21/**
22 * Wrapper for inc/dec rgb keycode
23 *
24 * noinline to optimise for firmware size not speed (not in hot path)
25 */
26static void __attribute__((noinline)) handleKeycodeRGB(const uint8_t is_shifted, const rgb_func_pointer inc_func, const rgb_func_pointer dec_func) {
27 if (is_shifted) {
28 dec_func();
29 } else {
30 inc_func();
31 }
32}
33
34/**
35 * Wrapper for animation mode
36 * - if not in animation family -> jump to that animation
37 * - otherwise -> wrap round animation speed
38 *
39 * noinline to optimise for firmware size not speed (not in hot path)
40 */
41static void __attribute__((noinline,unused)) handleKeycodeRGBMode(const uint8_t start, const uint8_t end) {
42 if ((start <= rgblight_get_mode()) && (rgblight_get_mode() < end)) {
43 rgblight_step();
44 } else {
45 rgblight_mode(start);
46 }
47}
48
49/**
50 * Handle keycodes for both rgblight and rgbmatrix
51 */
52bool process_rgb(const uint16_t keycode, const keyrecord_t *record) {
53#ifndef SPLIT_KEYBOARD
54 if (record->event.pressed) {
55#else
56 // Split keyboards need to trigger on key-up for edge-case issue
57 if (!record->event.pressed) {
58#endif
59 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
60 switch (keycode) {
61 case RGB_TOG:
62 rgblight_toggle();
63 return false;
64 case RGB_MODE_FORWARD:
65 handleKeycodeRGB(shifted, rgblight_step, rgblight_step_reverse);
66 return false;
67 case RGB_MODE_REVERSE:
68 handleKeycodeRGB(shifted, rgblight_step_reverse, rgblight_step);
69 return false;
70 case RGB_HUI:
71 handleKeycodeRGB(shifted, rgblight_increase_hue, rgblight_decrease_hue);
72 return false;
73 case RGB_HUD:
74 handleKeycodeRGB(shifted, rgblight_decrease_hue, rgblight_increase_hue);
75 return false;
76 case RGB_SAI:
77 handleKeycodeRGB(shifted, rgblight_increase_sat, rgblight_decrease_sat);
78 return false;
79 case RGB_SAD:
80 handleKeycodeRGB(shifted, rgblight_decrease_sat, rgblight_increase_sat);
81 return false;
82 case RGB_VAI:
83 handleKeycodeRGB(shifted, rgblight_increase_val, rgblight_decrease_val);
84 return false;
85 case RGB_VAD:
86 handleKeycodeRGB(shifted, rgblight_decrease_val, rgblight_increase_val);
87 return false;
88 case RGB_SPI:
89 handleKeycodeRGB(shifted, rgblight_increase_speed, rgblight_decrease_speed);
90 return false;
91 case RGB_SPD:
92 handleKeycodeRGB(shifted, rgblight_decrease_speed, rgblight_increase_speed);
93 return false;
94 case RGB_MODE_PLAIN:
95 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
96 return false;
97 case RGB_MODE_BREATHE:
98#ifdef RGBLIGHT_EFFECT_BREATHING
99 handleKeycodeRGBMode(RGBLIGHT_MODE_BREATHING, RGBLIGHT_MODE_BREATHING_end);
100#endif
101 return false;
102 case RGB_MODE_RAINBOW:
103#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
104 handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_MOOD, RGBLIGHT_MODE_RAINBOW_MOOD_end);
105#endif
106 return false;
107 case RGB_MODE_SWIRL:
108#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
109 handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_SWIRL, RGBLIGHT_MODE_RAINBOW_SWIRL_end);
110#endif
111 return false;
112 case RGB_MODE_SNAKE:
113#ifdef RGBLIGHT_EFFECT_SNAKE
114 handleKeycodeRGBMode(RGBLIGHT_MODE_SNAKE, RGBLIGHT_MODE_SNAKE_end);
115#endif
116 return false;
117 case RGB_MODE_KNIGHT:
118#ifdef RGBLIGHT_EFFECT_KNIGHT
119 handleKeycodeRGBMode(RGBLIGHT_MODE_KNIGHT, RGBLIGHT_MODE_KNIGHT_end);
120#endif
121 return false;
122 case RGB_MODE_XMAS:
123#ifdef RGBLIGHT_EFFECT_CHRISTMAS
124 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
125#endif
126 return false;
127 case RGB_MODE_GRADIENT:
128#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
129 handleKeycodeRGBMode(RGBLIGHT_MODE_STATIC_GRADIENT, RGBLIGHT_MODE_STATIC_GRADIENT_end);
130#endif
131 return false;
132 case RGB_MODE_RGBTEST:
133#ifdef RGBLIGHT_EFFECT_RGB_TEST
134 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
135#endif
136 return false;
137 }
138 }
139
140 return true;
141}
diff --git a/quantum/process_keycode/process_rgb.h b/quantum/process_keycode/process_rgb.h
new file mode 100644
index 000000000..26aca4689
--- /dev/null
+++ b/quantum/process_keycode/process_rgb.h
@@ -0,0 +1,20 @@
1/* Copyright 2019
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#pragma once
17
18#include "quantum.h"
19
20bool process_rgb(const uint16_t keycode, const keyrecord_t *record);
diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c
index e0b33ec86..57e279f21 100644
--- a/quantum/process_keycode/process_steno.c
+++ b/quantum/process_keycode/process_steno.c
@@ -73,7 +73,9 @@ static void steno_clear_state(void) {
73static void send_steno_state(uint8_t size, bool send_empty) { 73static void send_steno_state(uint8_t size, bool send_empty) {
74 for (uint8_t i = 0; i < size; ++i) { 74 for (uint8_t i = 0; i < size; ++i) {
75 if (chord[i] || send_empty) { 75 if (chord[i] || send_empty) {
76#ifdef VIRTSER_ENABLE
76 virtser_send(chord[i]); 77 virtser_send(chord[i]);
78#endif
77 } 79 }
78 } 80 }
79} 81}
@@ -105,7 +107,9 @@ static void send_steno_chord(void) {
105 switch (mode) { 107 switch (mode) {
106 case STENO_MODE_BOLT: 108 case STENO_MODE_BOLT:
107 send_steno_state(BOLT_STATE_SIZE, false); 109 send_steno_state(BOLT_STATE_SIZE, false);
110#ifdef VIRTSER_ENABLE
108 virtser_send(0); // terminating byte 111 virtser_send(0); // terminating byte
112#endif
109 break; 113 break;
110 case STENO_MODE_GEMINI: 114 case STENO_MODE_GEMINI:
111 chord[0] |= 0x80; // Indicate start of packet 115 chord[0] |= 0x80; // Indicate start of packet
diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h
index 367542372..ed049eb13 100644
--- a/quantum/process_keycode/process_steno.h
+++ b/quantum/process_keycode/process_steno.h
@@ -18,10 +18,6 @@
18 18
19#include "quantum.h" 19#include "quantum.h"
20 20
21#if defined(STENO_ENABLE) && !defined(VIRTSER_ENABLE)
22# error "must have virtser enabled to use steno"
23#endif
24
25typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t; 21typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t;
26 22
27bool process_steno(uint16_t keycode, keyrecord_t *record); 23bool process_steno(uint16_t keycode, keyrecord_t *record);
diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c
index f48f3d702..7d1eefa9e 100644
--- a/quantum/process_keycode/process_terminal.c
+++ b/quantum/process_keycode/process_terminal.c
@@ -61,7 +61,7 @@ void enable_terminal(void) {
61 memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80); 61 memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80);
62 for (int i = 0; i < 6; i++) strcpy(arguments[i], ""); 62 for (int i = 0; i < 6; i++) strcpy(arguments[i], "");
63 // select all text to start over 63 // select all text to start over
64 // SEND_STRING(SS_LCTRL("a")); 64 // SEND_STRING(SS_LCTL("a"));
65 send_string(terminal_prompt); 65 send_string(terminal_prompt);
66} 66}
67 67
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 2e5e6376b..9cd50b11d 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -16,10 +16,6 @@
16 16
17#include "quantum.h" 17#include "quantum.h"
18 18
19#if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
20# include "rgb.h"
21#endif
22
23#ifdef PROTOCOL_LUFA 19#ifdef PROTOCOL_LUFA
24# include "outputselect.h" 20# include "outputselect.h"
25#endif 21#endif
@@ -57,26 +53,13 @@ extern backlight_config_t backlight_config;
57# ifndef GOODBYE_SONG 53# ifndef GOODBYE_SONG
58# define GOODBYE_SONG SONG(GOODBYE_SOUND) 54# define GOODBYE_SONG SONG(GOODBYE_SOUND)
59# endif 55# endif
60# ifndef AG_NORM_SONG
61# define AG_NORM_SONG SONG(AG_NORM_SOUND)
62# endif
63# ifndef AG_SWAP_SONG
64# define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
65# endif
66# ifndef CG_NORM_SONG
67# define CG_NORM_SONG SONG(AG_NORM_SOUND)
68# endif
69# ifndef CG_SWAP_SONG
70# define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
71# endif
72float goodbye_song[][2] = GOODBYE_SONG; 56float goodbye_song[][2] = GOODBYE_SONG;
73float ag_norm_song[][2] = AG_NORM_SONG;
74float ag_swap_song[][2] = AG_SWAP_SONG;
75float cg_norm_song[][2] = CG_NORM_SONG;
76float cg_swap_song[][2] = CG_SWAP_SONG;
77# ifdef DEFAULT_LAYER_SONGS 57# ifdef DEFAULT_LAYER_SONGS
78float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; 58float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
79# endif 59# endif
60# ifdef SENDSTRING_BELL
61float bell_song[][2] = SONG(TERMINAL_SOUND);
62# endif
80#endif 63#endif
81 64
82static void do_code16(uint16_t code, void (*f)(uint8_t)) { 65static void do_code16(uint16_t code, void (*f)(uint8_t)) {
@@ -164,11 +147,6 @@ void reset_keyboard(void) {
164 bootloader_jump(); 147 bootloader_jump();
165} 148}
166 149
167/* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
168 * Used to ensure that the correct keycode is released if the key is released.
169 */
170static bool grave_esc_was_shifted = false;
171
172/* Convert record into usable keycode via the contained event. */ 150/* Convert record into usable keycode via the contained event. */
173uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); } 151uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
174 152
@@ -235,6 +213,9 @@ bool process_record_quantum(keyrecord_t *record) {
235#if defined(RGB_MATRIX_ENABLE) 213#if defined(RGB_MATRIX_ENABLE)
236 process_rgb_matrix(keycode, record) && 214 process_rgb_matrix(keycode, record) &&
237#endif 215#endif
216#if defined(VIA_ENABLE)
217 process_record_via(keycode, record) &&
218#endif
238 process_record_kb(keycode, record) && 219 process_record_kb(keycode, record) &&
239#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) 220#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
240 process_midi(keycode, record) && 221 process_midi(keycode, record) &&
@@ -272,402 +253,77 @@ bool process_record_quantum(keyrecord_t *record) {
272#ifdef SPACE_CADET_ENABLE 253#ifdef SPACE_CADET_ENABLE
273 process_space_cadet(keycode, record) && 254 process_space_cadet(keycode, record) &&
274#endif 255#endif
256#ifdef MAGIC_KEYCODE_ENABLE
257 process_magic(keycode, record) &&
258#endif
259#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
260 process_rgb(keycode, record) &&
261#endif
275 true)) { 262 true)) {
276 return false; 263 return false;
277 } 264 }
278 265
279 // Shift / paren setup 266 if (record->event.pressed) {
280 267 switch (keycode) {
281 switch (keycode) { 268 case RESET:
282 case RESET:
283 if (record->event.pressed) {
284 reset_keyboard(); 269 reset_keyboard();
285 } 270 return false;
286 return false; 271#ifndef NO_DEBUG
287 case DEBUG: 272 case DEBUG:
288 if (record->event.pressed) {
289 debug_enable ^= 1; 273 debug_enable ^= 1;
290 if (debug_enable) { 274 if (debug_enable) {
291 print("DEBUG: enabled.\n"); 275 print("DEBUG: enabled.\n");
292 } else { 276 } else {
293 print("DEBUG: disabled.\n"); 277 print("DEBUG: disabled.\n");
294 } 278 }
295 } 279#endif
296 return false; 280 return false;
297 case EEPROM_RESET: 281 case EEPROM_RESET:
298 if (record->event.pressed) {
299 eeconfig_init(); 282 eeconfig_init();
300 } 283 return false;
301 return false;
302#ifdef FAUXCLICKY_ENABLE 284#ifdef FAUXCLICKY_ENABLE
303 case FC_TOG: 285 case FC_TOG:
304 if (record->event.pressed) {
305 FAUXCLICKY_TOGGLE; 286 FAUXCLICKY_TOGGLE;
306 } 287 return false;
307 return false; 288 case FC_ON:
308 case FC_ON:
309 if (record->event.pressed) {
310 FAUXCLICKY_ON; 289 FAUXCLICKY_ON;
311 } 290 return false;
312 return false; 291 case FC_OFF:
313 case FC_OFF:
314 if (record->event.pressed) {
315 FAUXCLICKY_OFF; 292 FAUXCLICKY_OFF;
316 } 293 return false;
317 return false;
318#endif 294#endif
319#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
320 case RGB_TOG:
321// Split keyboards need to trigger on key-up for edge-case issue
322# ifndef SPLIT_KEYBOARD
323 if (record->event.pressed) {
324# else
325 if (!record->event.pressed) {
326# endif
327 rgblight_toggle();
328 }
329 return false;
330 case RGB_MODE_FORWARD:
331 if (record->event.pressed) {
332 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
333 if (shifted) {
334 rgblight_step_reverse();
335 } else {
336 rgblight_step();
337 }
338 }
339 return false;
340 case RGB_MODE_REVERSE:
341 if (record->event.pressed) {
342 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
343 if (shifted) {
344 rgblight_step();
345 } else {
346 rgblight_step_reverse();
347 }
348 }
349 return false;
350 case RGB_HUI:
351// Split keyboards need to trigger on key-up for edge-case issue
352# ifndef SPLIT_KEYBOARD
353 if (record->event.pressed) {
354# else
355 if (!record->event.pressed) {
356# endif
357 rgblight_increase_hue();
358 }
359 return false;
360 case RGB_HUD:
361// Split keyboards need to trigger on key-up for edge-case issue
362# ifndef SPLIT_KEYBOARD
363 if (record->event.pressed) {
364# else
365 if (!record->event.pressed) {
366# endif
367 rgblight_decrease_hue();
368 }
369 return false;
370 case RGB_SAI:
371// Split keyboards need to trigger on key-up for edge-case issue
372# ifndef SPLIT_KEYBOARD
373 if (record->event.pressed) {
374# else
375 if (!record->event.pressed) {
376# endif
377 rgblight_increase_sat();
378 }
379 return false;
380 case RGB_SAD:
381// Split keyboards need to trigger on key-up for edge-case issue
382# ifndef SPLIT_KEYBOARD
383 if (record->event.pressed) {
384# else
385 if (!record->event.pressed) {
386# endif
387 rgblight_decrease_sat();
388 }
389 return false;
390 case RGB_VAI:
391// Split keyboards need to trigger on key-up for edge-case issue
392# ifndef SPLIT_KEYBOARD
393 if (record->event.pressed) {
394# else
395 if (!record->event.pressed) {
396# endif
397 rgblight_increase_val();
398 }
399 return false;
400 case RGB_VAD:
401// Split keyboards need to trigger on key-up for edge-case issue
402# ifndef SPLIT_KEYBOARD
403 if (record->event.pressed) {
404# else
405 if (!record->event.pressed) {
406# endif
407 rgblight_decrease_val();
408 }
409 return false;
410 case RGB_SPI:
411 if (record->event.pressed) {
412 rgblight_increase_speed();
413 }
414 return false;
415 case RGB_SPD:
416 if (record->event.pressed) {
417 rgblight_decrease_speed();
418 }
419 return false;
420 case RGB_MODE_PLAIN:
421 if (record->event.pressed) {
422 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
423 }
424 return false;
425 case RGB_MODE_BREATHE:
426# ifdef RGBLIGHT_EFFECT_BREATHING
427 if (record->event.pressed) {
428 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
429 rgblight_step();
430 } else {
431 rgblight_mode(RGBLIGHT_MODE_BREATHING);
432 }
433 }
434# endif
435 return false;
436 case RGB_MODE_RAINBOW:
437# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
438 if (record->event.pressed) {
439 if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
440 rgblight_step();
441 } else {
442 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
443 }
444 }
445# endif
446 return false;
447 case RGB_MODE_SWIRL:
448# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
449 if (record->event.pressed) {
450 if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
451 rgblight_step();
452 } else {
453 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
454 }
455 }
456# endif
457 return false;
458 case RGB_MODE_SNAKE:
459# ifdef RGBLIGHT_EFFECT_SNAKE
460 if (record->event.pressed) {
461 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
462 rgblight_step();
463 } else {
464 rgblight_mode(RGBLIGHT_MODE_SNAKE);
465 }
466 }
467# endif
468 return false;
469 case RGB_MODE_KNIGHT:
470# ifdef RGBLIGHT_EFFECT_KNIGHT
471 if (record->event.pressed) {
472 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
473 rgblight_step();
474 } else {
475 rgblight_mode(RGBLIGHT_MODE_KNIGHT);
476 }
477 }
478# endif
479 return false;
480 case RGB_MODE_XMAS:
481# ifdef RGBLIGHT_EFFECT_CHRISTMAS
482 if (record->event.pressed) {
483 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
484 }
485# endif
486 return false;
487 case RGB_MODE_GRADIENT:
488# ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
489 if (record->event.pressed) {
490 if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
491 rgblight_step();
492 } else {
493 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
494 }
495 }
496# endif
497 return false;
498 case RGB_MODE_RGBTEST:
499# ifdef RGBLIGHT_EFFECT_RGB_TEST
500 if (record->event.pressed) {
501 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
502 }
503# endif
504 return false;
505#endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
506#ifdef VELOCIKEY_ENABLE 295#ifdef VELOCIKEY_ENABLE
507 case VLK_TOG: 296 case VLK_TOG:
508 if (record->event.pressed) {
509 velocikey_toggle(); 297 velocikey_toggle();
510 } 298 return false;
511 return false;
512#endif 299#endif
513#ifdef PROTOCOL_LUFA 300#ifdef BLUETOOTH_ENABLE
514 case OUT_AUTO: 301 case OUT_AUTO:
515 if (record->event.pressed) {
516 set_output(OUTPUT_AUTO); 302 set_output(OUTPUT_AUTO);
517 } 303 return false;
518 return false; 304 case OUT_USB:
519 case OUT_USB:
520 if (record->event.pressed) {
521 set_output(OUTPUT_USB); 305 set_output(OUTPUT_USB);
522 } 306 return false;
523 return false; 307 case OUT_BT:
524# ifdef BLUETOOTH_ENABLE
525 case OUT_BT:
526 if (record->event.pressed) {
527 set_output(OUTPUT_BLUETOOTH); 308 set_output(OUTPUT_BLUETOOTH);
528 } 309 return false;
529 return false;
530# endif
531#endif
532 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI:
533 case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT:
534 if (record->event.pressed) {
535 // MAGIC actions (BOOTMAGIC without the boot)
536 if (!eeconfig_is_enabled()) {
537 eeconfig_init();
538 }
539 /* keymap config */
540 keymap_config.raw = eeconfig_read_keymap();
541 switch (keycode) {
542 case MAGIC_SWAP_CONTROL_CAPSLOCK:
543 keymap_config.swap_control_capslock = true;
544 break;
545 case MAGIC_CAPSLOCK_TO_CONTROL:
546 keymap_config.capslock_to_control = true;
547 break;
548 case MAGIC_SWAP_LALT_LGUI:
549 keymap_config.swap_lalt_lgui = true;
550 break;
551 case MAGIC_SWAP_RALT_RGUI:
552 keymap_config.swap_ralt_rgui = true;
553 break;
554 case MAGIC_SWAP_LCTL_LGUI:
555 keymap_config.swap_lctl_lgui = true;
556 break;
557 case MAGIC_SWAP_RCTL_RGUI:
558 keymap_config.swap_rctl_rgui = true;
559 break;
560 case MAGIC_NO_GUI:
561 keymap_config.no_gui = true;
562 break;
563 case MAGIC_SWAP_GRAVE_ESC:
564 keymap_config.swap_grave_esc = true;
565 break;
566 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
567 keymap_config.swap_backslash_backspace = true;
568 break;
569 case MAGIC_HOST_NKRO:
570 clear_keyboard(); // clear first buffer to prevent stuck keys
571 keymap_config.nkro = true;
572 break;
573 case MAGIC_SWAP_ALT_GUI:
574 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
575#ifdef AUDIO_ENABLE
576 PLAY_SONG(ag_swap_song);
577#endif
578 break;
579 case MAGIC_SWAP_CTL_GUI:
580 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
581#ifdef AUDIO_ENABLE
582 PLAY_SONG(cg_swap_song);
583#endif
584 break;
585 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
586 keymap_config.swap_control_capslock = false;
587 break;
588 case MAGIC_UNCAPSLOCK_TO_CONTROL:
589 keymap_config.capslock_to_control = false;
590 break;
591 case MAGIC_UNSWAP_LALT_LGUI:
592 keymap_config.swap_lalt_lgui = false;
593 break;
594 case MAGIC_UNSWAP_RALT_RGUI:
595 keymap_config.swap_ralt_rgui = false;
596 break;
597 case MAGIC_UNSWAP_LCTL_LGUI:
598 keymap_config.swap_lctl_lgui = false;
599 break;
600 case MAGIC_UNSWAP_RCTL_RGUI:
601 keymap_config.swap_rctl_rgui = false;
602 break;
603 case MAGIC_UNNO_GUI:
604 keymap_config.no_gui = false;
605 break;
606 case MAGIC_UNSWAP_GRAVE_ESC:
607 keymap_config.swap_grave_esc = false;
608 break;
609 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
610 keymap_config.swap_backslash_backspace = false;
611 break;
612 case MAGIC_UNHOST_NKRO:
613 clear_keyboard(); // clear first buffer to prevent stuck keys
614 keymap_config.nkro = false;
615 break;
616 case MAGIC_UNSWAP_ALT_GUI:
617 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
618#ifdef AUDIO_ENABLE
619 PLAY_SONG(ag_norm_song);
620#endif
621 break;
622 case MAGIC_UNSWAP_CTL_GUI:
623 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
624#ifdef AUDIO_ENABLE
625 PLAY_SONG(cg_norm_song);
626#endif 310#endif
627 break; 311#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
628 case MAGIC_TOGGLE_ALT_GUI: 312 case BL_BRTG:
629 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; 313 backlight_toggle_breathing();
630 keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui;
631#ifdef AUDIO_ENABLE
632 if (keymap_config.swap_ralt_rgui) {
633 PLAY_SONG(ag_swap_song);
634 } else {
635 PLAY_SONG(ag_norm_song);
636 }
637#endif
638 break;
639 case MAGIC_TOGGLE_CTL_GUI:
640 keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui;
641 keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui;
642#ifdef AUDIO_ENABLE
643 if (keymap_config.swap_rctl_rgui) {
644 PLAY_SONG(cg_swap_song);
645 } else {
646 PLAY_SONG(cg_norm_song);
647 }
648#endif
649 break;
650 case MAGIC_TOGGLE_NKRO:
651 clear_keyboard(); // clear first buffer to prevent stuck keys
652 keymap_config.nkro = !keymap_config.nkro;
653 break;
654 case MAGIC_EE_HANDS_LEFT:
655 eeconfig_update_handedness(true);
656 break;
657 case MAGIC_EE_HANDS_RIGHT:
658 eeconfig_update_handedness(false);
659 break;
660 default:
661 break;
662 }
663 eeconfig_update_keymap(keymap_config.raw);
664 clear_keyboard(); // clear to prevent stuck keys
665
666 return false; 314 return false;
667 } 315#endif
668 break; 316 }
317 }
669 318
319 // keycodes that depend on both pressed and non-pressed state
320 switch (keycode) {
670 case GRAVE_ESC: { 321 case GRAVE_ESC: {
322 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
323 * Used to ensure that the correct keycode is released if the key is released.
324 */
325 static bool grave_esc_was_shifted = false;
326
671 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))); 327 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)));
672 328
673#ifdef GRAVE_ESC_ALT_OVERRIDE 329#ifdef GRAVE_ESC_ALT_OVERRIDE
@@ -710,15 +366,6 @@ bool process_record_quantum(keyrecord_t *record) {
710 send_keyboard_report(); 366 send_keyboard_report();
711 return false; 367 return false;
712 } 368 }
713
714#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
715 case BL_BRTG: {
716 if (record->event.pressed) {
717 backlight_toggle_breathing();
718 }
719 return false;
720 }
721#endif
722 } 369 }
723 370
724 return process_action_kb(record); 371 return process_action_kb(record);
@@ -829,6 +476,13 @@ void send_string_with_delay_P(const char *str, uint8_t interval) {
829} 476}
830 477
831void send_char(char ascii_code) { 478void send_char(char ascii_code) {
479#if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
480 if (ascii_code == '\a') { // BEL
481 PLAY_SONG(bell_song);
482 return;
483 }
484#endif
485
832 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]); 486 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
833 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]); 487 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]);
834 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]); 488 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]);
@@ -909,9 +563,7 @@ __attribute__((weak)) void bootmagic_lite(void) {
909 563
910 // We need multiple scans because debouncing can't be turned off. 564 // We need multiple scans because debouncing can't be turned off.
911 matrix_scan(); 565 matrix_scan();
912#if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0 566#if defined(DEBOUNCE) && DEBOUNCE > 0
913 wait_ms(DEBOUNCING_DELAY * 2);
914#elif defined(DEBOUNCE) && DEBOUNCE > 0
915 wait_ms(DEBOUNCE * 2); 567 wait_ms(DEBOUNCE * 2);
916#else 568#else
917 wait_ms(30); 569 wait_ms(30);
@@ -982,12 +634,8 @@ void matrix_scan_quantum() {
982 matrix_scan_combo(); 634 matrix_scan_combo();
983#endif 635#endif
984 636
985#if defined(BACKLIGHT_ENABLE) 637#ifdef LED_MATRIX_ENABLE
986# if defined(LED_MATRIX_ENABLE)
987 led_matrix_task(); 638 led_matrix_task();
988# elif defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)
989 backlight_task();
990# endif
991#endif 639#endif
992 640
993#ifdef RGB_MATRIX_ENABLE 641#ifdef RGB_MATRIX_ENABLE
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 6beab65a3..09550fec3 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -22,6 +22,7 @@
22#endif 22#endif
23#if defined(PROTOCOL_CHIBIOS) 23#if defined(PROTOCOL_CHIBIOS)
24# include "hal.h" 24# include "hal.h"
25# include "chibios_config.h"
25#endif 26#endif
26 27
27#include "wait.h" 28#include "wait.h"
@@ -133,6 +134,14 @@ extern layer_state_t layer_state;
133# include "process_space_cadet.h" 134# include "process_space_cadet.h"
134#endif 135#endif
135 136
137#ifdef MAGIC_KEYCODE_ENABLE
138# include "process_magic.h"
139#endif
140
141#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
142# include "process_rgb.h"
143#endif
144
136#ifdef HD44780_ENABLE 145#ifdef HD44780_ENABLE
137# include "hd44780.h" 146# include "hd44780.h"
138#endif 147#endif
@@ -153,6 +162,14 @@ extern layer_state_t layer_state;
153# include "process_dynamic_macro.h" 162# include "process_dynamic_macro.h"
154#endif 163#endif
155 164
165#ifdef DYNAMIC_KEYMAP_ENABLE
166# include "dynamic_keymap.h"
167#endif
168
169#ifdef VIA_ENABLE
170# include "via.h"
171#endif
172
156// Function substitutions to ease GPIO manipulation 173// Function substitutions to ease GPIO manipulation
157#if defined(__AVR__) 174#if defined(__AVR__)
158typedef uint8_t pin_t; 175typedef uint8_t pin_t;
@@ -182,30 +199,8 @@ typedef ioline_t pin_t;
182# define readPin(pin) palReadLine(pin) 199# define readPin(pin) palReadLine(pin)
183#endif 200#endif
184 201
185// Send string macros
186#define STRINGIZE(z) #z
187#define ADD_SLASH_X(y) STRINGIZE(\x##y)
188#define SYMBOL_STR(x) ADD_SLASH_X(x)
189
190#define SS_TAP_CODE 1
191#define SS_DOWN_CODE 2
192#define SS_UP_CODE 3
193
194#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode)
195#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode)
196#define SS_UP(keycode) "\3" SYMBOL_STR(keycode)
197
198// `string` arguments must not be parenthesized
199#define SS_LCTRL(string) SS_DOWN(X_LCTRL) string SS_UP(X_LCTRL)
200#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
201#define SS_LCMD(string) SS_LGUI(string)
202#define SS_LWIN(string) SS_LGUI(string)
203#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
204#define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT)
205#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
206#define SS_ALGR(string) SS_RALT(string)
207
208#define SEND_STRING(string) send_string_P(PSTR(string)) 202#define SEND_STRING(string) send_string_P(PSTR(string))
203#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
209 204
210extern const bool ascii_to_shift_lut[128]; 205extern const bool ascii_to_shift_lut[128];
211extern const bool ascii_to_altgr_lut[128]; 206extern const bool ascii_to_altgr_lut[128];
@@ -256,30 +251,6 @@ void register_code16(uint16_t code);
256void unregister_code16(uint16_t code); 251void unregister_code16(uint16_t code);
257void tap_code16(uint16_t code); 252void tap_code16(uint16_t code);
258 253
259#ifdef BACKLIGHT_ENABLE
260void backlight_init_ports(void);
261void backlight_task(void);
262void backlight_task_internal(void);
263void backlight_on(pin_t backlight_pin);
264void backlight_off(pin_t backlight_pin);
265
266# ifdef BACKLIGHT_BREATHING
267void breathing_task(void);
268void breathing_enable(void);
269void breathing_pulse(void);
270void breathing_disable(void);
271void breathing_self_disable(void);
272void breathing_toggle(void);
273bool is_breathing(void);
274
275void breathing_intensity_default(void);
276void breathing_period_default(void);
277void breathing_period_set(uint8_t value);
278void breathing_period_inc(void);
279void breathing_period_dec(void);
280# endif
281#endif
282
283void send_dword(uint32_t number); 254void send_dword(uint32_t number);
284void send_word(uint16_t number); 255void send_word(uint16_t number);
285void send_byte(uint8_t number); 256void send_byte(uint8_t number);
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 66a3c66e8..c8d0e354b 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -655,13 +655,42 @@ enum quantum_keycodes {
655// L-ayer, T-ap - 256 keycode max, 16 layer max 655// L-ayer, T-ap - 256 keycode max, 16 layer max
656#define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF)) 656#define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF))
657 657
658#define CL_SWAP MAGIC_SWAP_CONTROL_CAPSLOCK
659#define CL_NORM MAGIC_UNSWAP_CONTROL_CAPSLOCK
660#define CL_CTRL MAGIC_CAPSLOCK_TO_CONTROL
661#define CL_CAPS MAGIC_UNCAPSLOCK_TO_CONTROL
662
663#define LCG_SWP MAGIC_SWAP_LCTL_LGUI
664#define LCG_NRM MAGIC_UNSWAP_LCTL_LGUI
665#define RCG_SWP MAGIC_SWAP_RCTL_RGUI
666#define RCG_NRM MAGIC_UNSWAP_RCTL_RGUI
667#define CG_SWAP MAGIC_SWAP_CTL_GUI
668#define CG_NORM MAGIC_UNSWAP_CTL_GUI
669#define CG_TOGG MAGIC_TOGGLE_CTL_GUI
670
671#define LAG_SWP MAGIC_SWAP_LALT_LGUI
672#define LAG_NRM MAGIC_UNSWAP_LALT_LGUI
673#define RAG_SWP MAGIC_SWAP_RALT_RGUI
674#define RAG_NRM MAGIC_UNSWAP_RALT_RGUI
658#define AG_SWAP MAGIC_SWAP_ALT_GUI 675#define AG_SWAP MAGIC_SWAP_ALT_GUI
659#define AG_NORM MAGIC_UNSWAP_ALT_GUI 676#define AG_NORM MAGIC_UNSWAP_ALT_GUI
660#define AG_TOGG MAGIC_TOGGLE_ALT_GUI 677#define AG_TOGG MAGIC_TOGGLE_ALT_GUI
661 678
662#define CG_SWAP MAGIC_SWAP_CTL_GUI 679#define GUI_OFF MAGIC_NO_GUI
663#define CG_NORM MAGIC_UNSWAP_CTL_GUI 680#define GUI_ON MAGIC_UNNO_GUI
664#define CG_TOGG MAGIC_TOGGLE_CTL_GUI 681
682#define GE_SWAP MAGIC_SWAP_GRAVE_ESC
683#define GE_NORM MAGIC_UNSWAP_GRAVE_ESC
684
685#define BS_SWAP MAGIC_SWAP_BACKSLASH_BACKSPACE
686#define BS_NORM MAGIC_UNSWAP_BACKSLASH_BACKSPACE
687
688#define NK_ON MAGIC_HOST_NKRO
689#define NK_OFF MAGIC_UNHOST_NKRO
690#define NK_TOGG MAGIC_TOGGLE_NKRO
691
692#define EH_LEFT MAGIC_EE_HANDS_LEFT
693#define EH_RGHT MAGIC_EE_HANDS_RIGHT
665 694
666// GOTO layer - 16 layers max 695// GOTO layer - 16 layers max
667// when: 696// when:
diff --git a/quantum/rgb_matrix.c b/quantum/rgb_matrix.c
index 55a6f74be..25ca44054 100644
--- a/quantum/rgb_matrix.c
+++ b/quantum/rgb_matrix.c
@@ -95,6 +95,23 @@ const point_t k_rgb_matrix_center = RGB_MATRIX_CENTER;
95# endif 95# endif
96#endif 96#endif
97 97
98#if !defined(RGB_MATRIX_STARTUP_HUE)
99# define RGB_MATRIX_STARTUP_HUE 0
100#endif
101
102#if !defined(RGB_MATRIX_STARTUP_SAT)
103# define RGB_MATRIX_STARTUP_SAT UINT8_MAX
104#endif
105
106#if !defined(RGB_MATRIX_STARTUP_VAL)
107# define RGB_MATRIX_STARTUP_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS
108#endif
109
110#if !defined(RGB_MATRIX_STARTUP_SPD)
111# define RGB_MATRIX_STARTUP_SPD UINT8_MAX / 2
112#endif
113
114
98bool g_suspend_state = false; 115bool g_suspend_state = false;
99 116
100rgb_config_t rgb_matrix_config; 117rgb_config_t rgb_matrix_config;
@@ -119,8 +136,8 @@ void eeconfig_update_rgb_matrix_default(void) {
119 dprintf("eeconfig_update_rgb_matrix_default\n"); 136 dprintf("eeconfig_update_rgb_matrix_default\n");
120 rgb_matrix_config.enable = 1; 137 rgb_matrix_config.enable = 1;
121 rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE; 138 rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE;
122 rgb_matrix_config.hsv = (HSV){0, UINT8_MAX, RGB_MATRIX_MAXIMUM_BRIGHTNESS}; 139 rgb_matrix_config.hsv = (HSV){RGB_MATRIX_STARTUP_HUE, RGB_MATRIX_STARTUP_SAT, RGB_MATRIX_STARTUP_VAL};
123 rgb_matrix_config.speed = UINT8_MAX / 2; 140 rgb_matrix_config.speed = RGB_MATRIX_STARTUP_SPD;
124 eeconfig_update_rgb_matrix(); 141 eeconfig_update_rgb_matrix();
125} 142}
126 143
@@ -417,7 +434,12 @@ void rgb_matrix_init(void) {
417 eeconfig_debug_rgb_matrix(); // display current eeprom values 434 eeconfig_debug_rgb_matrix(); // display current eeprom values
418} 435}
419 436
420void rgb_matrix_set_suspend_state(bool state) { g_suspend_state = state; } 437void rgb_matrix_set_suspend_state(bool state) {
438 if (RGB_DISABLE_WHEN_USB_SUSPENDED && state) {
439 rgb_matrix_set_color_all(0, 0, 0); // turn off all LEDs when suspending
440 }
441 g_suspend_state = state;
442}
421 443
422void rgb_matrix_toggle(void) { 444void rgb_matrix_toggle(void) {
423 rgb_matrix_config.enable ^= 1; 445 rgb_matrix_config.enable ^= 1;
diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h
index 16ec96f03..96494836e 100644
--- a/quantum/rgb_matrix.h
+++ b/quantum/rgb_matrix.h
@@ -128,26 +128,26 @@ void 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); 128void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val);
129 129
130#ifndef RGBLIGHT_ENABLE 130#ifndef RGBLIGHT_ENABLE
131# define rgblight_toggle() rgb_matrix_toggle() 131# define rgblight_toggle rgb_matrix_toggle
132# define rgblight_enable() rgb_matrix_enable() 132# define rgblight_enable rgb_matrix_enable
133# define rgblight_enable_noeeprom() rgb_matrix_enable_noeeprom() 133# define rgblight_enable_noeeprom rgb_matrix_enable_noeeprom
134# define rgblight_disable() rgb_matrix_disable() 134# define rgblight_disable rgb_matrix_disable
135# define rgblight_disable_noeeprom() rgb_matrix_disable_noeeprom() 135# define rgblight_disable_noeeprom rgb_matrix_disable_noeeprom
136# define rgblight_step() rgb_matrix_step() 136# define rgblight_step rgb_matrix_step
137# define rgblight_sethsv(hue, sat, val) rgb_matrix_sethsv(hue, sat, val) 137# define rgblight_sethsv rgb_matrix_sethsv
138# define rgblight_sethsv_noeeprom(hue, sat, val) rgb_matrix_sethsv_noeeprom(hue, sat, val) 138# define rgblight_sethsv_noeeprom rgb_matrix_sethsv_noeeprom
139# define rgblight_step_reverse() rgb_matrix_step_reverse() 139# define rgblight_step_reverse rgb_matrix_step_reverse
140# define rgblight_increase_hue() rgb_matrix_increase_hue() 140# define rgblight_increase_hue rgb_matrix_increase_hue
141# define rgblight_decrease_hue() rgb_matrix_decrease_hue() 141# define rgblight_decrease_hue rgb_matrix_decrease_hue
142# define rgblight_increase_sat() rgb_matrix_increase_sat() 142# define rgblight_increase_sat rgb_matrix_increase_sat
143# define rgblight_decrease_sat() rgb_matrix_decrease_sat() 143# define rgblight_decrease_sat rgb_matrix_decrease_sat
144# define rgblight_increase_val() rgb_matrix_increase_val() 144# define rgblight_increase_val rgb_matrix_increase_val
145# define rgblight_decrease_val() rgb_matrix_decrease_val() 145# define rgblight_decrease_val rgb_matrix_decrease_val
146# define rgblight_increase_speed() rgb_matrix_increase_speed() 146# define rgblight_increase_speed rgb_matrix_increase_speed
147# define rgblight_decrease_speed() rgb_matrix_decrease_speed() 147# define rgblight_decrease_speed rgb_matrix_decrease_speed
148# define rgblight_mode(mode) rgb_matrix_mode(mode) 148# define rgblight_mode rgb_matrix_mode
149# define rgblight_mode_noeeprom(mode) rgb_matrix_mode_noeeprom(mode) 149# define rgblight_mode_noeeprom rgb_matrix_mode_noeeprom
150# define rgblight_get_mode() rgb_matrix_get_mode() 150# define rgblight_get_mode rgb_matrix_get_mode
151#endif 151#endif
152 152
153typedef struct { 153typedef struct {
diff --git a/quantum/rgb_matrix_animations/gradient_left_right_anim.h b/quantum/rgb_matrix_animations/gradient_left_right_anim.h
new file mode 100644
index 000000000..2eab2eb75
--- /dev/null
+++ b/quantum/rgb_matrix_animations/gradient_left_right_anim.h
@@ -0,0 +1,22 @@
1#ifndef DISABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
2RGB_MATRIX_EFFECT(GRADIENT_LEFT_RIGHT)
3# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
4
5bool GRADIENT_LEFT_RIGHT(effect_params_t* params) {
6 RGB_MATRIX_USE_LIMITS(led_min, led_max);
7
8 HSV hsv = rgb_matrix_config.hsv;
9 uint8_t scale = scale8(64, rgb_matrix_config.speed);
10 for (uint8_t i = led_min; i < led_max; i++) {
11 RGB_MATRIX_TEST_LED_FLAGS();
12 // The x range will be 0..224, map this to 0..7
13 // Relies on hue being 8-bit and wrapping
14 hsv.h = rgb_matrix_config.hsv.h + (scale * g_led_config.point[i].x >> 5);
15 RGB rgb = hsv_to_rgb(hsv);
16 rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
17 }
18 return led_max < DRIVER_LED_TOTAL;
19}
20
21# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
22#endif // DISABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
diff --git a/quantum/rgb_matrix_animations/rgb_matrix_effects.inc b/quantum/rgb_matrix_animations/rgb_matrix_effects.inc
index 01332ed0d..4c1723d93 100644
--- a/quantum/rgb_matrix_animations/rgb_matrix_effects.inc
+++ b/quantum/rgb_matrix_animations/rgb_matrix_effects.inc
@@ -2,6 +2,7 @@
2#include "rgb_matrix_animations/solid_color_anim.h" 2#include "rgb_matrix_animations/solid_color_anim.h"
3#include "rgb_matrix_animations/alpha_mods_anim.h" 3#include "rgb_matrix_animations/alpha_mods_anim.h"
4#include "rgb_matrix_animations/gradient_up_down_anim.h" 4#include "rgb_matrix_animations/gradient_up_down_anim.h"
5#include "rgb_matrix_animations/gradient_left_right_anim.h"
5#include "rgb_matrix_animations/breathing_anim.h" 6#include "rgb_matrix_animations/breathing_anim.h"
6#include "rgb_matrix_animations/colorband_sat_anim.h" 7#include "rgb_matrix_animations/colorband_sat_anim.h"
7#include "rgb_matrix_animations/colorband_val_anim.h" 8#include "rgb_matrix_animations/colorband_val_anim.h"
diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c
index 9729a3064..ea41b0d39 100644
--- a/quantum/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix_drivers.c
@@ -113,7 +113,7 @@ static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
113 led[i].g = g; 113 led[i].g = g;
114 led[i].b = b; 114 led[i].b = b;
115# ifdef RGBW 115# ifdef RGBW
116 led[i].w = 0; 116 convert_rgb_to_rgbw(led[i]);
117# endif 117# endif
118} 118}
119 119
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 7949bb688..141dc2e7b 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -611,6 +611,7 @@ void rgblight_set(void) {
611# endif 611# endif
612 } 612 }
613 } 613 }
614
614# ifdef RGBLIGHT_LED_MAP 615# ifdef RGBLIGHT_LED_MAP
615 LED_TYPE led0[RGBLED_NUM]; 616 LED_TYPE led0[RGBLED_NUM];
616 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 617 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
@@ -620,7 +621,13 @@ void rgblight_set(void) {
620# else 621# else
621 start_led = led + clipping_start_pos; 622 start_led = led + clipping_start_pos;
622# endif 623# endif
623 ws2812_setleds(start_led, num_leds); 624
625#ifdef RGBW
626 for (uint8_t i = 0; i < num_leds; i++) {
627 convert_rgb_to_rgbw(&start_led[i]);
628 }
629#endif
630 ws2812_setleds(start_led, num_leds);
624} 631}
625#endif 632#endif
626 633
diff --git a/quantum/send_string_keycodes.h b/quantum/send_string_keycodes.h
index e71790a1d..fc6467a74 100644
--- a/quantum/send_string_keycodes.h
+++ b/quantum/send_string_keycodes.h
@@ -1,207 +1,374 @@
1#ifndef SEND_STRING_KEYCODES 1/* Copyright 2019
2#define SEND_STRING_KEYCODES 2 *
3 3 * This program is free software: you can redistribute it and/or modify
4#define X_NO 00 4 * it under the terms of the GNU General Public License as published by
5#define X_ROLL_OVER 01 5 * the Free Software Foundation, either version 2 of the License, or
6#define X_POST_FAIL 02 6 * (at your option) any later version.
7#define X_UNDEFINED 03 7 *
8#define X_A 04 8 * This program is distributed in the hope that it will be useful,
9#define X_B 05 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10#define X_C 06 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11#define X_D 07 11 * GNU General Public License for more details.
12#define X_E 08 12 *
13#define X_F 09 13 * You should have received a copy of the GNU General Public License
14#define X_G 0a 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15#define X_H 0b 15 */
16#define X_I 0c 16
17#define X_J 0d 17#pragma once
18#define X_K 0e 18
19#define X_L 0f 19// clang-format off
20#define X_M 10 20
21#define X_N 11 21/* Punctuation */
22#define X_O 12 22#define X_ENT X_ENTER
23#define X_P 13 23#define X_ESC X_ESCAPE
24#define X_Q 14 24#define X_BSPC X_BSPACE
25#define X_R 15 25#define X_SPC X_SPACE
26#define X_S 16 26#define X_MINS X_MINUS
27#define X_T 17 27#define X_EQL X_EQUAL
28#define X_U 18 28#define X_LBRC X_LBRACKET
29#define X_V 19 29#define X_RBRC X_RBRACKET
30#define X_W 1a 30#define X_BSLS X_BSLASH
31#define X_X 1b 31#define X_NUHS X_NONUS_HASH
32#define X_Y 1c 32#define X_SCLN X_SCOLON
33#define X_Z 1d 33#define X_QUOT X_QUOTE
34#define X_1 1e 34#define X_GRV X_GRAVE
35#define X_2 1f 35#define X_COMM X_COMMA
36#define X_3 20 36#define X_SLSH X_SLASH
37#define X_4 21 37#define X_NUBS X_NONUS_BSLASH
38#define X_5 22 38
39#define X_6 23 39/* Lock Keys */
40#define X_7 24 40#define X_CLCK X_CAPSLOCK
41#define X_8 25 41#define X_CAPS X_CAPSLOCK
42#define X_9 26 42#define X_SLCK X_SCROLLLOCK
43#define X_0 27 43#define X_NLCK X_NUMLOCK
44#define X_ENTER 28 44#define X_LCAP X_LOCKING_CAPS
45#define X_ESCAPE 29 45#define X_LNUM X_LOCKING_NUM
46#define X_BSPACE 2a 46#define X_LSCR X_LOCKING_SCROLL
47#define X_TAB 2b 47
48#define X_SPACE 2c 48/* Commands */
49#define X_MINUS 2d 49#define X_PSCR X_PSCREEN
50#define X_EQUAL 2e 50#define X_PAUS X_PAUSE
51#define X_LBRACKET 2f 51#define X_BRK X_PAUSE
52#define X_RBRACKET 30 52#define X_INS X_INSERT
53#define X_BSLASH 31 53#define X_DEL X_DELETE
54#define X_NONUS_HASH 32 54#define X_PGDN X_PGDOWN
55#define X_SCOLON 33 55#define X_RGHT X_RIGHT
56#define X_QUOTE 34 56#define X_APP X_APPLICATION
57#define X_GRAVE 35 57#define X_EXEC X_EXECUTE
58#define X_COMMA 36 58#define X_SLCT X_SELECT
59#define X_DOT 37 59#define X_AGIN X_AGAIN
60#define X_SLASH 38 60#define X_PSTE X_PASTE
61#define X_CAPSLOCK 39 61#define X_ERAS X_ALT_ERASE
62#define X_F1 3a 62#define X_CLR X_CLEAR
63#define X_F2 3b 63
64#define X_F3 3c 64/* Keypad */
65#define X_F4 3d 65#define X_PSLS X_KP_SLASH
66#define X_F5 3e 66#define X_PAST X_KP_ASTERISK
67#define X_F6 3f 67#define X_PMNS X_KP_MINUS
68#define X_F7 40 68#define X_PPLS X_KP_PLUS
69#define X_F8 41 69#define X_PENT X_KP_ENTER
70#define X_F9 42 70#define X_P1 X_KP_1
71#define X_F10 43 71#define X_P2 X_KP_2
72#define X_F11 44 72#define X_P3 X_KP_3
73#define X_F12 45 73#define X_P4 X_KP_4
74#define X_PSCREEN 46 74#define X_P5 X_KP_5
75#define X_SCROLLLOCK 47 75#define X_P6 X_KP_6
76#define X_PAUSE 48 76#define X_P7 X_KP_7
77#define X_INSERT 49 77#define X_P8 X_KP_8
78#define X_HOME 4a 78#define X_P9 X_KP_9
79#define X_PGUP 4b 79#define X_P0 X_KP_0
80#define X_DELETE 4c 80#define X_PDOT X_KP_DOT
81#define X_END 4d 81#define X_PEQL X_KP_EQUAL
82#define X_PGDOWN 4e 82#define X_PCMM X_KP_COMMA
83#define X_RIGHT 4f 83
84#define X_LEFT 50 84/* Japanese specific */
85#define X_DOWN 51 85#define X_ZKHK X_GRAVE
86#define X_UP 52 86#define X_RO X_INT1
87#define X_NUMLOCK 53 87#define X_KANA X_INT2
88#define X_KP_SLASH 54 88#define X_JYEN X_INT3
89#define X_KP_ASTERISK 55 89#define X_HENK X_INT4
90#define X_KP_MINUS 56 90#define X_MHEN X_INT5
91#define X_KP_PLUS 57 91
92#define X_KP_ENTER 58 92/* Korean specific */
93#define X_KP_1 59 93#define X_HAEN X_LANG1
94#define X_KP_2 5a 94#define X_HANJ X_LANG2
95#define X_KP_3 5b 95
96#define X_KP_4 5c 96/* Modifiers */
97#define X_KP_5 5d 97#define X_LCTL X_LCTRL
98#define X_KP_6 5e 98#define X_LSFT X_LSHIFT
99#define X_KP_7 5f 99#define X_LCMD X_LGUI
100#define X_KP_8 60 100#define X_LWIN X_LGUI
101#define X_KP_9 61 101#define X_RCTL X_RCTRL
102#define X_KP_0 62 102#define X_RSFT X_RSHIFT
103#define X_KP_DOT 63 103#define X_ALGR X_RALT
104#define X_NONUS_BSLASH 64 104#define X_RCMD X_RGUI
105#define X_APPLICATION 65 105#define X_RWIN X_RGUI
106#define X_POWER 66 106
107#define X_KP_EQUAL 67 107/* Generic Desktop Page (0x01) */
108#define X_F13 68 108#define X_PWR X_SYSTEM_POWER
109#define X_F14 69 109#define X_SLEP X_SYSTEM_SLEEP
110#define X_F15 6a 110#define X_WAKE X_SYSTEM_WAKE
111#define X_F16 6b 111
112#define X_F17 6c 112/* Consumer Page (0x0C) */
113#define X_F18 6d 113#define X_MUTE X_AUDIO_MUTE
114#define X_F19 6e 114#define X_VOLU X_AUDIO_VOL_UP
115#define X_F20 6f 115#define X_VOLD X_AUDIO_VOL_DOWN
116#define X_F21 70 116#define X_MNXT X_MEDIA_NEXT_TRACK
117#define X_F22 71 117#define X_MPRV X_MEDIA_PREV_TRACK
118#define X_F23 72 118#define X_MSTP X_MEDIA_STOP
119#define X_F24 73 119#define X_MPLY X_MEDIA_PLAY_PAUSE
120#define X_EXECUTE 74 120#define X_MSEL X_MEDIA_SELECT
121#define X_HELP 75 121#define X_EJCT X_MEDIA_EJECT
122#define X_MENU 76 122#define X_CALC X_CALCULATOR
123#define X_SELECT 77 123#define X_MYCM X_MY_COMPUTER
124#define X_STOP 78 124#define X_WSCH X_WWW_SEARCH
125#define X_AGAIN 79 125#define X_WHOM X_WWW_HOME
126#define X_UNDO 7a 126#define X_WBAK X_WWW_BACK
127#define X_CUT 7b 127#define X_WFWD X_WWW_FORWARD
128#define X_COPY 7c 128#define X_WSTP X_WWW_STOP
129#define X_PASTE 7d 129#define X_WREF X_WWW_REFRESH
130#define X_FIND 7e 130#define X_WFAV X_WWW_FAVORITES
131#define X__MUTE 7f 131#define X_MFFD X_MEDIA_FAST_FORWARD
132#define X__VOLUP 80 132#define X_MRWD X_MEDIA_REWIND
133#define X__VOLDOWN 81 133#define X_BRIU X_BRIGHTNESS_UP
134#define X_LOCKING_CAPS 82 134#define X_BRID X_BRIGHTNESS_DOWN
135#define X_LOCKING_NUM 83 135
136#define X_LOCKING_SCROLL 84 136/* System Specific */
137#define X_KP_COMMA 85 137#define X_BRMU X_PAUSE
138#define X_KP_EQUAL_AS400 86 138#define X_BRMD X_SCROLLLOCK
139#define X_INT1 87 139
140#define X_INT2 88 140/* Keyboard/Keypad Page (0x07) */
141#define X_INT3 89 141#define X_A 04
142#define X_INT4 8a 142#define X_B 05
143#define X_INT5 8b 143#define X_C 06
144#define X_INT6 8c 144#define X_D 07
145#define X_INT7 8d 145#define X_E 08
146#define X_INT8 8e 146#define X_F 09
147#define X_INT9 8f 147#define X_G 0a
148#define X_LANG1 90 148#define X_H 0b
149#define X_LANG2 91 149#define X_I 0c
150#define X_LANG3 92 150#define X_J 0d
151#define X_LANG4 93 151#define X_K 0e
152#define X_LANG5 94 152#define X_L 0f
153#define X_LANG6 95 153#define X_M 10
154#define X_LANG7 96 154#define X_N 11
155#define X_LANG8 97 155#define X_O 12
156#define X_LANG9 98 156#define X_P 13
157#define X_ALT_ERASE 99 157#define X_Q 14
158#define X_SYSREQ 9a 158#define X_R 15
159#define X_CANCEL 9b 159#define X_S 16
160#define X_CLEAR 9c 160#define X_T 17
161#define X_PRIOR 9d 161#define X_U 18
162#define X_RETURN 9e 162#define X_V 19
163#define X_SEPARATOR 9f 163#define X_W 1a
164#define X_OUT a0 164#define X_X 1b
165#define X_OPER a1 165#define X_Y 1c
166#define X_CLEAR_AGAIN a2 166#define X_Z 1d
167#define X_CRSEL a3 167#define X_1 1e
168#define X_EXSEL a4 168#define X_2 1f
169#define X_3 20
170#define X_4 21
171#define X_5 22
172#define X_6 23
173#define X_7 24
174#define X_8 25
175#define X_9 26
176#define X_0 27
177#define X_ENTER 28
178#define X_ESCAPE 29
179#define X_BSPACE 2a
180#define X_TAB 2b
181#define X_SPACE 2c
182#define X_MINUS 2d
183#define X_EQUAL 2e
184#define X_LBRACKET 2f
185#define X_RBRACKET 30
186#define X_BSLASH 31
187#define X_NONUS_HASH 32
188#define X_SCOLON 33
189#define X_QUOTE 34
190#define X_GRAVE 35
191#define X_COMMA 36
192#define X_DOT 37
193#define X_SLASH 38
194#define X_CAPSLOCK 39
195#define X_F1 3a
196#define X_F2 3b
197#define X_F3 3c
198#define X_F4 3d
199#define X_F5 3e
200#define X_F6 3f
201#define X_F7 40
202#define X_F8 41
203#define X_F9 42
204#define X_F10 43
205#define X_F11 44
206#define X_F12 45
207#define X_PSCREEN 46
208#define X_SCROLLLOCK 47
209#define X_PAUSE 48
210#define X_INSERT 49
211#define X_HOME 4a
212#define X_PGUP 4b
213#define X_DELETE 4c
214#define X_END 4d
215#define X_PGDOWN 4e
216#define X_RIGHT 4f
217#define X_LEFT 50
218#define X_DOWN 51
219#define X_UP 52
220#define X_NUMLOCK 53
221#define X_KP_SLASH 54
222#define X_KP_ASTERISK 55
223#define X_KP_MINUS 56
224#define X_KP_PLUS 57
225#define X_KP_ENTER 58
226#define X_KP_1 59
227#define X_KP_2 5a
228#define X_KP_3 5b
229#define X_KP_4 5c
230#define X_KP_5 5d
231#define X_KP_6 5e
232#define X_KP_7 5f
233#define X_KP_8 60
234#define X_KP_9 61
235#define X_KP_0 62
236#define X_KP_DOT 63
237#define X_NONUS_BSLASH 64
238#define X_APPLICATION 65
239#define X_POWER 66
240#define X_KP_EQUAL 67
241#define X_F13 68
242#define X_F14 69
243#define X_F15 6a
244#define X_F16 6b
245#define X_F17 6c
246#define X_F18 6d
247#define X_F19 6e
248#define X_F20 6f
249#define X_F21 70
250#define X_F22 71
251#define X_F23 72
252#define X_F24 73
253#define X_EXECUTE 74
254#define X_HELP 75
255#define X_MENU 76
256#define X_SELECT 77
257#define X_STOP 78
258#define X_AGAIN 79
259#define X_UNDO 7a
260#define X_CUT 7b
261#define X_COPY 7c
262#define X_PASTE 7d
263#define X_FIND 7e
264#define X__MUTE 7f
265#define X__VOLUP 80
266#define X__VOLDOWN 81
267#define X_LOCKING_CAPS 82
268#define X_LOCKING_NUM 83
269#define X_LOCKING_SCROLL 84
270#define X_KP_COMMA 85
271#define X_KP_EQUAL_AS400 86
272#define X_INT1 87
273#define X_INT2 88
274#define X_INT3 89
275#define X_INT4 8a
276#define X_INT5 8b
277#define X_INT6 8c
278#define X_INT7 8d
279#define X_INT8 8e
280#define X_INT9 8f
281#define X_LANG1 90
282#define X_LANG2 91
283#define X_LANG3 92
284#define X_LANG4 93
285#define X_LANG5 94
286#define X_LANG6 95
287#define X_LANG7 96
288#define X_LANG8 97
289#define X_LANG9 98
290#define X_ALT_ERASE 99
291#define X_SYSREQ 9a
292#define X_CANCEL 9b
293#define X_CLEAR 9c
294#define X_PRIOR 9d
295#define X_RETURN 9e
296#define X_SEPARATOR 9f
297#define X_OUT a0
298#define X_OPER a1
299#define X_CLEAR_AGAIN a2
300#define X_CRSEL a3
301#define X_EXSEL a4
169 302
170/* Modifiers */ 303/* Modifiers */
171#define X_LCTRL e0 304#define X_LCTRL e0
172#define X_LSHIFT e1 305#define X_LSHIFT e1
173#define X_LALT e2 306#define X_LALT e2
174#define X_LGUI e3 307#define X_LGUI e3
175#define X_RCTRL e4 308#define X_RCTRL e4
176#define X_RSHIFT e5 309#define X_RSHIFT e5
177#define X_RALT e6 310#define X_RALT e6
178#define X_RGUI e7 311#define X_RGUI e7
179 312
180/* System Control */ 313/* Media and Function keys */
181#define X_SYSTEM_POWER a5 314/* Generic Desktop Page (0x01) */
182#define X_SYSTEM_SLEEP a6 315#define X_SYSTEM_POWER a5
183#define X_SYSTEM_WAKE a7 316#define X_SYSTEM_SLEEP a6
184 317#define X_SYSTEM_WAKE a7
185/* Media Control */ 318
186#define X_AUDIO_MUTE a8 319/* Consumer Page (0x0C) */
187#define X_AUDIO_VOL_UP a9 320#define X_AUDIO_MUTE a8
188#define X_AUDIO_VOL_DOWN aa 321#define X_AUDIO_VOL_UP a9
189#define X_MEDIA_NEXT_TRACK ab 322#define X_AUDIO_VOL_DOWN aa
190#define X_MEDIA_PREV_TRACK ac 323#define X_MEDIA_NEXT_TRACK ab
191#define X_MEDIA_STOP ad 324#define X_MEDIA_PREV_TRACK ac
192#define X_MEDIA_PLAY_PAUSE ae 325#define X_MEDIA_STOP ad
193#define X_MEDIA_SELECT af 326#define X_MEDIA_PLAY_PAUSE ae
194#define X_MEDIA_EJECT b0 327#define X_MEDIA_SELECT af
195#define X_MAIL b1 328#define X_MEDIA_EJECT b0
196#define X_CALCULATOR b2 329#define X_MAIL b1
197#define X_MY_COMPUTER b3 330#define X_CALCULATOR b2
198#define X_WWW_SEARCH b4 331#define X_MY_COMPUTER b3
199#define X_WWW_HOME b5 332#define X_WWW_SEARCH b4
200#define X_WWW_BACK b6 333#define X_WWW_HOME b5
201#define X_WWW_FORWARD b7 334#define X_WWW_BACK b6
202#define X_WWW_STOP b8 335#define X_WWW_FORWARD b7
203#define X_WWW_REFRESH b9 336#define X_WWW_STOP b8
204#define X_WWW_FAVORITES ba 337#define X_WWW_REFRESH b9
338#define X_WWW_FAVORITES ba
205#define X_MEDIA_FAST_FORWARD bb 339#define X_MEDIA_FAST_FORWARD bb
206#define X_MEDIA_REWIND bc 340#define X_MEDIA_REWIND bc
207#endif 341#define X_BRIGHTNESS_UP bd
342#define X_BRIGHTNESS_DOWN be
343
344// Send string macros
345#define STRINGIZE(z) #z
346#define ADD_SLASH_X(y) STRINGIZE(\x##y)
347#define SYMBOL_STR(x) ADD_SLASH_X(x)
348
349#define SS_TAP_CODE 1
350#define SS_DOWN_CODE 2
351#define SS_UP_CODE 3
352
353#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode)
354#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode)
355#define SS_UP(keycode) "\3" SYMBOL_STR(keycode)
356
357// `string` arguments must not be parenthesized
358#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL)
359#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT)
360#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
361#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI)
362#define SS_LCMD(string) SS_LGUI(string)
363#define SS_LWIN(string) SS_LGUI(string)
364
365#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL)
366#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT)
367#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
368#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI)
369#define SS_ALGR(string) SS_RALT(string)
370#define SS_RCMD(string) SS_RGUI(string)
371#define SS_RWIN(string) SS_RGUI(string)
372
373// DEPRECATED
374#define SS_LCTRL(string) SS_LCTL(string)
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index 7176d0cc4..ed1ff5acf 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -14,10 +14,6 @@ GNU General Public License for more details.
14You should have received a copy of the GNU General Public License 14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17
18/*
19 * scan matrix
20 */
21#include <stdint.h> 17#include <stdint.h>
22#include <stdbool.h> 18#include <stdbool.h>
23#include "wait.h" 19#include "wait.h"
@@ -33,23 +29,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
33# include "encoder.h" 29# include "encoder.h"
34#endif 30#endif
35 31
36#if (MATRIX_COLS <= 8)
37# define print_matrix_header() print("\nr/c 01234567\n")
38# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
39# define matrix_bitpop(i) bitpop(matrix[i])
40# define ROW_SHIFTER ((uint8_t)1)
41#elif (MATRIX_COLS <= 16)
42# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
43# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
44# define matrix_bitpop(i) bitpop16(matrix[i])
45# define ROW_SHIFTER ((uint16_t)1)
46#elif (MATRIX_COLS <= 32)
47# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
48# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
49# define matrix_bitpop(i) bitpop32(matrix[i])
50# define ROW_SHIFTER ((uint32_t)1)
51#endif
52
53#define ERROR_DISCONNECT_COUNT 5 32#define ERROR_DISCONNECT_COUNT 5
54 33
55#define ROWS_PER_HAND (MATRIX_ROWS / 2) 34#define ROWS_PER_HAND (MATRIX_ROWS / 2)
@@ -62,58 +41,15 @@ static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
62#endif 41#endif
63 42
64/* matrix state(1:on, 0:off) */ 43/* matrix state(1:on, 0:off) */
65static matrix_row_t matrix[MATRIX_ROWS]; 44extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
66static matrix_row_t raw_matrix[ROWS_PER_HAND]; 45extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
67 46
68// row offsets for each hand 47// row offsets for each hand
69uint8_t thisHand, thatHand; 48uint8_t thisHand, thatHand;
70 49
71// user-defined overridable functions 50// user-defined overridable functions
72
73__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
74
75__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
76
77__attribute__((weak)) void matrix_init_user(void) {}
78
79__attribute__((weak)) void matrix_scan_user(void) {}
80
81__attribute__((weak)) void matrix_slave_scan_user(void) {} 51__attribute__((weak)) void matrix_slave_scan_user(void) {}
82 52
83// helper functions
84
85inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
86
87inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
88
89bool matrix_is_modified(void) {
90 if (debounce_active()) return false;
91 return true;
92}
93
94inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
95
96inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
97
98void matrix_print(void) {
99 print_matrix_header();
100
101 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
102 phex(row);
103 print(": ");
104 print_matrix_row(row);
105 print("\n");
106 }
107}
108
109uint8_t matrix_key_count(void) {
110 uint8_t count = 0;
111 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
112 count += matrix_bitpop(i);
113 }
114 return count;
115}
116
117// matrix code 53// matrix code
118 54
119#ifdef DIRECT_PINS 55#ifdef DIRECT_PINS
@@ -136,7 +72,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
136 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 72 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
137 pin_t pin = direct_pins[current_row][col_index]; 73 pin_t pin = direct_pins[current_row][col_index];
138 if (pin != NO_PIN) { 74 if (pin != NO_PIN) {
139 current_matrix[current_row] |= readPin(pin) ? 0 : (ROW_SHIFTER << col_index); 75 current_matrix[current_row] |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
140 } 76 }
141 } 77 }
142 78
@@ -179,7 +115,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
179 // For each col... 115 // For each col...
180 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { 116 for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
181 // Populate the matrix row with the state of the col pin 117 // Populate the matrix row with the state of the col pin
182 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (ROW_SHIFTER << col_index); 118 current_matrix[current_row] |= readPin(col_pins[col_index]) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
183 } 119 }
184 120
185 // Unselect row 121 // Unselect row
@@ -225,10 +161,10 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
225 // Check row pin state 161 // Check row pin state
226 if (readPin(row_pins[row_index])) { 162 if (readPin(row_pins[row_index])) {
227 // Pin HI, clear col bit 163 // Pin HI, clear col bit
228 current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); 164 current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col);
229 } else { 165 } else {
230 // Pin LO, set col bit 166 // Pin LO, set col bit
231 current_matrix[row_index] |= (ROW_SHIFTER << current_col); 167 current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col);
232 } 168 }
233 169
234 // Determine if the matrix changed state 170 // Determine if the matrix changed state
@@ -280,7 +216,8 @@ void matrix_init(void) {
280 216
281 // initialize matrix state: all keys off 217 // initialize matrix state: all keys off
282 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 218 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
283 matrix[i] = 0; 219 raw_matrix[i] = 0;
220 matrix[i] = 0;
284 } 221 }
285 222
286 debounce_init(ROWS_PER_HAND); 223 debounce_init(ROWS_PER_HAND);
@@ -288,29 +225,7 @@ void matrix_init(void) {
288 matrix_init_quantum(); 225 matrix_init_quantum();
289} 226}
290 227
291uint8_t _matrix_scan(void) { 228void matrix_post_scan(void) {
292 bool changed = false;
293
294#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
295 // Set row, read cols
296 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
297 changed |= read_cols_on_row(raw_matrix, current_row);
298 }
299#elif (DIODE_DIRECTION == ROW2COL)
300 // Set col, read rows
301 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
302 changed |= read_rows_on_col(raw_matrix, current_col);
303 }
304#endif
305
306 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
307
308 return (uint8_t)changed;
309}
310
311uint8_t matrix_scan(void) {
312 uint8_t ret = _matrix_scan();
313
314 if (is_keyboard_master()) { 229 if (is_keyboard_master()) {
315 static uint8_t error_count; 230 static uint8_t error_count;
316 231
@@ -335,6 +250,25 @@ uint8_t matrix_scan(void) {
335#endif 250#endif
336 matrix_slave_scan_user(); 251 matrix_slave_scan_user();
337 } 252 }
253}
254
255uint8_t matrix_scan(void) {
256 bool changed = false;
257
258#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
259 // Set row, read cols
260 for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
261 changed |= read_cols_on_row(raw_matrix, current_row);
262 }
263#elif (DIODE_DIRECTION == ROW2COL)
264 // Set col, read rows
265 for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
266 changed |= read_rows_on_col(raw_matrix, current_col);
267 }
268#endif
269
270 debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed);
338 271
339 return ret; 272 matrix_post_scan();
273 return (uint8_t)changed;
340} 274}
diff --git a/quantum/split_common/matrix.h b/quantum/split_common/matrix.h
deleted file mode 100644
index c2bdd3098..000000000
--- a/quantum/split_common/matrix.h
+++ /dev/null
@@ -1,3 +0,0 @@
1#pragma once
2
3#include <common/matrix.h>
diff --git a/quantum/split_common/post_config.h b/quantum/split_common/post_config.h
index 5c0b414fb..4ae1d5273 100644
--- a/quantum/split_common/post_config.h
+++ b/quantum/split_common/post_config.h
@@ -1,4 +1,4 @@
1#if defined(USE_I2C) || defined(EH) 1#if defined(USE_I2C)
2// When using I2C, using rgblight implicitly involves split support. 2// When using I2C, using rgblight implicitly involves split support.
3# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT) 3# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)
4# define RGBLIGHT_SPLIT 4# define RGBLIGHT_SPLIT
diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c
index 5c548de05..076f18664 100644
--- a/quantum/split_common/split_util.c
+++ b/quantum/split_common/split_util.c
@@ -33,9 +33,11 @@ bool waitForUsb(void) {
33 wait_ms(100); 33 wait_ms(100);
34 } 34 }
35 35
36#if defined(__AVR__)
37 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow 36 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
37#if defined(__AVR__)
38 (USBCON &= ~(_BV(USBE) | _BV(OTGPADE))); 38 (USBCON &= ~(_BV(USBE) | _BV(OTGPADE)));
39#else
40 usbStop(&USBD1);
39#endif 41#endif
40 42
41 return false; 43 return false;
@@ -76,7 +78,7 @@ __attribute__((weak)) bool is_keyboard_master(void) {
76} 78}
77 79
78static void keyboard_master_setup(void) { 80static void keyboard_master_setup(void) {
79#if defined(USE_I2C) || defined(EH) 81#if defined(USE_I2C)
80# ifdef SSD1306OLED 82# ifdef SSD1306OLED
81 matrix_master_OLED_init(); 83 matrix_master_OLED_init();
82# endif 84# endif
diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c
index 3c783dc56..ab421adc4 100644
--- a/quantum/split_common/transport.c
+++ b/quantum/split_common/transport.c
@@ -21,7 +21,7 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A;
21# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) 21# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))
22#endif 22#endif
23 23
24#if defined(USE_I2C) || defined(EH) 24#if defined(USE_I2C)
25 25
26# include "i2c_master.h" 26# include "i2c_master.h"
27# include "i2c_slave.h" 27# include "i2c_slave.h"
diff --git a/quantum/stm32/proton_c.mk b/quantum/stm32/proton_c.mk
index ff28a4cb5..b25b55504 100644
--- a/quantum/stm32/proton_c.mk
+++ b/quantum/stm32/proton_c.mk
@@ -5,9 +5,7 @@ AUDIO_ENABLE = yes
5WS2812_DRIVER = bitbang 5WS2812_DRIVER = bitbang
6 6
7# Force task driven PWM until ARM can provide automatic configuration 7# Force task driven PWM until ARM can provide automatic configuration
8ifneq ($(strip $(BACKLIGHT_ENABLE)), no) 8BACKLIGHT_DRIVER = software
9 BACKLIGHT_ENABLE = software
10endif
11 9
12# The rest of these settings shouldn't change 10# The rest of these settings shouldn't change
13 11
diff --git a/quantum/template/base/keymaps/default/keymap.c b/quantum/template/base/keymaps/default/keymap.c
index 3a68f5487..af35ccec1 100644
--- a/quantum/template/base/keymaps/default/keymap.c
+++ b/quantum/template/base/keymaps/default/keymap.c
@@ -52,7 +52,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
52 case QMKURL: 52 case QMKURL:
53 if (record->event.pressed) { 53 if (record->event.pressed) {
54 // when keycode QMKURL is pressed 54 // when keycode QMKURL is pressed
55 SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER)); 55 SEND_STRING("https://qmk.fm/\n");
56 } else { 56 } else {
57 // when keycode QMKURL is released 57 // when keycode QMKURL is released
58 } 58 }
diff --git a/quantum/via.c b/quantum/via.c
new file mode 100644
index 000000000..64b05324a
--- /dev/null
+++ b/quantum/via.c
@@ -0,0 +1,400 @@
1/* Copyright 2019 Jason Williams (Wilba)
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#ifndef RAW_ENABLE
18# error "RAW_ENABLE is not enabled"
19#endif
20
21#ifndef DYNAMIC_KEYMAP_ENABLE
22# error "DYNAMIC_KEYMAP_ENABLE is not enabled"
23#endif
24
25#include "quantum.h"
26
27#include "via.h"
28#include "raw_hid.h"
29#include "dynamic_keymap.h"
30#include "tmk_core/common/eeprom.h"
31#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
32
33// Can be called in an overriding via_init_kb() to test if keyboard level code usage of
34// EEPROM is invalid and use/save defaults.
35bool via_eeprom_is_valid(void)
36{
37 char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
38 uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
39 uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
40 uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
41
42 return (eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0 ) == magic0 &&
43 eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1 ) == magic1 &&
44 eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2 ) == magic2 );
45}
46
47// Sets VIA/keyboard level usage of EEPROM to valid/invalid
48// Keyboard level code (eg. via_init_kb()) should not call this
49void via_eeprom_set_valid(bool valid)
50{
51 char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
52 uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
53 uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
54 uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
55
56 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0, valid ? magic0 : 0xFF);
57 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1, valid ? magic1 : 0xFF);
58 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2, valid ? magic2 : 0xFF);
59}
60
61// Flag QMK and VIA/keyboard level EEPROM as invalid.
62// Used in bootmagic_lite() and VIA command handler.
63// Keyboard level code should not need to call this.
64void via_eeprom_reset(void)
65{
66 // Set the VIA specific EEPROM state as invalid.
67 via_eeprom_set_valid(false);
68 // Set the TMK/QMK EEPROM state as invalid.
69 eeconfig_disable();
70}
71
72// Override bootmagic_lite() so it can flag EEPROM as invalid
73// as well as jump to bootloader, thus performing a "factory reset"
74// of dynamic keymaps and optionally backlight/other settings.
75void bootmagic_lite(void)
76{
77 // The lite version of TMK's bootmagic based on Wilba.
78 // 100% less potential for accidentally making the
79 // keyboard do stupid things.
80
81 // We need multiple scans because debouncing can't be turned off.
82 matrix_scan();
83#if defined(DEBOUNCE) && DEBOUNCE > 0
84 wait_ms(DEBOUNCE * 2);
85#else
86 wait_ms(30);
87#endif
88 matrix_scan();
89
90 // If the Esc and space bar are held down on power up,
91 // reset the EEPROM valid state and jump to bootloader.
92 // Assumes Esc is at [0,0].
93 // This isn't very generalized, but we need something that doesn't
94 // rely on user's keymaps in firmware or EEPROM.
95 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
96 // This is the only difference from the default implementation.
97 via_eeprom_reset();
98 // Jump to bootloader.
99 bootloader_jump();
100 }
101}
102
103// Override this at the keyboard code level to check
104// VIA's EEPROM valid state and reset to defaults as needed.
105// Used by keyboards that store their own state in EEPROM,
106// for backlight, rotary encoders, etc.
107// The override should not set via_eeprom_set_valid(true) as
108// the caller also needs to check the valid state.
109__attribute__((weak)) void via_init_kb(void) {
110}
111
112// Called by QMK core to initialize dynamic keymaps etc.
113void via_init(void)
114{
115 // Let keyboard level test EEPROM valid state,
116 // but not set it valid, it is done here.
117 via_init_kb();
118
119 // If the EEPROM has the magic, the data is good.
120 // OK to load from EEPROM.
121 if (via_eeprom_is_valid()) {
122 } else {
123 // This resets the layout options
124 via_set_layout_options(0);
125 // This resets the keymaps in EEPROM to what is in flash.
126 dynamic_keymap_reset();
127 // This resets the macros in EEPROM to nothing.
128 dynamic_keymap_macro_reset();
129 // Save the magic number last, in case saving was interrupted
130 via_eeprom_set_valid(true);
131 }
132}
133
134// This is generalized so the layout options EEPROM usage can be
135// variable, between 1 and 4 bytes.
136uint32_t via_get_layout_options(void)
137{
138 uint32_t value = 0;
139 // Start at the most significant byte
140 void * source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR);
141 for ( uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++ ) {
142 value = value << 8;
143 value |= eeprom_read_byte(source);
144 source++;
145 }
146 return value;
147}
148
149void via_set_layout_options(uint32_t value)
150{
151 // Start at the least significant byte
152 void * target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR+VIA_EEPROM_LAYOUT_OPTIONS_SIZE-1);
153 for ( uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++ ) {
154 eeprom_update_byte(target, value & 0xFF );
155 value = value >> 8;
156 target--;
157 }
158}
159
160// Called by QMK core to process VIA-specific keycodes.
161bool process_record_via(uint16_t keycode, keyrecord_t *record)
162{
163 // Handle macros
164 if (record->event.pressed) {
165 if ( keycode >= MACRO00 && keycode <= MACRO15 )
166 {
167 uint8_t id = keycode - MACRO00;
168 dynamic_keymap_macro_send(id);
169 return false;
170 }
171 }
172
173 // TODO: ideally this would be generalized and refactored into
174 // QMK core as advanced keycodes, until then, the simple case
175 // can be available here to keyboards using VIA
176 switch(keycode) {
177 case FN_MO13:
178 if (record->event.pressed) {
179 layer_on(1);
180 update_tri_layer(1, 2, 3);
181 } else {
182 layer_off(1);
183 update_tri_layer(1, 2, 3);
184 }
185 return false;
186 break;
187 case FN_MO23:
188 if (record->event.pressed) {
189 layer_on(2);
190 update_tri_layer(1, 2, 3);
191 } else {
192 layer_off(2);
193 update_tri_layer(1, 2, 3);
194 }
195 return false;
196 break;
197 }
198 return true;
199}
200
201// Keyboard level code can override this to handle custom messages from VIA.
202// See raw_hid_receive() implementation.
203// DO NOT call raw_hid_send() in the overide function.
204__attribute__((weak)) void raw_hid_receive_kb(uint8_t *data, uint8_t length) {
205 uint8_t *command_id = &(data[0]);
206 *command_id = id_unhandled;
207}
208
209// VIA handles received HID messages first, and will route to
210// raw_hid_receive_kb() for command IDs that are not handled here.
211// This gives the keyboard code level the ability to handle the command
212// specifically.
213//
214// raw_hid_send() is called at the end, with the same buffer, which was
215// possibly modified with returned values.
216void raw_hid_receive( uint8_t *data, uint8_t length )
217{
218 uint8_t *command_id = &(data[0]);
219 uint8_t *command_data = &(data[1]);
220 switch ( *command_id )
221 {
222 case id_get_protocol_version:
223 {
224 command_data[0] = VIA_PROTOCOL_VERSION >> 8;
225 command_data[1] = VIA_PROTOCOL_VERSION & 0xFF;
226 break;
227 }
228 case id_get_keyboard_value:
229 {
230 switch ( command_data[0] )
231 {
232 case id_uptime:
233 {
234 uint32_t value = timer_read32();
235 command_data[1] = (value >> 24 ) & 0xFF;
236 command_data[2] = (value >> 16 ) & 0xFF;
237 command_data[3] = (value >> 8 ) & 0xFF;
238 command_data[4] = value & 0xFF;
239 break;
240 }
241 case id_layout_options:
242 {
243 uint32_t value = via_get_layout_options();
244 command_data[1] = (value >> 24 ) & 0xFF;
245 command_data[2] = (value >> 16 ) & 0xFF;
246 command_data[3] = (value >> 8 ) & 0xFF;
247 command_data[4] = value & 0xFF;
248 break;
249 }
250 case id_switch_matrix_state:
251 {
252#if ( (MATRIX_COLS/8+1)*MATRIX_ROWS <= 28 )
253 uint8_t i = 1;
254 for ( uint8_t row=0; row<MATRIX_ROWS; row++ ) {
255 matrix_row_t value = matrix_get_row(row);
256#if (MATRIX_COLS > 24)
257 command_data[i++] = (value >> 24 ) & 0xFF;
258#endif
259#if (MATRIX_COLS > 16)
260 command_data[i++] = (value >> 16 ) & 0xFF;
261#endif
262#if (MATRIX_COLS > 8)
263 command_data[i++] = (value >> 8 ) & 0xFF;
264#endif
265 command_data[i++] = value & 0xFF;
266 }
267#endif
268 break;
269 }
270 default:
271 {
272 raw_hid_receive_kb(data,length);
273 break;
274 }
275 }
276 break;
277 }
278 case id_set_keyboard_value:
279 {
280 switch ( command_data[0] )
281 {
282 case id_layout_options:
283 {
284 uint32_t value = ( (uint32_t)command_data[1] << 24 ) |
285 ( (uint32_t)command_data[2] << 16 ) |
286 ( (uint32_t)command_data[3] << 8 ) |
287 (uint32_t)command_data[4];
288 via_set_layout_options(value);
289 break;
290 }
291 default:
292 {
293 raw_hid_receive_kb(data,length);
294 break;
295 }
296 }
297 break;
298 }
299 case id_dynamic_keymap_get_keycode:
300 {
301 uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
302 command_data[3] = keycode >> 8;
303 command_data[4] = keycode & 0xFF;
304 break;
305 }
306 case id_dynamic_keymap_set_keycode:
307 {
308 dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
309 break;
310 }
311 case id_dynamic_keymap_reset:
312 {
313 dynamic_keymap_reset();
314 break;
315 }
316 case id_backlight_config_set_value:
317 case id_backlight_config_get_value:
318 case id_backlight_config_save:
319 {
320 raw_hid_receive_kb(data, length);
321 break;
322 }
323 case id_dynamic_keymap_macro_get_count:
324 {
325 command_data[0] = dynamic_keymap_macro_get_count();
326 break;
327 }
328 case id_dynamic_keymap_macro_get_buffer_size:
329 {
330 uint16_t size = dynamic_keymap_macro_get_buffer_size();
331 command_data[0] = size >> 8;
332 command_data[1] = size & 0xFF;
333 break;
334 }
335 case id_dynamic_keymap_macro_get_buffer:
336 {
337 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
338 uint16_t size = command_data[2]; // size <= 28
339 dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
340 break;
341 }
342 case id_dynamic_keymap_macro_set_buffer:
343 {
344 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
345 uint16_t size = command_data[2]; // size <= 28
346 dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
347 break;
348 }
349 case id_dynamic_keymap_macro_reset:
350 {
351 dynamic_keymap_macro_reset();
352 break;
353 }
354 case id_dynamic_keymap_get_layer_count:
355 {
356 command_data[0] = dynamic_keymap_get_layer_count();
357 break;
358 }
359 case id_dynamic_keymap_get_buffer:
360 {
361 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
362 uint16_t size = command_data[2]; // size <= 28
363 dynamic_keymap_get_buffer( offset, size, &command_data[3] );
364 break;
365 }
366 case id_dynamic_keymap_set_buffer:
367 {
368 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
369 uint16_t size = command_data[2]; // size <= 28
370 dynamic_keymap_set_buffer( offset, size, &command_data[3] );
371 break;
372 }
373 case id_eeprom_reset:
374 {
375 via_eeprom_reset();
376 break;
377 }
378 case id_bootloader_jump:
379 {
380 // Need to send data back before the jump
381 // Informs host that the command is handled
382 raw_hid_send( data, length );
383 // Give host time to read it
384 wait_ms(100);
385 bootloader_jump();
386 break;
387 }
388 default:
389 {
390 // The command ID is not known
391 // Return the unhandled state
392 *command_id = id_unhandled;
393 break;
394 }
395 }
396
397 // Return the same buffer, optionally with values changed
398 // (i.e. returning state to the host, or the unhandled state).
399 raw_hid_send( data, length );
400}
diff --git a/quantum/via.h b/quantum/via.h
new file mode 100644
index 000000000..f9a8017b2
--- /dev/null
+++ b/quantum/via.h
@@ -0,0 +1,151 @@
1/* Copyright 2019 Jason Williams (Wilba)
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#pragma once
18
19#include <tmk_core/common/eeconfig.h> // for EECONFIG_SIZE
20
21// Keyboard level code can change where VIA stores the magic.
22// The magic is the build date YYMMDD encoded as BCD in 3 bytes,
23// thus installing firmware built on a different date to the one
24// already installed can be detected and the EEPROM data is reset.
25// The only reason this is important is in case EEPROM usage changes
26// and the EEPROM was not explicitly reset by bootmagic lite.
27#ifndef VIA_EEPROM_MAGIC_ADDR
28# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE)
29#endif
30
31#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR+3)
32
33// Changing the layout options size after release will invalidate EEPROM,
34// but this is something that should be set correctly on initial implementation.
35// 1 byte is enough for most uses (i.e. 8 binary states, or 6 binary + 1 ternary/quaternary )
36#ifndef VIA_EEPROM_LAYOUT_OPTIONS_SIZE
37# define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 1
38#endif
39
40// The end of the EEPROM memory used by VIA
41// By default, dynamic keymaps will start at this if there is no
42// custom config
43#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR+VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
44
45#ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE
46# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
47#endif
48
49// This is changed only when the command IDs change,
50// so VIA Configurator can detect compatible firmware.
51#define VIA_PROTOCOL_VERSION 0x0009
52
53enum via_command_id
54{
55 id_get_protocol_version = 0x01, // always 0x01
56 id_get_keyboard_value,
57 id_set_keyboard_value,
58 id_dynamic_keymap_get_keycode,
59 id_dynamic_keymap_set_keycode,
60 id_dynamic_keymap_reset,
61 id_backlight_config_set_value,
62 id_backlight_config_get_value,
63 id_backlight_config_save,
64 id_eeprom_reset,
65 id_bootloader_jump,
66 id_dynamic_keymap_macro_get_count,
67 id_dynamic_keymap_macro_get_buffer_size,
68 id_dynamic_keymap_macro_get_buffer,
69 id_dynamic_keymap_macro_set_buffer,
70 id_dynamic_keymap_macro_reset,
71 id_dynamic_keymap_get_layer_count,
72 id_dynamic_keymap_get_buffer,
73 id_dynamic_keymap_set_buffer,
74 id_unhandled = 0xFF,
75};
76
77enum via_keyboard_value_id
78{
79 id_uptime = 0x01,
80 id_layout_options,
81 id_switch_matrix_state
82};
83
84// Can't use SAFE_RANGE here, it might change if someone adds
85// new values to enum quantum_keycodes.
86// Need to keep checking 0x5F10 is still in the safe range.
87// TODO: merge this into quantum_keycodes
88// Backlight keycodes are in range 0x5F00-0x5F0F
89enum via_keycodes {
90 FN_MO13 = 0x5F10,
91 FN_MO23,
92 MACRO00,
93 MACRO01,
94 MACRO02,
95 MACRO03,
96 MACRO04,
97 MACRO05,
98 MACRO06,
99 MACRO07,
100 MACRO08,
101 MACRO09,
102 MACRO10,
103 MACRO11,
104 MACRO12,
105 MACRO13,
106 MACRO14,
107 MACRO15,
108};
109
110enum user_keycodes {
111 USER00 = 0x5F80,
112 USER01,
113 USER02,
114 USER03,
115 USER04,
116 USER05,
117 USER06,
118 USER07,
119 USER08,
120 USER09,
121 USER10,
122 USER11,
123 USER12,
124 USER13,
125 USER14,
126 USER15,
127};
128
129// Can be called in an overriding via_init_kb() to test if keyboard level code usage of
130// EEPROM is invalid and use/save defaults.
131bool via_eeprom_is_valid(void);
132
133// Sets VIA/keyboard level usage of EEPROM to valid/invalid
134// Keyboard level code (eg. via_init_kb()) should not call this
135void via_eeprom_set_valid(bool valid);
136
137// Flag QMK and VIA/keyboard level EEPROM as invalid.
138// Used in bootmagic_lite() and VIA command handler.
139// Keyboard level code should not need to call this.
140void via_eeprom_reset(void);
141
142// Called by QMK core to initialize dynamic keymaps etc.
143void via_init(void);
144
145// Used by VIA to store and retrieve the layout options.
146uint32_t via_get_layout_options(void);
147void via_set_layout_options(uint32_t value);
148
149// Called by QMK core to process VIA-specific keycodes.
150bool process_record_via(uint16_t keycode, keyrecord_t *record);
151