diff options
Diffstat (limited to 'quantum')
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 | ||
| 22 | backlight_config_t backlight_config; | 22 | backlight_config_t backlight_config; |
| 23 | 23 | ||
| 24 | // TODO: migrate to backlight_config_t | ||
| 25 | static 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 | */ |
| 192 | bool is_backlight_breathing(void) { return backlight_config.breathing; } | 195 | bool 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 | ||
| 43 | void backlight_init(void); | 43 | void backlight_init(void); |
| 44 | void backlight_increase(void); | ||
| 45 | void backlight_decrease(void); | ||
| 46 | void backlight_toggle(void); | 44 | void backlight_toggle(void); |
| 47 | void backlight_enable(void); | 45 | void backlight_enable(void); |
| 48 | void backlight_disable(void); | 46 | void backlight_disable(void); |
| 49 | bool is_backlight_enabled(void); | 47 | bool is_backlight_enabled(void); |
| 50 | void backlight_step(void); | 48 | void backlight_step(void); |
| 51 | void backlight_set(uint8_t level); | 49 | void backlight_increase(void); |
| 50 | void backlight_decrease(void); | ||
| 52 | void backlight_level(uint8_t level); | 51 | void backlight_level(uint8_t level); |
| 53 | uint8_t get_backlight_level(void); | 52 | uint8_t get_backlight_level(void); |
| 54 | 53 | ||
| 54 | // implementation specific | ||
| 55 | void backlight_init_ports(void); | ||
| 56 | void backlight_set(uint8_t level); | ||
| 57 | void backlight_task(void); | ||
| 58 | |||
| 55 | #ifdef BACKLIGHT_BREATHING | 59 | #ifdef BACKLIGHT_BREATHING |
| 60 | |||
| 56 | void backlight_toggle_breathing(void); | 61 | void backlight_toggle_breathing(void); |
| 57 | void backlight_enable_breathing(void); | 62 | void backlight_enable_breathing(void); |
| 58 | void backlight_disable_breathing(void); | 63 | void backlight_disable_breathing(void); |
| 59 | bool is_backlight_breathing(void); | 64 | bool is_backlight_breathing(void); |
| 65 | |||
| 66 | void breathing_period_set(uint8_t value); | ||
| 67 | uint8_t get_breathing_period(void); | ||
| 68 | void breathing_period_default(void); | ||
| 69 | void breathing_period_inc(void); | ||
| 70 | void breathing_period_dec(void); | ||
| 71 | |||
| 72 | // implementation specific | ||
| 60 | void breathing_enable(void); | 73 | void breathing_enable(void); |
| 61 | void breathing_disable(void); | 74 | void breathing_disable(void); |
| 75 | void breathing_toggle(void); | ||
| 76 | bool is_breathing(void); | ||
| 77 | void breathing_pulse(void); | ||
| 78 | void 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 | ||
| 113 | static uint8_t breathing_period = BREATHING_PERIOD; | ||
| 114 | static uint8_t breathing_halt = BREATHING_NO_HALT; | 109 | static uint8_t breathing_halt = BREATHING_NO_HALT; |
| 115 | static uint16_t breathing_counter = 0; | 110 | static uint16_t breathing_counter = 0; |
| 116 | 111 | ||
| @@ -118,7 +113,7 @@ bool is_breathing(void) { return BACKLIGHT_PWM_DRIVER.config == &pwmCFG_breathin | |||
| 118 | 113 | ||
| 119 | static inline void breathing_min(void) { breathing_counter = 0; } | 114 | static inline void breathing_min(void) { breathing_counter = 0; } |
| 120 | 115 | ||
| 121 | static inline void breathing_max(void) { breathing_counter = breathing_period * 256 / 2; } | 116 | static inline void breathing_max(void) { breathing_counter = get_breathing_period() * 256 / 2; } |
| 122 | 117 | ||
| 123 | void breathing_interrupt_enable(void) { | 118 | void 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 | ||
| 173 | void breathing_period_set(uint8_t value) { | ||
| 174 | if (!value) value = 1; | ||
| 175 | breathing_period = value; | ||
| 176 | } | ||
| 177 | |||
| 178 | void breathing_period_default(void) { breathing_period_set(BREATHING_PERIOD); } | ||
| 179 | |||
| 180 | void breathing_period_inc(void) { breathing_period_set(breathing_period + 1); } | ||
| 181 | |||
| 182 | void 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 | ||
| 192 | static void breathing_callback(PWMDriver *pwmp) { | 176 | static 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) { | 209 | void 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 | |||
| 222 | uint8_t backlight_tick = 0; | 220 | uint8_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) { | |||
| 303 | static inline void set_pwm(uint16_t val) { OCRxx = val; } | 301 | static 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) { | 304 | void 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 | ||
| 345 | static uint8_t breathing_period = BREATHING_PERIOD; | ||
| 346 | static uint8_t breathing_halt = BREATHING_NO_HALT; | 343 | static uint8_t breathing_halt = BREATHING_NO_HALT; |
| 347 | static uint16_t breathing_counter = 0; | 344 | static 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 | ||
| 385 | void breathing_enable(void) { | 382 | void breathing_enable(void) { |
| @@ -417,17 +414,6 @@ void breathing_toggle(void) { | |||
| 417 | breathing_enable(); | 414 | breathing_enable(); |
| 418 | } | 415 | } |
| 419 | 416 | ||
| 420 | void breathing_period_set(uint8_t value) { | ||
| 421 | if (!value) value = 1; | ||
| 422 | breathing_period = value; | ||
| 423 | } | ||
| 424 | |||
| 425 | void breathing_period_default(void) { breathing_period_set(BREATHING_PERIOD); } | ||
| 426 | |||
| 427 | void breathing_period_inc(void) { breathing_period_set(breathing_period + 1); } | ||
| 428 | |||
| 429 | void 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) | |||
| 445 | ISR(TIMERx_OVF_vect) | 431 | ISR(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) { | 449 | void 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 | ||
| 23 | static uint16_t s_duty_pattern = 0; | ||
| 23 | static const pin_t backlight_pins[] = BACKLIGHT_PIN_INIT; | 24 | static 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 | ||
| 48 | void backlight_init_ports(void) { | 49 | void 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 | */ | ||
| 61 | static 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 | |||
| 76 | static uint8_t scale_backlight(uint8_t v) { return v * (backlight_duty_table_size - 1) / BACKLIGHT_LEVELS; } | ||
| 77 | |||
| 53 | void backlight_task(void) { | 78 | void 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 | ||
| 64 | void backlight_set(uint8_t level) { | 89 | void 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 | ||
| 93 | void 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 | ||
| 66 | RGB hsv_to_rgb(HSV hsv); | 66 | RGB hsv_to_rgb(HSV hsv); |
| 67 | 67 | #ifdef RGBW | |
| 68 | void 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 | ||
| 46 | uint8_t dynamic_keymap_get_layer_count(void) { return DYNAMIC_KEYMAP_LAYER_COUNT; } | 55 | uint8_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 | ||
| 38 | static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; | 38 | static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; |
| 39 | 39 | ||
| 40 | static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; | 40 | static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; |
| 41 | static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0}; | 41 | static 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 | ||
| 81 | static void encoder_update(int8_t index, uint8_t state) { | 81 | static 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 | ||
| 94 | void encoder_read(void) { | 98 | void 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) { | |||
| 107 | void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } | 107 | void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); } |
| 108 | 108 | ||
| 109 | void encoder_update_raw(uint8_t* slave_state) { | 109 | void 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 | ||
| 45 | extern const matrix_row_t matrix_mask[]; | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #ifdef DIRECT_PINS | 25 | #ifdef DIRECT_PINS |
| 49 | static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; | 26 | static 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) */ |
| 56 | static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values | 33 | extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values |
| 57 | static matrix_row_t matrix[MATRIX_ROWS]; // debounced values | 34 | extern 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 | |||
| 71 | inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } | ||
| 72 | |||
| 73 | inline uint8_t matrix_cols(void) { return MATRIX_COLS; } | ||
| 74 | |||
| 75 | // Deprecated. | ||
| 76 | bool matrix_is_modified(void) { | ||
| 77 | if (debounce_active()) return false; | ||
| 78 | return true; | ||
| 79 | } | ||
| 80 | |||
| 81 | inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } | ||
| 82 | |||
| 83 | inline 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 | |||
| 93 | void 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 | |||
| 104 | uint8_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) */ | ||
| 7 | matrix_row_t raw_matrix[MATRIX_ROWS]; | ||
| 8 | matrix_row_t matrix[MATRIX_ROWS]; | ||
| 9 | |||
| 10 | #ifdef MATRIX_MASKED | ||
| 11 | extern 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 | |||
| 26 | inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } | ||
| 27 | |||
| 28 | inline uint8_t matrix_cols(void) { return MATRIX_COLS; } | ||
| 29 | |||
| 30 | inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } | ||
| 31 | |||
| 32 | inline 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. | ||
| 43 | bool 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 | |||
| 62 | void 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 | |||
| 73 | uint8_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 @@ | |||
| 1 | ifneq ($(findstring STM32F303, $(MCU)),) | 1 | ifneq ($(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 | ||
| 32 | endif | ||
| 33 | |||
| 34 | ifneq ($(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 |
| 65 | endif | ||
| 66 | |||
| 67 | ifneq ($(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 | ||
| 98 | endif | ||
| 99 | |||
| 100 | ifneq ($(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 | ||
| 37 | endif | 131 | endif |
| 38 | 132 | ||
| 39 | ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb1286)) | 133 | ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb1286)) |
| @@ -75,6 +169,9 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a | |||
| 75 | endif | 169 | endif |
| 76 | 170 | ||
| 77 | ifneq (,$(filter $(MCU),atmega32a)) | 171 | ifneq (,$(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 | ||
| 93 | endif | 187 | endif |
| 94 | 188 | ||
| 95 | ifneq (,$(filter $(MCU),atmega328p)) | 189 | ifneq (,$(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 | ||
| 31 | float ag_norm_song[][2] = AG_NORM_SONG; | ||
| 32 | float ag_swap_song[][2] = AG_SWAP_SONG; | ||
| 33 | float cg_norm_song[][2] = CG_NORM_SONG; | ||
| 34 | float cg_swap_song[][2] = CG_SWAP_SONG; | ||
| 35 | #endif | ||
| 36 | |||
| 37 | /** | ||
| 38 | * MAGIC actions (BOOTMAGIC without the boot) | ||
| 39 | */ | ||
| 40 | bool 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 | |||
| 20 | bool 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 | |||
| 19 | typedef 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 | */ | ||
| 26 | static 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 | */ | ||
| 41 | static 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 | */ | ||
| 52 | bool 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 | |||
| 20 | bool 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) { | |||
| 73 | static void send_steno_state(uint8_t size, bool send_empty) { | 73 | static 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 | |||
| 25 | typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t; | 21 | typedef enum { STENO_MODE_BOLT, STENO_MODE_GEMINI } steno_mode_t; |
| 26 | 22 | ||
| 27 | bool process_steno(uint16_t keycode, keyrecord_t *record); | 23 | bool 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 | ||
| 72 | float goodbye_song[][2] = GOODBYE_SONG; | 56 | float goodbye_song[][2] = GOODBYE_SONG; |
| 73 | float ag_norm_song[][2] = AG_NORM_SONG; | ||
| 74 | float ag_swap_song[][2] = AG_SWAP_SONG; | ||
| 75 | float cg_norm_song[][2] = CG_NORM_SONG; | ||
| 76 | float cg_swap_song[][2] = CG_SWAP_SONG; | ||
| 77 | # ifdef DEFAULT_LAYER_SONGS | 57 | # ifdef DEFAULT_LAYER_SONGS |
| 78 | float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; | 58 | float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; |
| 79 | # endif | 59 | # endif |
| 60 | # ifdef SENDSTRING_BELL | ||
| 61 | float bell_song[][2] = SONG(TERMINAL_SOUND); | ||
| 62 | # endif | ||
| 80 | #endif | 63 | #endif |
| 81 | 64 | ||
| 82 | static void do_code16(uint16_t code, void (*f)(uint8_t)) { | 65 | static 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 | */ | ||
| 170 | static 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. */ |
| 173 | uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); } | 151 | uint16_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 | ||
| 831 | void send_char(char ascii_code) { | 478 | void 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__) |
| 158 | typedef uint8_t pin_t; | 175 | typedef 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 | ||
| 210 | extern const bool ascii_to_shift_lut[128]; | 205 | extern const bool ascii_to_shift_lut[128]; |
| 211 | extern const bool ascii_to_altgr_lut[128]; | 206 | extern const bool ascii_to_altgr_lut[128]; |
| @@ -256,30 +251,6 @@ void register_code16(uint16_t code); | |||
| 256 | void unregister_code16(uint16_t code); | 251 | void unregister_code16(uint16_t code); |
| 257 | void tap_code16(uint16_t code); | 252 | void tap_code16(uint16_t code); |
| 258 | 253 | ||
| 259 | #ifdef BACKLIGHT_ENABLE | ||
| 260 | void backlight_init_ports(void); | ||
| 261 | void backlight_task(void); | ||
| 262 | void backlight_task_internal(void); | ||
| 263 | void backlight_on(pin_t backlight_pin); | ||
| 264 | void backlight_off(pin_t backlight_pin); | ||
| 265 | |||
| 266 | # ifdef BACKLIGHT_BREATHING | ||
| 267 | void breathing_task(void); | ||
| 268 | void breathing_enable(void); | ||
| 269 | void breathing_pulse(void); | ||
| 270 | void breathing_disable(void); | ||
| 271 | void breathing_self_disable(void); | ||
| 272 | void breathing_toggle(void); | ||
| 273 | bool is_breathing(void); | ||
| 274 | |||
| 275 | void breathing_intensity_default(void); | ||
| 276 | void breathing_period_default(void); | ||
| 277 | void breathing_period_set(uint8_t value); | ||
| 278 | void breathing_period_inc(void); | ||
| 279 | void breathing_period_dec(void); | ||
| 280 | # endif | ||
| 281 | #endif | ||
| 282 | |||
| 283 | void send_dword(uint32_t number); | 254 | void send_dword(uint32_t number); |
| 284 | void send_word(uint16_t number); | 255 | void send_word(uint16_t number); |
| 285 | void send_byte(uint8_t number); | 256 | void 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 | |||
| 98 | bool g_suspend_state = false; | 115 | bool g_suspend_state = false; |
| 99 | 116 | ||
| 100 | rgb_config_t rgb_matrix_config; | 117 | rgb_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 | ||
| 420 | void rgb_matrix_set_suspend_state(bool state) { g_suspend_state = state; } | 437 | void 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 | ||
| 422 | void rgb_matrix_toggle(void) { | 444 | void 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); | |||
| 128 | void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); | 128 | void 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 | ||
| 153 | typedef struct { | 153 | typedef 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 | ||
| 2 | RGB_MATRIX_EFFECT(GRADIENT_LEFT_RIGHT) | ||
| 3 | # ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS | ||
| 4 | |||
| 5 | bool 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. | |||
| 14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ | 16 | */ |
| 17 | |||
| 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) */ |
| 65 | static matrix_row_t matrix[MATRIX_ROWS]; | 44 | extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values |
| 66 | static matrix_row_t raw_matrix[ROWS_PER_HAND]; | 45 | extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values |
| 67 | 46 | ||
| 68 | // row offsets for each hand | 47 | // row offsets for each hand |
| 69 | uint8_t thisHand, thatHand; | 48 | uint8_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 | |||
| 85 | inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } | ||
| 86 | |||
| 87 | inline uint8_t matrix_cols(void) { return MATRIX_COLS; } | ||
| 88 | |||
| 89 | bool matrix_is_modified(void) { | ||
| 90 | if (debounce_active()) return false; | ||
| 91 | return true; | ||
| 92 | } | ||
| 93 | |||
| 94 | inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); } | ||
| 95 | |||
| 96 | inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } | ||
| 97 | |||
| 98 | void 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 | |||
| 109 | uint8_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 | ||
| 291 | uint8_t _matrix_scan(void) { | 228 | void 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 | |||
| 311 | uint8_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 | |||
| 255 | uint8_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 | ||
| 78 | static void keyboard_master_setup(void) { | 80 | static 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 | |||
| 5 | WS2812_DRIVER = bitbang | 5 | WS2812_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 |
| 8 | ifneq ($(strip $(BACKLIGHT_ENABLE)), no) | 8 | BACKLIGHT_DRIVER = software |
| 9 | BACKLIGHT_ENABLE = software | ||
| 10 | endif | ||
| 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. | ||
| 35 | bool 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 | ||
| 49 | void 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. | ||
| 64 | void 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. | ||
| 75 | void 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. | ||
| 113 | void 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. | ||
| 136 | uint32_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 | |||
| 149 | void 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. | ||
| 161 | bool 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. | ||
| 216 | void 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 | |||
| 53 | enum 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 | |||
| 77 | enum 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 | ||
| 89 | enum 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 | |||
| 110 | enum 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. | ||
| 131 | bool 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 | ||
| 135 | void 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. | ||
| 140 | void via_eeprom_reset(void); | ||
| 141 | |||
| 142 | // Called by QMK core to initialize dynamic keymaps etc. | ||
| 143 | void via_init(void); | ||
| 144 | |||
| 145 | // Used by VIA to store and retrieve the layout options. | ||
| 146 | uint32_t via_get_layout_options(void); | ||
| 147 | void via_set_layout_options(uint32_t value); | ||
| 148 | |||
| 149 | // Called by QMK core to process VIA-specific keycodes. | ||
| 150 | bool process_record_via(uint16_t keycode, keyrecord_t *record); | ||
| 151 | |||
