From eac8fa799909817bfc7cb4043448f85551154c6b Mon Sep 17 00:00:00 2001 From: Ofer Plesser Date: Sat, 10 Dec 2016 00:49:11 +0200 Subject: Implemented basic key combination feature --- quantum/process_keycode/process_combo.c | 66 +++++++++++++++++++++++++++++++++ quantum/process_keycode/process_combo.h | 25 +++++++++++++ quantum/quantum.c | 3 ++ quantum/quantum.h | 4 ++ 4 files changed, 98 insertions(+) create mode 100644 quantum/process_keycode/process_combo.c create mode 100644 quantum/process_keycode/process_combo.h (limited to 'quantum') diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c new file mode 100644 index 0000000000..a6cfed11aa --- /dev/null +++ b/quantum/process_keycode/process_combo.c @@ -0,0 +1,66 @@ +#include "process_combo.h" +#include "print.h" + +// __attribute__ ((weak)) +// combo_t key_combos[] = { + +// }; + +#define SEND_KEY(key) \ +do { \ + register_code16(key); \ + send_keyboard_report(); \ + unregister_code16(key); \ +} while(0) + + +#define ALL_COMBO_KEYS_ARE_DOWN (((1<state) +static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) +{ + uint8_t count = 0; + bool is_combo_key = false; + // bool combo_key_released = false; + + // Count the number of combo keys + for (const uint16_t *key = combo->keys; COMBO_END != pgm_read_word(key); ++key, ++count); + + for (uint8_t i = 0; i < count; ++i) { + uint16_t key = pgm_read_word(&combo->keys[i]); + + if (key == keycode) { + is_combo_key = true; + + if (record->event.pressed) { + combo->state |= (1<state) { + // The combo was sent, no need to send released key + return true; + } + + combo->state &= ~(1<action); + combo->state = 0; + } + + return is_combo_key; +} + + +bool process_combo(uint16_t keycode, keyrecord_t *record) +{ + bool is_combo_key = false; + + for (int i = 0; i < NUM_ELEMS(key_combos); ++i) { + combo_t *combo = &key_combos[i]; + is_combo_key |= process_single_combo(combo, keycode, record); + } + + return !is_combo_key; +} \ No newline at end of file diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h new file mode 100644 index 0000000000..68786c0f19 --- /dev/null +++ b/quantum/process_keycode/process_combo.h @@ -0,0 +1,25 @@ +#ifndef PROCESS_COMBO_H +#define PROCESS_COMBO_H + +#include +#include "progmem.h" +#include "quantum.h" + + +typedef struct +{ + const uint16_t *keys; + uint16_t action; + uint32_t state; +} combo_t; + + +#define COMBO_END 0 +#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a]) + + +extern combo_t key_combos[1]; + +bool process_combo(uint16_t keycode, keyrecord_t *record); + +#endif \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index f653564a67..eabeacff87 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -113,6 +113,9 @@ bool process_record_quantum(keyrecord_t *record) { if (!( process_record_kb(keycode, record) && + #ifdef COMBO_ENABLE + process_combo(keycode, record) && + #endif #ifdef MIDI_ENABLE process_midi(keycode, record) && #endif diff --git a/quantum/quantum.h b/quantum/quantum.h index e6adf974ab..8614c053ab 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -63,6 +63,10 @@ extern uint32_t default_layer_state; #include "process_printer.h" #endif +#ifdef COMBO_ENABLE + #include "process_combo.h" +#endif + #define SEND_STRING(str) send_string(PSTR(str)) void send_string(const char *str); -- cgit v1.2.3 From b6bf4e0dce062a535685c4e772f613252d401ed3 Mon Sep 17 00:00:00 2001 From: Ofer Plesser Date: Sat, 10 Dec 2016 16:11:59 +0200 Subject: Added support for timing out combos if a key as been pressed for longer than COMBO_TERM --- quantum/process_keycode/process_combo.c | 107 +++++++++++++++++++++++--------- quantum/process_keycode/process_combo.h | 20 +++++- quantum/quantum.c | 5 ++ 3 files changed, 101 insertions(+), 31 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index a6cfed11aa..ff7e8aba55 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c @@ -1,11 +1,6 @@ #include "process_combo.h" #include "print.h" -// __attribute__ ((weak)) -// combo_t key_combos[] = { - -// }; - #define SEND_KEY(key) \ do { \ register_code16(key); \ @@ -13,54 +8,110 @@ do { \ unregister_code16(key); \ } while(0) +#define COMBO_TIMER_ELAPSED -1 + +#if COMBO_TERM +#define IS_COMBO_KEY_HELD(combo) (COMBO_TIMER_ELAPSED == combo->timer ? false : true) +#define RESET_COMBO_TIMER_AND_KEY(combo) combo->timer = 0; combo->key = 0 +#else +#define IS_COMBO_KEY_HELD(combo) (true) +#define RESET_COMBO_TIMER_AND_KEY(combo) do {} while (0) +#endif + + +__attribute__ ((weak)) +combo_t key_combos[COMBO_COUNT] = { + +}; + +static inline void reset_combo(combo_t *combo) +{ + combo->state = 0; + RESET_COMBO_TIMER_AND_KEY(combo); +} #define ALL_COMBO_KEYS_ARE_DOWN (((1<state) +#define NO_COMBO_KEYS_ARE_DOWN (0 == combo->state) +#define KEY_STATE_DOWN(key) do{ combo->state |= (1<state &= ~(1<keys; ;++count) { + uint16_t key = pgm_read_word(&keys[count]); + if (keycode == key) index = count; + if (COMBO_END == key) break; + } - // Count the number of combo keys - for (const uint16_t *key = combo->keys; COMBO_END != pgm_read_word(key); ++key, ++count); + /* Return if not a combo key */ + if (-1 == index) return false; - for (uint8_t i = 0; i < count; ++i) { - uint16_t key = pgm_read_word(&combo->keys[i]); + bool is_combo_active = IS_COMBO_KEY_HELD(combo); - if (key == keycode) { - is_combo_key = true; + if (record->event.pressed) { + KEY_STATE_DOWN(index); + +#if COMBO_TERM + if (is_combo_active) { + combo->timer = timer_read(); + combo->key = keycode; + } +#endif - if (record->event.pressed) { - combo->state |= (1<state) { - // The combo was sent, no need to send released key - return true; - } + } else { + if (is_combo_active && combo->state) { /* Combo key was tapped */ + RESET_COMBO_TIMER_AND_KEY(combo); + SEND_KEY(keycode); + } - combo->state &= ~(1<key) { /* Held combo key was released */ + unregister_code16(combo->key); } +#endif + + KEY_STATE_UP(index); } - if (ALL_COMBO_KEYS_ARE_DOWN) { + if (ALL_COMBO_KEYS_ARE_DOWN && is_combo_active) { SEND_KEY(combo->action); - combo->state = 0; + reset_combo(combo); + } + + if(NO_COMBO_KEYS_ARE_DOWN && !is_combo_active) { + reset_combo(combo); } - return is_combo_key; + return is_combo_active; } - bool process_combo(uint16_t keycode, keyrecord_t *record) { bool is_combo_key = false; - for (int i = 0; i < NUM_ELEMS(key_combos); ++i) { + for (int i = 0; i < COMBO_COUNT; ++i) { combo_t *combo = &key_combos[i]; is_combo_key |= process_single_combo(combo, keycode, record); } return !is_combo_key; +} + +void matrix_scan_combo(void) +{ +#if COMBO_TERM + for (int i = 0; i < COMBO_COUNT; ++i) { + combo_t *combo = &key_combos[i]; + if (combo->timer && + combo->timer != COMBO_TIMER_ELAPSED && + timer_elapsed(combo->timer) > COMBO_TERM) { + + combo->timer = COMBO_TIMER_ELAPSED; + unregister_code16(combo->key); + register_code16(combo->key); + } + } +#endif } \ No newline at end of file diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h index 68786c0f19..c475acd332 100644 --- a/quantum/process_keycode/process_combo.h +++ b/quantum/process_keycode/process_combo.h @@ -5,21 +5,35 @@ #include "progmem.h" #include "quantum.h" +#ifndef COMBO_TERM +#define COMBO_TERM TAPPING_TERM +#endif typedef struct { const uint16_t *keys; uint16_t action; uint32_t state; +#if COMBO_TERM + uint16_t timer; + uint16_t key; +#endif } combo_t; +#if COMBO_TERM +#define COMBO(ck, ca) {.keys = &(ck)[0], .action = (ca), .state = 0, .timer = 0, .key = 0} +#else +#define COMBO(ck, ca) {.keys = &(ck)[0], .action = (ca), .state = 0 } +#endif #define COMBO_END 0 -#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a]) +#ifndef COMBO_COUNT +#define COMBO_COUNT 0 +#endif - -extern combo_t key_combos[1]; +extern combo_t key_combos[COMBO_COUNT]; bool process_combo(uint16_t keycode, keyrecord_t *record); +void matrix_scan_combo(void); #endif \ No newline at end of file diff --git a/quantum/quantum.c b/quantum/quantum.c index eabeacff87..7767b63016 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -509,6 +509,11 @@ void matrix_scan_quantum() { #ifdef TAP_DANCE_ENABLE matrix_scan_tap_dance(); #endif + + #ifdef COMBO_ENABLE + matrix_scan_combo(); + #endif + matrix_scan_kb(); } -- cgit v1.2.3 From 6e7cfa83b9424061914793b02757fa4ec75b356b Mon Sep 17 00:00:00 2001 From: Ofer Plesser Date: Fri, 16 Dec 2016 21:50:28 +0200 Subject: Refactored as well as added support for action keys in combos --- quantum/process_keycode/process_combo.c | 123 ++++++++++++++++++-------------- quantum/process_keycode/process_combo.h | 34 +++++---- 2 files changed, 89 insertions(+), 68 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c index ff7e8aba55..e2189ad98b 100644 --- a/quantum/process_keycode/process_combo.c +++ b/quantum/process_keycode/process_combo.c @@ -1,39 +1,39 @@ #include "process_combo.h" #include "print.h" -#define SEND_KEY(key) \ -do { \ - register_code16(key); \ - send_keyboard_report(); \ - unregister_code16(key); \ -} while(0) #define COMBO_TIMER_ELAPSED -1 -#if COMBO_TERM -#define IS_COMBO_KEY_HELD(combo) (COMBO_TIMER_ELAPSED == combo->timer ? false : true) -#define RESET_COMBO_TIMER_AND_KEY(combo) combo->timer = 0; combo->key = 0 -#else -#define IS_COMBO_KEY_HELD(combo) (true) -#define RESET_COMBO_TIMER_AND_KEY(combo) do {} while (0) -#endif - __attribute__ ((weak)) -combo_t key_combos[COMBO_COUNT] = { +combo_t key_combos[] = { }; -static inline void reset_combo(combo_t *combo) +__attribute__ ((weak)) +void process_combo_event(uint8_t combo_index, bool pressed) { + +} + +static uint8_t current_combo_index = 0; + +static inline void send_combo(uint16_t action, bool pressed) { - combo->state = 0; - RESET_COMBO_TIMER_AND_KEY(combo); + if (action) { + if (pressed) { + register_code16(action); + } else { + unregister_code16(action); + } + } else { + process_combo_event(current_combo_index, pressed); + } } -#define ALL_COMBO_KEYS_ARE_DOWN (((1<state) -#define NO_COMBO_KEYS_ARE_DOWN (0 == combo->state) -#define KEY_STATE_DOWN(key) do{ combo->state |= (1<state &= ~(1<state) +#define NO_COMBO_KEYS_ARE_DOWN (0 == combo->state) +#define KEY_STATE_DOWN(key) do{ combo->state |= (1<state &= ~(1<timer ? false : true; if (record->event.pressed) { KEY_STATE_DOWN(index); - -#if COMBO_TERM + if (is_combo_active) { - combo->timer = timer_read(); - combo->key = keycode; - } + if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was pressed */ + send_combo(combo->keycode, true); + combo->timer = COMBO_TIMER_ELAPSED; + } else { /* Combo key was pressed */ + combo->timer = timer_read(); +#ifdef COMBO_ALLOW_ACTION_KEYS + combo->prev_record = *record; +#else + combo->prev_key = keycode; #endif - + } + } } else { - if (is_combo_active && combo->state) { /* Combo key was tapped */ - RESET_COMBO_TIMER_AND_KEY(combo); - SEND_KEY(keycode); + if (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was released */ + send_combo(combo->keycode, false); } -#if COMBO_TERM - if (!is_combo_active && keycode == combo->key) { /* Held combo key was released */ - unregister_code16(combo->key); - } + if (is_combo_active) { /* Combo key was tapped */ +#ifdef COMBO_ALLOW_ACTION_KEYS + record->event.pressed = true; + process_action(record, store_or_get_action(record->event.pressed, record->event.key)); + record->event.pressed = false; + process_action(record, store_or_get_action(record->event.pressed, record->event.key)); +#else + register_code16(keycode); + send_keyboard_report(); + unregister_code16(keycode); #endif + combo->timer = 0; + } - KEY_STATE_UP(index); + KEY_STATE_UP(index); } - if (ALL_COMBO_KEYS_ARE_DOWN && is_combo_active) { - SEND_KEY(combo->action); - reset_combo(combo); - } - - if(NO_COMBO_KEYS_ARE_DOWN && !is_combo_active) { - reset_combo(combo); + if (NO_COMBO_KEYS_ARE_DOWN) { + combo->timer = 0; } return is_combo_active; @@ -91,8 +100,8 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) { bool is_combo_key = false; - for (int i = 0; i < COMBO_COUNT; ++i) { - combo_t *combo = &key_combos[i]; + for (current_combo_index = 0; current_combo_index < COMBO_COUNT; ++current_combo_index) { + combo_t *combo = &key_combos[current_combo_index]; is_combo_key |= process_single_combo(combo, keycode, record); } @@ -101,17 +110,25 @@ bool process_combo(uint16_t keycode, keyrecord_t *record) void matrix_scan_combo(void) { -#if COMBO_TERM for (int i = 0; i < COMBO_COUNT; ++i) { combo_t *combo = &key_combos[i]; if (combo->timer && combo->timer != COMBO_TIMER_ELAPSED && timer_elapsed(combo->timer) > COMBO_TERM) { - + + /* This disables the combo, meaning key events for this + * combo will be handled by the next processors in the chain + */ combo->timer = COMBO_TIMER_ELAPSED; - unregister_code16(combo->key); - register_code16(combo->key); + +#ifdef COMBO_ALLOW_ACTION_KEYS + process_action(&combo->prev_record, + store_or_get_action(combo->prev_record.event.pressed, + combo->prev_record.event.key)); +#else + unregister_code16(combo->prev_key); + register_code16(combo->prev_key); +#endif } } -#endif -} \ No newline at end of file +} diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h index c475acd332..847f2b7376 100644 --- a/quantum/process_keycode/process_combo.h +++ b/quantum/process_keycode/process_combo.h @@ -5,35 +5,39 @@ #include "progmem.h" #include "quantum.h" -#ifndef COMBO_TERM -#define COMBO_TERM TAPPING_TERM -#endif - typedef struct { const uint16_t *keys; - uint16_t action; + uint16_t keycode; +#ifdef EXTRA_EXTRA_LONG_COMBOS uint32_t state; -#if COMBO_TERM +#elif EXTRA_LONG_COMBOS + uint16_t state; +#else + uint8_t state; +#endif uint16_t timer; - uint16_t key; +#ifdef COMBO_ALLOW_ACTION_KEYS + keyrecord_t prev_record; +#else + uint16_t prev_key; #endif } combo_t; -#if COMBO_TERM -#define COMBO(ck, ca) {.keys = &(ck)[0], .action = (ca), .state = 0, .timer = 0, .key = 0} -#else -#define COMBO(ck, ca) {.keys = &(ck)[0], .action = (ca), .state = 0 } -#endif +#define COMBO(ck, ca) {.keys = &(ck)[0], .keycode = (ca)} +#define COMBO_ACTION(ck) {.keys = &(ck)[0]} + #define COMBO_END 0 #ifndef COMBO_COUNT #define COMBO_COUNT 0 #endif - -extern combo_t key_combos[COMBO_COUNT]; +#ifndef COMBO_TERM +#define COMBO_TERM TAPPING_TERM +#endif bool process_combo(uint16_t keycode, keyrecord_t *record); void matrix_scan_combo(void); +void process_combo_event(uint8_t combo_index, bool pressed); -#endif \ No newline at end of file +#endif -- cgit v1.2.3 From 40abf8bc9ce22cab472f79e3a97c413ac5648986 Mon Sep 17 00:00:00 2001 From: Ofer Plesser Date: Fri, 16 Dec 2016 22:00:29 +0200 Subject: Moved combo processing lower down in process logic --- quantum/quantum.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 7767b63016..e5385bc21c 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -113,9 +113,6 @@ bool process_record_quantum(keyrecord_t *record) { if (!( process_record_kb(keycode, record) && - #ifdef COMBO_ENABLE - process_combo(keycode, record) && - #endif #ifdef MIDI_ENABLE process_midi(keycode, record) && #endif @@ -131,6 +128,9 @@ bool process_record_quantum(keyrecord_t *record) { #ifndef DISABLE_CHORDING process_chording(keycode, record) && #endif + #ifdef COMBO_ENABLE + process_combo(keycode, record) && + #endif #ifdef UNICODE_ENABLE process_unicode(keycode, record) && #endif -- cgit v1.2.3 From 438a5d685bb7b726ff59109ce4229eca6303cd8e Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 20 Dec 2016 19:38:22 -0500 Subject: limit voices by default, add some drums --- quantum/audio/voices.c | 105 +++++++++++++++++++++++++++++++++++++------------ quantum/audio/voices.h | 2 + 2 files changed, 82 insertions(+), 25 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 06ff275ba4..4e30289775 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -33,6 +33,8 @@ float voice_envelope(float frequency) { polyphony_rate = 0; break; + #ifdef AUDIO_VOICES + case something: glissando = false; polyphony_rate = 0; @@ -58,36 +60,87 @@ float voice_envelope(float frequency) { case drums: glissando = false; polyphony_rate = 0; - note_timbre = 0; + // switch (compensated_index) { + // case 0 ... 10: + // note_timbre = 0.5; + // break; + // case 11 ... 20: + // note_timbre = 0.5 * (21 - compensated_index) / 10; + // break; + // default: + // note_timbre = 0; + // break; + // } + // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8); + + if (frequency < 80.0) { + + } else if (frequency < 160.0) { + + // Bass drum: 60 - 100 Hz + frequency = (rand() % (int)(40)) + 60; + switch (envelope_index) { + case 0 ... 10: + note_timbre = 0.5; + break; + case 11 ... 20: + note_timbre = 0.5 * (21 - envelope_index) / 10; + break; + default: + note_timbre = 0; + break; + } + + } else if (frequency < 320.0) { + + + // Snare drum: 1 - 2 KHz + frequency = (rand() % (int)(1000)) + 1000; + switch (envelope_index) { + case 0 ... 5: + note_timbre = 0.5; + break; + case 6 ... 20: + note_timbre = 0.5 * (21 - envelope_index) / 15; + break; + default: + note_timbre = 0; + break; + } + + } else if (frequency < 640.0) { + + // Closed Hi-hat: 3 - 5 KHz + frequency = (rand() % (int)(2000)) + 3000; switch (envelope_index) { - case 0 ... 20: + case 0 ... 15: note_timbre = 0.5; + break; + case 16 ... 20: + note_timbre = 0.5 * (21 - envelope_index) / 5; + break; default: - frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8); + note_timbre = 0; break; } - // if (frequency < 80.0) { - // switch (envelope_index % 4) { - // case 0: - // frequency = 348.0; - // case 1: - // frequency = 53.0; - // case 2: - // frequency = 128.0; - // case 3: - // frequency = 934.0; - // default: - // break; - // } - // } else if (frequency < 160.0) { - - // } else if (frequency < 320.0) { - - // } else if (frequency < 640.0) { - - // } else if (frequency < 1280.0) { - - // } + + } else if (frequency < 1280.0) { + + // Open Hi-hat: 3 - 5 KHz + frequency = (rand() % (int)(2000)) + 3000; + switch (envelope_index) { + case 0 ... 35: + note_timbre = 0.5; + break; + case 36 ... 50: + note_timbre = 0.5 * (51 - envelope_index) / 15; + break; + default: + note_timbre = 0; + break; + } + + } break; case butts_fader: glissando = true; @@ -217,6 +270,8 @@ float voice_envelope(float frequency) { // note_timbre = 0.25; // break; + #endif + default: break; } diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h index 72f139e9cd..52f7e006d6 100644 --- a/quantum/audio/voices.h +++ b/quantum/audio/voices.h @@ -11,6 +11,7 @@ float voice_envelope(float frequency); typedef enum { default_voice, + #ifdef AUDIO_VOICES something, drums, butts_fader, @@ -23,6 +24,7 @@ typedef enum { // duty_fourth_down, // duty_third_down, // duty_fifth_third_down, + #endif number_of_voices // important that this is last } voice_type; -- cgit v1.2.3 From 2fa36e38cf28f07ad4a4d74722486921fa7b8706 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Wed, 21 Dec 2016 00:22:32 -0500 Subject: initial subatomic keymap (text) --- quantum/audio/voices.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c index 4e30289775..8326e91eaa 100644 --- a/quantum/audio/voices.c +++ b/quantum/audio/voices.c @@ -278,5 +278,3 @@ float voice_envelope(float frequency) { return frequency; } - - -- cgit v1.2.3 From cae269b08b642b07ee06dec7120a784a3c3d7aab Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 23 Dec 2016 10:29:19 -0500 Subject: Christmas RGB light mode --- quantum/rgblight.c | 21 +++++++++++++++++++++ quantum/rgblight.h | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 625971e0fe..6e335a4831 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -449,6 +449,9 @@ void rgblight_task(void) { } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { // mode = 21 to 23, knight mode rgblight_effect_knight(rgblight_config.mode - 21); + } else { + // mode = 24, christmas mode + rgblight_effect_christmas(); } } } @@ -594,4 +597,22 @@ void rgblight_effect_knight(uint8_t interval) { } } + +void rgblight_effect_christmas(void) { + static uint16_t current_offset = 0; + static uint16_t last_timer = 0; + uint16_t hue; + uint8_t i; + if (timer_elapsed(last_timer) < 1000) { + return; + } + last_timer = timer_read(); + current_offset = (current_offset + 1) % 2; + for (i = 0; i < RGBLED_NUM; i++) { + hue = 0 + ((RGBLED_NUM * (i + current_offset)) % 2) * 80; + sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); + } + rgblight_set(); +} + #endif diff --git a/quantum/rgblight.h b/quantum/rgblight.h index aa1d026e0e..ceb624692a 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -2,7 +2,7 @@ #define RGBLIGHT_H #ifdef RGBLIGHT_ANIMATIONS - #define RGBLIGHT_MODES 23 + #define RGBLIGHT_MODES 24 #else #define RGBLIGHT_MODES 1 #endif @@ -98,5 +98,6 @@ void rgblight_effect_rainbow_mood(uint8_t interval); void rgblight_effect_rainbow_swirl(uint8_t interval); void rgblight_effect_snake(uint8_t interval); void rgblight_effect_knight(uint8_t interval); +void rgblight_effect_christmas(void); #endif -- cgit v1.2.3 From 01038ab54ca6c2858ea9e856c717a1129ffe4156 Mon Sep 17 00:00:00 2001 From: Ofer Plesser Date: Fri, 23 Dec 2016 21:51:11 +0200 Subject: Added check that makes sure a code is a right modifier before considering it as one --- quantum/keymap.h | 1 + quantum/quantum.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index ae56d16c75..745c552799 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -53,6 +53,7 @@ enum quantum_keycodes { QK_LSFT = 0x0200, QK_LALT = 0x0400, QK_LGUI = 0x0800, + QK_RMODS_MIN = 0x1000, QK_RCTL = 0x1100, QK_RSFT = 0x1200, QK_RALT = 0x1400, diff --git a/quantum/quantum.c b/quantum/quantum.c index f653564a67..63ffe2074e 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -21,6 +21,8 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { if (code & QK_LGUI) f(KC_LGUI); + if (code < QK_RMODS_MIN) return; + if (code & QK_RCTL) f(KC_RCTL); if (code & QK_RSFT) -- cgit v1.2.3 From 273faa4d9cd5a84207548f83ba550c9efee90933 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 23 Dec 2016 20:59:00 -0500 Subject: add different scales for music mode --- quantum/process_keycode/process_music.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c index bae43943e0..ca68bef6c8 100644 --- a/quantum/process_keycode/process_music.c +++ b/quantum/process_keycode/process_music.c @@ -115,7 +115,16 @@ bool process_music(uint16_t keycode, keyrecord_t *record) { return false; } + #ifdef MUSIC_MODE_CHROMATIC + float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(MATRIX_ROWS - record->event.key.row)); + #elif defined(MUSIC_MODE_GUITAR) + float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 7)*5.0/12); + #elif defined(MUSIC_MODE_VIOLIN) + float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 5)*7.0/12); + #else float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + SCALE[record->event.key.col + music_offset])/12.0+(MATRIX_ROWS - record->event.key.row)); + #endif + if (record->event.pressed) { play_note(freq, 0xF); if (music_sequence_recording) { -- cgit v1.2.3 From 748181dccddb8c9fa52a776f4fcd904ddca9aa31 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Wed, 28 Dec 2016 16:29:02 -0500 Subject: Add extern for 'led' global, set 'weak' attribute for rgblight_set() --- quantum/rgblight.c | 1 + quantum/rgblight.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 6e335a4831..0f7a1d8280 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -370,6 +370,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { rgblight_set(); } ++__attribute__ ((weak)) void rgblight_set(void) { if (rgblight_config.enable) { #ifdef RGBW diff --git a/quantum/rgblight.h b/quantum/rgblight.h index ceb624692a..726b8de72e 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -40,6 +40,8 @@ #include "eeconfig.h" #include "light_ws2812.h" +extern LED_TYPE led[RGBLED_NUM]; + extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM; extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM; -- cgit v1.2.3 From d8a608f3ff4cb4d73cd57be500fd9881e230099d Mon Sep 17 00:00:00 2001 From: Wilba6582 Date: Thu, 29 Dec 2016 18:28:48 +1100 Subject: Keycode refactor --- quantum/keymap.h | 314 +-------------------------------------------- quantum/keymap_common.c | 16 ++- quantum/quantum_keycodes.h | 313 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+), 313 deletions(-) create mode 100644 quantum/quantum_keycodes.h (limited to 'quantum') diff --git a/quantum/keymap.h b/quantum/keymap.h index 745c552799..c000d2da8e 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -38,318 +38,16 @@ along with this program. If not, see . #define RESET QK_RESET #endif -/* translates key to keycode */ +#include "quantum_keycodes.h" + +// translates key to keycode uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); +// translates function id to action +uint16_t keymap_function_id_to_action( uint16_t function_id ); + extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; extern const uint16_t fn_actions[]; -enum quantum_keycodes { - // Ranges used in shortucuts - not to be used directly - QK_TMK = 0x0000, - QK_TMK_MAX = 0x00FF, - QK_MODS = 0x0100, - QK_LCTL = 0x0100, - QK_LSFT = 0x0200, - QK_LALT = 0x0400, - QK_LGUI = 0x0800, - QK_RMODS_MIN = 0x1000, - QK_RCTL = 0x1100, - QK_RSFT = 0x1200, - QK_RALT = 0x1400, - QK_RGUI = 0x1800, - QK_MODS_MAX = 0x1FFF, - QK_FUNCTION = 0x2000, - QK_FUNCTION_MAX = 0x2FFF, - QK_MACRO = 0x3000, - QK_MACRO_MAX = 0x3FFF, - QK_LAYER_TAP = 0x4000, - QK_LAYER_TAP_MAX = 0x4FFF, - QK_TO = 0x5000, - QK_TO_MAX = 0x50FF, - QK_MOMENTARY = 0x5100, - QK_MOMENTARY_MAX = 0x51FF, - QK_DEF_LAYER = 0x5200, - QK_DEF_LAYER_MAX = 0x52FF, - QK_TOGGLE_LAYER = 0x5300, - QK_TOGGLE_LAYER_MAX = 0x53FF, - QK_ONE_SHOT_LAYER = 0x5400, - QK_ONE_SHOT_LAYER_MAX = 0x54FF, - QK_ONE_SHOT_MOD = 0x5500, - QK_ONE_SHOT_MOD_MAX = 0x55FF, -#ifndef DISABLE_CHORDING - QK_CHORDING = 0x5600, - QK_CHORDING_MAX = 0x56FF, -#endif - QK_MOD_TAP = 0x6000, - QK_MOD_TAP_MAX = 0x6FFF, - QK_TAP_DANCE = 0x7100, - QK_TAP_DANCE_MAX = 0x71FF, -#ifdef UNICODEMAP_ENABLE - QK_UNICODE_MAP = 0x7800, - QK_UNICODE_MAP_MAX = 0x7FFF, -#endif -#ifdef UNICODE_ENABLE - QK_UNICODE = 0x8000, - QK_UNICODE_MAX = 0xFFFF, -#endif - - // Loose keycodes - to be used directly - - RESET = 0x7000, - DEBUG, - MAGIC_SWAP_CONTROL_CAPSLOCK, - MAGIC_CAPSLOCK_TO_CONTROL, - MAGIC_SWAP_LALT_LGUI, - MAGIC_SWAP_RALT_RGUI, - MAGIC_NO_GUI, - MAGIC_SWAP_GRAVE_ESC, - MAGIC_SWAP_BACKSLASH_BACKSPACE, - MAGIC_HOST_NKRO, - MAGIC_SWAP_ALT_GUI, - MAGIC_UNSWAP_CONTROL_CAPSLOCK, - MAGIC_UNCAPSLOCK_TO_CONTROL, - MAGIC_UNSWAP_LALT_LGUI, - MAGIC_UNSWAP_RALT_RGUI, - MAGIC_UNNO_GUI, - MAGIC_UNSWAP_GRAVE_ESC, - MAGIC_UNSWAP_BACKSLASH_BACKSPACE, - MAGIC_UNHOST_NKRO, - MAGIC_UNSWAP_ALT_GUI, - MAGIC_TOGGLE_NKRO, - - // Leader key -#ifndef DISABLE_LEADER - KC_LEAD, -#endif - - // Audio on/off/toggle - AU_ON, - AU_OFF, - AU_TOG, - - // Music mode on/off/toggle - MU_ON, - MU_OFF, - MU_TOG, - - // Music voice iterate - MUV_IN, - MUV_DE, - - // Midi mode on/off - MIDI_ON, - MIDI_OFF, - - // Backlight functionality - BL_0, - BL_1, - BL_2, - BL_3, - BL_4, - BL_5, - BL_6, - BL_7, - BL_8, - BL_9, - BL_10, - BL_11, - BL_12, - BL_13, - BL_14, - BL_15, - BL_DEC, - BL_INC, - BL_TOGG, - BL_STEP, - - // RGB functionality - RGB_TOG, - RGB_MOD, - RGB_HUI, - RGB_HUD, - RGB_SAI, - RGB_SAD, - RGB_VAI, - RGB_VAD, - - // Left shift, open paren - KC_LSPO, - - // Right shift, close paren - KC_RSPC, - - // Printing - PRINT_ON, - PRINT_OFF, - - // always leave at the end - SAFE_RANGE -}; - -// Ability to use mods in layouts -#define LCTL(kc) (kc | QK_LCTL) -#define LSFT(kc) (kc | QK_LSFT) -#define LALT(kc) (kc | QK_LALT) -#define LGUI(kc) (kc | QK_LGUI) -#define RCTL(kc) (kc | QK_RCTL) -#define RSFT(kc) (kc | QK_RSFT) -#define RALT(kc) (kc | QK_RALT) -#define RGUI(kc) (kc | QK_RGUI) - -#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) -#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) -#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) -#define ALTG(kc) (kc | QK_RCTL | QK_RALT) - -#define MOD_HYPR 0xf -#define MOD_MEH 0x7 - - -// Aliases for shifted symbols -// Each key has a 4-letter code, and some have longer aliases too. -// While the long aliases are descriptive, the 4-letter codes -// make for nicer grid layouts (everything lines up), and are -// the preferred style for Quantum. -#define KC_TILD LSFT(KC_GRV) // ~ -#define KC_TILDE KC_TILD - -#define KC_EXLM LSFT(KC_1) // ! -#define KC_EXCLAIM KC_EXLM - -#define KC_AT LSFT(KC_2) // @ - -#define KC_HASH LSFT(KC_3) // # - -#define KC_DLR LSFT(KC_4) // $ -#define KC_DOLLAR KC_DLR - -#define KC_PERC LSFT(KC_5) // % -#define KC_PERCENT KC_PERC - -#define KC_CIRC LSFT(KC_6) // ^ -#define KC_CIRCUMFLEX KC_CIRC - -#define KC_AMPR LSFT(KC_7) // & -#define KC_AMPERSAND KC_AMPR - -#define KC_ASTR LSFT(KC_8) // * -#define KC_ASTERISK KC_ASTR - -#define KC_LPRN LSFT(KC_9) // ( -#define KC_LEFT_PAREN KC_LPRN - -#define KC_RPRN LSFT(KC_0) // ) -#define KC_RIGHT_PAREN KC_RPRN - -#define KC_UNDS LSFT(KC_MINS) // _ -#define KC_UNDERSCORE KC_UNDS - -#define KC_PLUS LSFT(KC_EQL) // + - -#define KC_LCBR LSFT(KC_LBRC) // { -#define KC_LEFT_CURLY_BRACE KC_LCBR - -#define KC_RCBR LSFT(KC_RBRC) // } -#define KC_RIGHT_CURLY_BRACE KC_RCBR - -#define KC_LABK LSFT(KC_COMM) // < -#define KC_LEFT_ANGLE_BRACKET KC_LABK - -#define KC_RABK LSFT(KC_DOT) // > -#define KC_RIGHT_ANGLE_BRACKET KC_RABK - -#define KC_COLN LSFT(KC_SCLN) // : -#define KC_COLON KC_COLN - -#define KC_PIPE LSFT(KC_BSLS) // | - -#define KC_LT LSFT(KC_COMM) // < - -#define KC_GT LSFT(KC_DOT) // > - -#define KC_QUES LSFT(KC_SLSH) // ? -#define KC_QUESTION KC_QUES - -#define KC_DQT LSFT(KC_QUOT) // " -#define KC_DOUBLE_QUOTE KC_DQT -#define KC_DQUO KC_DQT - -#define KC_DELT KC_DELETE // Del key (four letter code) - -// Alias for function layers than expand past FN31 -#define FUNC(kc) (kc | QK_FUNCTION) - -// Aliases -#define S(kc) LSFT(kc) -#define F(kc) FUNC(kc) - -#define M(kc) (kc | QK_MACRO) - -#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) - -// L-ayer, T-ap - 256 keycode max, 16 layer max -#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) - -#define AG_SWAP MAGIC_SWAP_ALT_GUI -#define AG_NORM MAGIC_UNSWAP_ALT_GUI - -#define BL_ON BL_9 -#define BL_OFF BL_0 - -#define MI_ON MIDI_ON -#define MI_OFF MIDI_OFF - -// GOTO layer - 16 layers max -// when: -// ON_PRESS = 1 -// ON_RELEASE = 2 -// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. -// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own -// keycode modeled after the old version, kept below for this. -/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */ -#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4)) - -// Momentary switch layer - 256 layer max -#define MO(layer) (layer | QK_MOMENTARY) - -// Set default layer - 256 layer max -#define DF(layer) (layer | QK_DEF_LAYER) - -// Toggle to layer - 256 layer max -#define TG(layer) (layer | QK_TOGGLE_LAYER) - -// One-shot layer - 256 layer max -#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) - -// One-shot mod -#define OSM(mod) (mod | QK_ONE_SHOT_MOD) - -// M-od, T-ap - 256 keycode max -#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8)) -#define CTL_T(kc) MT(MOD_LCTL, kc) -#define SFT_T(kc) MT(MOD_LSFT, kc) -#define ALT_T(kc) MT(MOD_LALT, kc) -#define GUI_T(kc) MT(MOD_LGUI, kc) -#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal -#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl -#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui -#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ - -// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap -#define KC_HYPR HYPR(KC_NO) -#define KC_MEH MEH(KC_NO) - -#ifdef UNICODE_ENABLE - // For sending unicode codes. - // You may not send codes over 7FFF -- this supports most of UTF8. - // To have a key that sends out Œ, go UC(0x0152) - #define UNICODE(n) (n | QK_UNICODE) - #define UC(n) UNICODE(n) -#endif - -#ifdef UNICODEMAP_ENABLE - #define X(n) (n | QK_UNICODE_MAP) -#endif #endif diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 833e5a8f8d..eced3d2bba 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -48,12 +48,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) action_t action; uint8_t action_layer, when, mod; - // The arm-none-eabi compiler generates out of bounds warnings when using the fn_actions directly for some reason - const uint16_t* actions = fn_actions; switch (keycode) { case KC_FN0 ... KC_FN31: - action.code = pgm_read_word(&actions[FN_INDEX(keycode)]); + action.code = keymap_function_id_to_action(FN_INDEX(keycode)); break; case KC_A ... KC_EXSEL: case KC_LCTRL ... KC_RGUI: @@ -79,7 +77,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) case QK_FUNCTION ... QK_FUNCTION_MAX: ; // Is a shortcut for function action_layer, pull last 12bits // This means we have 4,096 FN macros at our disposal - action.code = pgm_read_word(&actions[(int)keycode & 0xFFF]); + action.code = keymap_function_id_to_action( (int)keycode & 0xFFF ); break; case QK_MACRO ... QK_MACRO_MAX: action.code = ACTION_MACRO(keycode & 0xFF); @@ -163,9 +161,17 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { } -/* translates key to keycode */ +// translates key to keycode +__attribute__ ((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { // Read entire word (16bits) return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); } + +// translates function id to action +__attribute__ ((weak)) +uint16_t keymap_function_id_to_action( uint16_t function_id ) +{ + return pgm_read_word(&fn_actions[function_id]); +} diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h new file mode 100644 index 0000000000..5cd3c8e780 --- /dev/null +++ b/quantum/quantum_keycodes.h @@ -0,0 +1,313 @@ + +#ifndef QUANTUM_KEYCODES_H +#define QUANTUM_KEYCODES_H + +enum quantum_keycodes { + // Ranges used in shortucuts - not to be used directly + QK_TMK = 0x0000, + QK_TMK_MAX = 0x00FF, + QK_MODS = 0x0100, + QK_LCTL = 0x0100, + QK_LSFT = 0x0200, + QK_LALT = 0x0400, + QK_LGUI = 0x0800, + QK_RMODS_MIN = 0x1000, + QK_RCTL = 0x1100, + QK_RSFT = 0x1200, + QK_RALT = 0x1400, + QK_RGUI = 0x1800, + QK_MODS_MAX = 0x1FFF, + QK_FUNCTION = 0x2000, + QK_FUNCTION_MAX = 0x2FFF, + QK_MACRO = 0x3000, + QK_MACRO_MAX = 0x3FFF, + QK_LAYER_TAP = 0x4000, + QK_LAYER_TAP_MAX = 0x4FFF, + QK_TO = 0x5000, + QK_TO_MAX = 0x50FF, + QK_MOMENTARY = 0x5100, + QK_MOMENTARY_MAX = 0x51FF, + QK_DEF_LAYER = 0x5200, + QK_DEF_LAYER_MAX = 0x52FF, + QK_TOGGLE_LAYER = 0x5300, + QK_TOGGLE_LAYER_MAX = 0x53FF, + QK_ONE_SHOT_LAYER = 0x5400, + QK_ONE_SHOT_LAYER_MAX = 0x54FF, + QK_ONE_SHOT_MOD = 0x5500, + QK_ONE_SHOT_MOD_MAX = 0x55FF, +#ifndef DISABLE_CHORDING + QK_CHORDING = 0x5600, + QK_CHORDING_MAX = 0x56FF, +#endif + QK_MOD_TAP = 0x6000, + QK_MOD_TAP_MAX = 0x6FFF, + QK_TAP_DANCE = 0x7100, + QK_TAP_DANCE_MAX = 0x71FF, +#ifdef UNICODEMAP_ENABLE + QK_UNICODE_MAP = 0x7800, + QK_UNICODE_MAP_MAX = 0x7FFF, +#endif +#ifdef UNICODE_ENABLE + QK_UNICODE = 0x8000, + QK_UNICODE_MAX = 0xFFFF, +#endif + + // Loose keycodes - to be used directly + + RESET = 0x7000, + DEBUG, + MAGIC_SWAP_CONTROL_CAPSLOCK, + MAGIC_CAPSLOCK_TO_CONTROL, + MAGIC_SWAP_LALT_LGUI, + MAGIC_SWAP_RALT_RGUI, + MAGIC_NO_GUI, + MAGIC_SWAP_GRAVE_ESC, + MAGIC_SWAP_BACKSLASH_BACKSPACE, + MAGIC_HOST_NKRO, + MAGIC_SWAP_ALT_GUI, + MAGIC_UNSWAP_CONTROL_CAPSLOCK, + MAGIC_UNCAPSLOCK_TO_CONTROL, + MAGIC_UNSWAP_LALT_LGUI, + MAGIC_UNSWAP_RALT_RGUI, + MAGIC_UNNO_GUI, + MAGIC_UNSWAP_GRAVE_ESC, + MAGIC_UNSWAP_BACKSLASH_BACKSPACE, + MAGIC_UNHOST_NKRO, + MAGIC_UNSWAP_ALT_GUI, + MAGIC_TOGGLE_NKRO, + + // Leader key +#ifndef DISABLE_LEADER + KC_LEAD, +#endif + + // Audio on/off/toggle + AU_ON, + AU_OFF, + AU_TOG, + + // Music mode on/off/toggle + MU_ON, + MU_OFF, + MU_TOG, + + // Music voice iterate + MUV_IN, + MUV_DE, + + // Midi mode on/off + MIDI_ON, + MIDI_OFF, + + // Backlight functionality + BL_0, + BL_1, + BL_2, + BL_3, + BL_4, + BL_5, + BL_6, + BL_7, + BL_8, + BL_9, + BL_10, + BL_11, + BL_12, + BL_13, + BL_14, + BL_15, + BL_DEC, + BL_INC, + BL_TOGG, + BL_STEP, + + // RGB functionality + RGB_TOG, + RGB_MOD, + RGB_HUI, + RGB_HUD, + RGB_SAI, + RGB_SAD, + RGB_VAI, + RGB_VAD, + + // Left shift, open paren + KC_LSPO, + + // Right shift, close paren + KC_RSPC, + + // Printing + PRINT_ON, + PRINT_OFF, + + // always leave at the end + SAFE_RANGE +}; + +// Ability to use mods in layouts +#define LCTL(kc) (kc | QK_LCTL) +#define LSFT(kc) (kc | QK_LSFT) +#define LALT(kc) (kc | QK_LALT) +#define LGUI(kc) (kc | QK_LGUI) +#define RCTL(kc) (kc | QK_RCTL) +#define RSFT(kc) (kc | QK_RSFT) +#define RALT(kc) (kc | QK_RALT) +#define RGUI(kc) (kc | QK_RGUI) + +#define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) +#define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) +#define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) +#define ALTG(kc) (kc | QK_RCTL | QK_RALT) + +#define MOD_HYPR 0xf +#define MOD_MEH 0x7 + + +// Aliases for shifted symbols +// Each key has a 4-letter code, and some have longer aliases too. +// While the long aliases are descriptive, the 4-letter codes +// make for nicer grid layouts (everything lines up), and are +// the preferred style for Quantum. +#define KC_TILD LSFT(KC_GRV) // ~ +#define KC_TILDE KC_TILD + +#define KC_EXLM LSFT(KC_1) // ! +#define KC_EXCLAIM KC_EXLM + +#define KC_AT LSFT(KC_2) // @ + +#define KC_HASH LSFT(KC_3) // # + +#define KC_DLR LSFT(KC_4) // $ +#define KC_DOLLAR KC_DLR + +#define KC_PERC LSFT(KC_5) // % +#define KC_PERCENT KC_PERC + +#define KC_CIRC LSFT(KC_6) // ^ +#define KC_CIRCUMFLEX KC_CIRC + +#define KC_AMPR LSFT(KC_7) // & +#define KC_AMPERSAND KC_AMPR + +#define KC_ASTR LSFT(KC_8) // * +#define KC_ASTERISK KC_ASTR + +#define KC_LPRN LSFT(KC_9) // ( +#define KC_LEFT_PAREN KC_LPRN + +#define KC_RPRN LSFT(KC_0) // ) +#define KC_RIGHT_PAREN KC_RPRN + +#define KC_UNDS LSFT(KC_MINS) // _ +#define KC_UNDERSCORE KC_UNDS + +#define KC_PLUS LSFT(KC_EQL) // + + +#define KC_LCBR LSFT(KC_LBRC) // { +#define KC_LEFT_CURLY_BRACE KC_LCBR + +#define KC_RCBR LSFT(KC_RBRC) // } +#define KC_RIGHT_CURLY_BRACE KC_RCBR + +#define KC_LABK LSFT(KC_COMM) // < +#define KC_LEFT_ANGLE_BRACKET KC_LABK + +#define KC_RABK LSFT(KC_DOT) // > +#define KC_RIGHT_ANGLE_BRACKET KC_RABK + +#define KC_COLN LSFT(KC_SCLN) // : +#define KC_COLON KC_COLN + +#define KC_PIPE LSFT(KC_BSLS) // | + +#define KC_LT LSFT(KC_COMM) // < + +#define KC_GT LSFT(KC_DOT) // > + +#define KC_QUES LSFT(KC_SLSH) // ? +#define KC_QUESTION KC_QUES + +#define KC_DQT LSFT(KC_QUOT) // " +#define KC_DOUBLE_QUOTE KC_DQT +#define KC_DQUO KC_DQT + +#define KC_DELT KC_DELETE // Del key (four letter code) + +// Alias for function layers than expand past FN31 +#define FUNC(kc) (kc | QK_FUNCTION) + +// Aliases +#define S(kc) LSFT(kc) +#define F(kc) FUNC(kc) + +#define M(kc) (kc | QK_MACRO) + +#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) + +// L-ayer, T-ap - 256 keycode max, 16 layer max +#define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) + +#define AG_SWAP MAGIC_SWAP_ALT_GUI +#define AG_NORM MAGIC_UNSWAP_ALT_GUI + +#define BL_ON BL_9 +#define BL_OFF BL_0 + +#define MI_ON MIDI_ON +#define MI_OFF MIDI_OFF + +// GOTO layer - 16 layers max +// when: +// ON_PRESS = 1 +// ON_RELEASE = 2 +// Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. +// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own +// keycode modeled after the old version, kept below for this. +/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */ +#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4)) + +// Momentary switch layer - 256 layer max +#define MO(layer) (layer | QK_MOMENTARY) + +// Set default layer - 256 layer max +#define DF(layer) (layer | QK_DEF_LAYER) + +// Toggle to layer - 256 layer max +#define TG(layer) (layer | QK_TOGGLE_LAYER) + +// One-shot layer - 256 layer max +#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) + +// One-shot mod +#define OSM(mod) (mod | QK_ONE_SHOT_MOD) + +// M-od, T-ap - 256 keycode max +#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8)) +#define CTL_T(kc) MT(MOD_LCTL, kc) +#define SFT_T(kc) MT(MOD_LSFT, kc) +#define ALT_T(kc) MT(MOD_LALT, kc) +#define GUI_T(kc) MT(MOD_LGUI, kc) +#define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal +#define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl +#define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui +#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ + +// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap +#define KC_HYPR HYPR(KC_NO) +#define KC_MEH MEH(KC_NO) + +#ifdef UNICODE_ENABLE + // For sending unicode codes. + // You may not send codes over 7FFF -- this supports most of UTF8. + // To have a key that sends out Œ, go UC(0x0152) + #define UNICODE(n) (n | QK_UNICODE) + #define UC(n) UNICODE(n) +#endif + +#ifdef UNICODEMAP_ENABLE + #define X(n) (n | QK_UNICODE_MAP) +#endif + +#endif // QUANTUM_KEYCODES_H -- cgit v1.2.3 From dd685eceb2045371d38f24d454f1ab08ca7416f4 Mon Sep 17 00:00:00 2001 From: Fred Sundvik Date: Thu, 29 Dec 2016 12:13:30 +0200 Subject: API Sysex fixes Fix memory leaks by using stack instead of malloc Reduce memory usage by having less temporary bufffers Remove warnings by adding includes Decrease code size by 608 bytes (mostly due to not linking malloc) More robust handling of buffer overflows --- quantum/api/api_sysex.c | 60 ++++++++++++++++++++++++++++++++++++------------- quantum/config_common.h | 2 ++ 2 files changed, 46 insertions(+), 16 deletions(-) (limited to 'quantum') diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c index a4a554e764..868f854b92 100644 --- a/quantum/api/api_sysex.c +++ b/quantum/api/api_sysex.c @@ -1,4 +1,6 @@ #include "api_sysex.h" +#include "sysex_tools.h" +#include "print.h" void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { // SEND_STRING("\nTX: "); @@ -6,24 +8,50 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, // send_byte(bytes[i]); // SEND_STRING(" "); // } - uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); - precode[0] = message_type; - precode[1] = data_type; - memcpy(precode + 2, bytes, length); - uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); - uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); - uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); - array[0] = 0xF0; - array[1] = 0x00; - array[2] = 0x00; - array[3] = 0x00; - array[encoded_length + 4] = 0xF7; - memcpy(array + 4, encoded, encoded_length); - midi_send_array(&midi_device, encoded_length + 5, array); + if (length > API_SYSEX_MAX_SIZE) { + xprintf("Sysex msg too big %d %d %d", message_type, data_type, length); + return; + } + + + // The buffer size required is calculated as the following + // API_SYSEX_MAX_SIZE is the maximum length + // In addition to that we have a two byte message header consisting of the message_type and data_type + // This has to be encoded with an additional overhead of one byte for every starting 7 bytes + // We just add one extra byte in case it's not divisible by 7 + // Then we have an unencoded header consisting of 4 bytes + // Plus a one byte terminator + const unsigned message_header = 2; + const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header; + const unsigned encoding_overhead = unencoded_message / 7 + 1; + const unsigned encoded_size = unencoded_message + encoding_overhead; + const unsigned unencoded_header = 4; + const unsigned terminator = 1; + const unsigned buffer_size = encoded_size + unencoded_header + terminator; + uint8_t buffer[encoded_size + unencoded_header + terminator]; + // The unencoded header + buffer[0] = 0xF0; + buffer[1] = 0x00; + buffer[2] = 0x00; + buffer[3] = 0x00; + + // We copy the message to the end of the array, this way we can do an inplace encoding, using the same + // buffer for both input and output + const unsigned message_size = length + message_header; + uint8_t* unencoded_start = buffer + buffer_size - message_size; + uint8_t* ptr = unencoded_start; + *(ptr++) = message_type; + *(ptr++) = data_type; + memcpy(ptr, bytes, length); + + unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size); + unsigned final_size = unencoded_header + encoded_length + terminator; + buffer[final_size - 1] = 0xF7; + midi_send_array(&midi_device, final_size, buffer); // SEND_STRING("\nTD: "); // for (uint8_t i = 0; i < encoded_length + 5; i++) { - // send_byte(array[i]); + // send_byte(buffer[i]); // SEND_STRING(" "); // } -} \ No newline at end of file +} diff --git a/quantum/config_common.h b/quantum/config_common.h index 17c11faeb6..4bdb2065d9 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -80,4 +80,6 @@ # endif #endif +#define API_SYSEX_MAX_SIZE 32 + #endif -- cgit v1.2.3 From b8e74c378b1f118178edf0634d9fa7f0f9dd5e08 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Thu, 29 Dec 2016 09:32:02 -0500 Subject: Removed errant + --- quantum/rgblight.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 0f7a1d8280..52a09817a1 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -370,7 +370,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { rgblight_set(); } -+__attribute__ ((weak)) +__attribute__ ((weak)) void rgblight_set(void) { if (rgblight_config.enable) { #ifdef RGBW -- cgit v1.2.3 From 0aa413af44b292e4b44d8f8aee1a92f2cb113438 Mon Sep 17 00:00:00 2001 From: Jonas Oberschweiber Date: Sat, 31 Dec 2016 19:37:56 +0100 Subject: Add support for supplementary planes for OS X --- quantum/process_keycode/process_unicode.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index cd3a610b4d..2606cf0c82 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -116,7 +116,16 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { const uint32_t* map = unicode_map; uint16_t index = keycode & 0x7FF; uint32_t code = pgm_read_dword_far(&map[index]); - if ((code > 0xFFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { + if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) { + // Convert to UTF-16 surrogate pair + code -= 0x10000; + uint32_t lo = code & 0x3ff; + uint32_t hi = (code & 0xffc00) >> 10; + unicode_input_start(); + register_hex32(hi + 0xd800); + register_hex32(lo + 0xdc00); + unicode_input_finish(); + } else if ((code > 0x10ffff && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { // when character is out of range supported by the OS unicode_map_input_error(); } else { -- cgit v1.2.3 From 30b80a23f3cafd846937b37b249f2df4411e1f5a Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Mon, 9 Jan 2017 02:59:10 +0700 Subject: Unregister all mods before inputting Unicode, and reregister afterwards --- quantum/process_keycode/process_unicode.c | 41 +++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index cd3a610b4d..a30e93ae32 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -1,6 +1,8 @@ #include "process_unicode.h" +#include "action_util.h" static uint8_t input_mode; +uint8_t mods; __attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) @@ -25,6 +27,19 @@ uint8_t get_unicode_input_mode(void) { __attribute__((weak)) void unicode_input_start (void) { + // save current mods + mods = keyboard_report->mods; + + // unregister all mods to start from clean state + if (mods & MOD_BIT(KC_LSFT)) unregister_code(KC_LSFT); + if (mods & MOD_BIT(KC_RSFT)) unregister_code(KC_RSFT); + if (mods & MOD_BIT(KC_LCTL)) unregister_code(KC_LCTL); + if (mods & MOD_BIT(KC_RCTL)) unregister_code(KC_RCTL); + if (mods & MOD_BIT(KC_LALT)) unregister_code(KC_LALT); + if (mods & MOD_BIT(KC_RALT)) unregister_code(KC_RALT); + if (mods & MOD_BIT(KC_LGUI)) unregister_code(KC_LGUI); + if (mods & MOD_BIT(KC_RGUI)) unregister_code(KC_RGUI); + switch(input_mode) { case UC_OSX: register_code(KC_LALT); @@ -54,15 +69,25 @@ void unicode_input_start (void) { __attribute__((weak)) void unicode_input_finish (void) { switch(input_mode) { - case UC_OSX: - case UC_WIN: - unregister_code(KC_LALT); - break; - case UC_LNX: - register_code(KC_SPC); - unregister_code(KC_SPC); - break; + case UC_OSX: + case UC_WIN: + unregister_code(KC_LALT); + break; + case UC_LNX: + register_code(KC_SPC); + unregister_code(KC_SPC); + break; } + + // reregister previously set mods + if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT); + if (mods & MOD_BIT(KC_RSFT)) register_code(KC_RSFT); + if (mods & MOD_BIT(KC_LCTL)) register_code(KC_LCTL); + if (mods & MOD_BIT(KC_RCTL)) register_code(KC_RCTL); + if (mods & MOD_BIT(KC_LALT)) register_code(KC_LALT); + if (mods & MOD_BIT(KC_RALT)) register_code(KC_RALT); + if (mods & MOD_BIT(KC_LGUI)) register_code(KC_LGUI); + if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI); } void register_hex(uint16_t hex) { -- cgit v1.2.3 From 8459bb97c1e8bcb9ccce55a1ed849d373bd7706c Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Wed, 11 Jan 2017 21:57:41 -0500 Subject: Adds SCMD and SCMD_T --- quantum/quantum_keycodes.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 5cd3c8e780..7466e185c1 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -159,6 +159,7 @@ enum quantum_keycodes { #define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) #define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) #define ALTG(kc) (kc | QK_RCTL | QK_RALT) +#define SCMD(kc) (kc | QK_LGUI | QK_LSFT) #define MOD_HYPR 0xf #define MOD_MEH 0x7 @@ -293,6 +294,7 @@ enum quantum_keycodes { #define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl #define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui #define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ +#define SCMD_T(kc) MT((MOD_LGUI | MOD_LSFT), kc) // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap #define KC_HYPR HYPR(KC_NO) -- cgit v1.2.3 From 3717cf5864d6505e406b5eb75f315e6dc2392912 Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Thu, 12 Jan 2017 07:38:07 -0500 Subject: A shot at aliasing --- quantum/quantum_keycodes.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 7466e185c1..80cd1d41d8 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -160,6 +160,7 @@ enum quantum_keycodes { #define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) #define ALTG(kc) (kc | QK_RCTL | QK_RALT) #define SCMD(kc) (kc | QK_LGUI | QK_LSFT) +#define SWIN SCMD #define MOD_HYPR 0xf #define MOD_MEH 0x7 @@ -295,6 +296,7 @@ enum quantum_keycodes { #define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui #define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ #define SCMD_T(kc) MT((MOD_LGUI | MOD_LSFT), kc) +#define SWIN_T SCMD_T // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap #define KC_HYPR HYPR(KC_NO) -- cgit v1.2.3 From 7288e5ab9c005a7b035d91e68358aa2b6a12420c Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Fri, 13 Jan 2017 14:04:51 -0500 Subject: Update quantum_keycodes.h --- quantum/quantum_keycodes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 80cd1d41d8..4853655f95 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -160,7 +160,7 @@ enum quantum_keycodes { #define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) #define ALTG(kc) (kc | QK_RCTL | QK_RALT) #define SCMD(kc) (kc | QK_LGUI | QK_LSFT) -#define SWIN SCMD +#define SWIN(kc) SCMD(kc) #define MOD_HYPR 0xf #define MOD_MEH 0x7 @@ -296,7 +296,7 @@ enum quantum_keycodes { #define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui #define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ #define SCMD_T(kc) MT((MOD_LGUI | MOD_LSFT), kc) -#define SWIN_T SCMD_T +#define SWIN_T(kc) SCMD_T(kc) // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap #define KC_HYPR HYPR(KC_NO) -- cgit v1.2.3 From 9eb8d05246fba4f46c04b8fa1884b8f2d2ee0664 Mon Sep 17 00:00:00 2001 From: SjB Date: Tue, 17 Jan 2017 21:47:07 -0500 Subject: added mods status bit to visualizer. Since we can't read the real_mods and oneshot_mods static variable directly within the update_user_visualizer_state function (Threading and serial link). We are know storing the mods states in the visualizer_keyboard_status_t structure. We can now display the status of the modifier keys on the LCD display. --- quantum/visualizer/visualizer.c | 58 ++++++++++++++++++++++++++++++++++++++++- quantum/visualizer/visualizer.h | 9 ++++++- 2 files changed, 65 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c index 54f6faaa42..5826d909e4 100644 --- a/quantum/visualizer/visualizer.c +++ b/quantum/visualizer/visualizer.c @@ -53,10 +53,13 @@ SOFTWARE. #define "Visualizer thread priority not defined" #endif +// mods status +#include "action_util.h" static visualizer_keyboard_status_t current_status = { .layer = 0xFFFFFFFF, .default_layer = 0xFFFFFFFF, + .mods = 0xFF, .leds = 0xFFFFFFFF, .suspended = false, }; @@ -64,6 +67,7 @@ static visualizer_keyboard_status_t current_status = { static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { return status1->layer == status2->layer && status1->default_layer == status2->default_layer && + status1->mods == status2->mods && status1->leds == status2->leds && status1->suspended == status2->suspended; } @@ -307,6 +311,45 @@ bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_s gdispFlush(); return false; } + +static void format_mods_bitmap_string(uint8_t mods, char* buffer) { + *buffer = ' '; + ++buffer; + + for (int i = 0; i<8; i++) + { + uint32_t mask = (1u << i); + if (mods & mask) { + *buffer = '1'; + } else { + *buffer = '0'; + } + ++buffer; + + if (i==3) { + *buffer = ' '; + ++buffer; + } + } + *buffer = 0; +} + +bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state) { + (void)animation; + + const char* title = "Modifier states"; + const char* mods_header = " CSAG CSAG "; + char status_buffer[12]; + + gdispClear(White); + gdispDrawString(0, 0, title, state->font_fixed5x8, Black); + gdispDrawString(0, 10, mods_header, state->font_fixed5x8, Black); + format_mods_bitmap_string(state->status.mods, status_buffer); + gdispDrawString(0, 20, status_buffer, state->font_fixed5x8, Black); + + gdispFlush(); + return false; +} #endif // LCD_ENABLE bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) { @@ -350,6 +393,7 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) { visualizer_keyboard_status_t initial_status = { .default_layer = 0xFFFFFFFF, .layer = 0xFFFFFFFF, + .mods = 0xFF, .leds = 0xFFFFFFFF, .suspended = false, }; @@ -499,7 +543,18 @@ void update_status(bool changed) { #endif } -void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) { +uint8_t visualizer_get_mods() { + uint8_t mods = get_mods(); + +#ifndef NO_ACTION_ONESHOT + if (!has_oneshot_mods_timed_out()) { + mods |= get_oneshot_mods(); + } +#endif + return mods; +} + +void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds) { // Note that there's a small race condition here, the thread could read // a state where one of these are set but not the other. But this should // not really matter as it will be fixed during the next loop step. @@ -523,6 +578,7 @@ void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) { visualizer_keyboard_status_t new_status = { .layer = state, .default_layer = default_state, + .mods = mods, .leds = leds, .suspended = current_status.suspended, }; diff --git a/quantum/visualizer/visualizer.h b/quantum/visualizer/visualizer.h index 53e250725c..315af50228 100644 --- a/quantum/visualizer/visualizer.h +++ b/quantum/visualizer/visualizer.h @@ -34,10 +34,14 @@ SOFTWARE. #include "lcd_backlight.h" #endif +// use this function to merget both real_mods and oneshot_mods in a uint16_t +uint8_t visualizer_get_mods(void); + // This need to be called once at the start void visualizer_init(void); // This should be called at every matrix scan -void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds); +void visualizer_update(uint32_t default_state, uint32_t state, uint8_t mods, uint32_t leds); + // This should be called when the keyboard goes to suspend state void visualizer_suspend(void); // This should be called when the keyboard wakes up from suspend state @@ -61,6 +65,7 @@ struct keyframe_animation_t; typedef struct { uint32_t layer; uint32_t default_layer; + uint8_t mods; uint32_t leds; // See led.h for available statuses bool suspended; } visualizer_keyboard_status_t; @@ -129,6 +134,8 @@ bool keyframe_set_backlight_color(keyframe_animation_t* animation, visualizer_st bool keyframe_display_layer_text(keyframe_animation_t* animation, visualizer_state_t* state); // Displays a bitmap (0/1) of all the currently active layers bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); +// Displays a bitmap (0/1) of all the currently active mods +bool keyframe_display_mods_bitmap(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state); -- cgit v1.2.3 From 841d7e6a1d74b1fc45575ed551132ec27353ebf3 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 23 Jan 2017 13:55:24 -0500 Subject: turn off rgb_midi in ez --- quantum/process_keycode/process_music.c | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c index ca68bef6c8..1e2648bff5 100644 --- a/quantum/process_keycode/process_music.c +++ b/quantum/process_keycode/process_music.c @@ -114,6 +114,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) { music_sequence_interval+=10; return false; } + #define MUSIC_MODE_GUITAR #ifdef MUSIC_MODE_CHROMATIC float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(MATRIX_ROWS - record->event.key.row)); -- cgit v1.2.3 From 2b3859937b1e7f96b684408d31ff12a4e682f7ee Mon Sep 17 00:00:00 2001 From: SjB Date: Sat, 21 Jan 2017 02:01:55 -0500 Subject: speeding up (un)register_code16 In register_code16 and unregister_code16 we call register_code and unregister_code twice, once for the mods and once for the keycode. The (un)register_code have many check to see that keycode we have sent however because we know that we are sending it a mods key, why not just skip all of it and call (un)register_mods instead. This will skip alot of checks and should speedup the loop a little. --- quantum/quantum.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 63ffe2074e..1767faed42 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -33,14 +33,22 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { f(KC_RGUI); } +static inline void qk_register_mods(uint8_t kc) { + register_mods(MOD_BIT(kc)); +} + +static inline void qk_unregister_mods(uint8_t kc) { + unregister_mods(MOD_BIT(kc)); +} + void register_code16 (uint16_t code) { - do_code16 (code, register_code); + do_code16 (code, qk_register_mods); register_code (code); } void unregister_code16 (uint16_t code) { unregister_code (code); - do_code16 (code, unregister_code); + do_code16 (code, qk_unregister_mods); } __attribute__ ((weak)) -- cgit v1.2.3 From cfc4149712217625fcb75e50348094fd9df432f5 Mon Sep 17 00:00:00 2001 From: Luke Silva Date: Fri, 27 Jan 2017 10:28:42 +1100 Subject: Add ability to use tap macros without using functions --- quantum/keymap_common.c | 5 ++++- quantum/quantum_keycodes.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index eced3d2bba..5190f24e87 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -80,7 +80,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) action.code = keymap_function_id_to_action( (int)keycode & 0xFFF ); break; case QK_MACRO ... QK_MACRO_MAX: - action.code = ACTION_MACRO(keycode & 0xFF); + if (keycode & 0x800) // tap macros have upper bit set + action.code = ACTION_MACRO_TAP(keycode & 0xFF); + else + action.code = ACTION_MACRO(keycode & 0xFF); break; case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 4853655f95..4566395fd8 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -246,6 +246,7 @@ enum quantum_keycodes { #define M(kc) (kc | QK_MACRO) +#define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8) #define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) // L-ayer, T-ap - 256 keycode max, 16 layer max -- cgit v1.2.3 From 2fe18a50ecddd5b8a8783f7185ad48b2e80d6bc0 Mon Sep 17 00:00:00 2001 From: Potiguar Faga Date: Fri, 27 Jan 2017 18:22:44 -0200 Subject: Clarify license on abnt2 keymap (#1038) --- quantum/keymap_extras/keymap_br_abnt2.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_br_abnt2.h b/quantum/keymap_extras/keymap_br_abnt2.h index 0df177721d..b001139dd4 100644 --- a/quantum/keymap_extras/keymap_br_abnt2.h +++ b/quantum/keymap_extras/keymap_br_abnt2.h @@ -1,3 +1,19 @@ +/* Copyright 2017 Potiguar Faga + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifndef KEYMAP_BR_ABNT2_H #define KEYMAP_BR_ABNT2_H -- cgit v1.2.3 From a3357d078ee80123040679a357f63e93ff24c4c6 Mon Sep 17 00:00:00 2001 From: Luke Silva Date: Sat, 28 Jan 2017 18:42:35 +1100 Subject: Add support for various tapping macros A macro key can now be easily set to act as a modifier on hold, and press a shifted key when tapped. Or to switch layers when held, and again press a shifted key when tapped. Various other helper defines have been created which send macros when the key is pressed, released and tapped, cleaning up the action_get_macro function inside keymap definitions. The layer switching macros require a GCC extension - 'compound statements enclosed within parentheses'. The use of this extension is already present within the macro subsystem of this project, so its use in this commit should not cause any additional issues. MACRO_NONE had to be cast to a (macro_t*) to suppress compiler warnings within some tapping macros. --- quantum/quantum_keycodes.h | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 4566395fd8..e0d4695618 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -249,6 +249,7 @@ enum quantum_keycodes { #define MACROTAP(kc) (kc | QK_MACRO | FUNC_TAP<<8) #define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) + // L-ayer, T-ap - 256 keycode max, 16 layer max #define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) -- cgit v1.2.3 From f644b9a07a34ae19a6014b08db656a4eeca1dcda Mon Sep 17 00:00:00 2001 From: SjB Date: Sun, 29 Jan 2017 12:06:24 -0500 Subject: registering a weak_mods when using register_code16 Scenario: Locking the KC_LSHIFT, and then using a tap dance key that registers a S(KC_9) will unregister the KC_LSHIFT. The tap dance or any keycode that is registered should not have the side effect of cancelling a locked moditifier. We should be using a similar logic as the TMK codes in tmk_core/comman/action.c:158. --- quantum/quantum.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 1767faed42..0aecd238e4 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -33,22 +33,42 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { f(KC_RGUI); } +static inline void qk_register_weak_mods(uint8_t kc) { + add_weak_mods(MOD_BIT(kc)); + send_keyboard_report(); +} + +static inline void qk_unregister_weak_mods(uint8_t kc) { + del_weak_mods(MOD_BIT(kc)); + send_keyboard_report(); +} + static inline void qk_register_mods(uint8_t kc) { - register_mods(MOD_BIT(kc)); + add_weak_mods(MOD_BIT(kc)); + send_keyboard_report(); } static inline void qk_unregister_mods(uint8_t kc) { - unregister_mods(MOD_BIT(kc)); + del_weak_mods(MOD_BIT(kc)); + send_keyboard_report(); } void register_code16 (uint16_t code) { - do_code16 (code, qk_register_mods); + if (IS_MOD(code) || code == KC_NO) { + do_code16 (code, qk_register_mods); + } else { + do_code16 (code, qk_register_weak_mods); + } register_code (code); } void unregister_code16 (uint16_t code) { unregister_code (code); - do_code16 (code, qk_unregister_mods); + if (IS_MOD(code) || code == KC_NO) { + do_code16 (code, qk_unregister_mods); + } else { + do_code16 (code, qk_unregister_weak_mods); + } } __attribute__ ((weak)) -- cgit v1.2.3 From 5a860b71a1943358d0722ace9d2c13bd5c77c971 Mon Sep 17 00:00:00 2001 From: SjB Date: Sun, 29 Jan 2017 13:04:43 -0500 Subject: race condition between oneshot_mods and tap_dance since the keycode for a tap dance process gets process only after the TAPPING_TERM timeout, you really only have ONESHOT_TIMEOUT - TAPPING_TERM time to tap or double tap on the key. This fix save the oneshot_mods into the action.state structure and applies the mods with the keycode when it's registered. It also unregisters the mod when the the tap dance process gets reset. --- quantum/process_keycode/process_tap_dance.c | 7 ++++++- quantum/process_keycode/process_tap_dance.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 6ae362c4c2..403dca5380 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -43,12 +43,16 @@ static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_acti if (action->state.finished) return; action->state.finished = true; + add_mods(action->state.oneshot_mods); + send_keyboard_report(); _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished); } static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action) { _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset); + del_mods(action->state.oneshot_mods); + send_keyboard_report(); } bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { @@ -70,6 +74,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { action->state.keycode = keycode; action->state.count++; action->state.timer = timer_read(); + action->state.oneshot_mods = get_oneshot_mods(); process_tap_dance_action_on_each_tap (action); if (last_td && last_td != keycode) { @@ -109,7 +114,7 @@ void matrix_scan_tap_dance () { if (highest_td == -1) return; - for (int i = 0; i <= highest_td; i++) { +for (int i = 0; i <= highest_td; i++) { qk_tap_dance_action_t *action = &tap_dance_actions[i]; if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) { diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index f753cbba66..726752ecc7 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -9,6 +9,7 @@ typedef struct { uint8_t count; + uint8_t oneshot_mods; uint16_t keycode; uint16_t timer; bool interrupted; -- cgit v1.2.3 From f46c2b3ca07c83e13bea6fc33a3c95fed4a9ece2 Mon Sep 17 00:00:00 2001 From: Erez Zukerman Date: Tue, 31 Jan 2017 21:31:05 -0500 Subject: Introduces ALGR_T for dual-function AltGr --- quantum/quantum_keycodes.h | 1 + 1 file changed, 1 insertion(+) (limited to 'quantum') diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 4853655f95..91324be35d 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -290,6 +290,7 @@ enum quantum_keycodes { #define CTL_T(kc) MT(MOD_LCTL, kc) #define SFT_T(kc) MT(MOD_LSFT, kc) #define ALT_T(kc) MT(MOD_LALT, kc) +#define ALGR_T(kc) MT(MOD_RALT, kc) // dual-function AltGR #define GUI_T(kc) MT(MOD_LGUI, kc) #define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal #define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl -- cgit v1.2.3 From c17070eca545f654f91cf3dcba6c6c611e0f8d03 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Wed, 1 Feb 2017 15:35:21 +0700 Subject: Add layer switcher keycodes: OUT_AUTO, OUT_USB, OUT_BT, OUT_BLE --- quantum/quantum.c | 29 +++++++++++++++++++++++++++++ quantum/quantum_keycodes.h | 10 ++++++++++ 2 files changed, 39 insertions(+) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 63ffe2074e..1d1a691e24 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,4 +1,5 @@ #include "quantum.h" +#include "outputselect.h" #ifndef TAPPING_TERM #define TAPPING_TERM 200 @@ -212,6 +213,34 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif + case OUT_AUTO: + if (record->event.pressed) { + set_output(OUTPUT_AUTO); + } + return false; + break; + case OUT_USB: + if (record->event.pressed) { + set_output(OUTPUT_USB); + } + return false; + break; + #ifdef BLUETOOTH_ENABLE + case OUT_BT: + if (record->event.pressed) { + set_output(OUTPUT_BLUETOOTH); + } + return false; + break; + #endif + #ifdef ADAFRUIT_BLE_ENABLE + case OUT_BLE: + if (record->event.pressed) { + set_output(OUTPUT_ADAFRUIT_BLE); + } + return false; + break; + #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 4853655f95..4f1345b49f 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -141,6 +141,16 @@ enum quantum_keycodes { PRINT_ON, PRINT_OFF, + // output selection + OUT_AUTO, + OUT_USB, +#ifdef BLUETOOTH_ENABLE + OUT_BT, +#endif +#ifdef ADAFRUIT_BLE_ENABLE + OUT_BLE, +#endif + // always leave at the end SAFE_RANGE }; -- cgit v1.2.3 From 2bef8b5b88547ce28fb056559b058e35109278b3 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Wed, 1 Feb 2017 19:37:52 +0700 Subject: Limit outputselect to AVR only for now --- quantum/quantum.c | 4 ++++ quantum/quantum.h | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 1d1a691e24..585692d4a3 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,5 +1,7 @@ #include "quantum.h" +#if defined(__AVR__) #include "outputselect.h" +#endif #ifndef TAPPING_TERM #define TAPPING_TERM 200 @@ -213,6 +215,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif + #if defined(__AVR__) case OUT_AUTO: if (record->event.pressed) { set_output(OUTPUT_AUTO); @@ -241,6 +244,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif + #endif case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) diff --git a/quantum/quantum.h b/quantum/quantum.h index e6adf974ab..810e9e4bb7 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -15,7 +15,6 @@ #ifdef RGBLIGHT_ENABLE #include "rgblight.h" #endif - #include "action_layer.h" #include "eeconfig.h" #include -- cgit v1.2.3 From e7c4f621f14b60bde68c01ae076cac49cac9927e Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Wed, 1 Feb 2017 22:30:06 +0700 Subject: Restrict outputselect to LUFA only for now --- quantum/quantum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index 585692d4a3..ad957a1b11 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,5 +1,5 @@ #include "quantum.h" -#if defined(__AVR__) +#ifdef PROTOCOL_LUFA #include "outputselect.h" #endif @@ -215,7 +215,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif - #if defined(__AVR__) + #ifdef PROTOCOL_LUFA case OUT_AUTO: if (record->event.pressed) { set_output(OUTPUT_AUTO); -- cgit v1.2.3 From e667e9f6da17c5551379b168cc97647b44972d10 Mon Sep 17 00:00:00 2001 From: Nikolaus Wittenstein Date: Fri, 3 Feb 2017 21:00:10 -0500 Subject: Fix compile warnings in light_ws2812.c Fixes the warning "function declaration isn't a prototype" by explicitly making the parameter list void. --- quantum/light_ws2812.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'quantum') diff --git a/quantum/light_ws2812.c b/quantum/light_ws2812.c index a883b13884..55bdd9cd81 100755 --- a/quantum/light_ws2812.c +++ b/quantum/light_ws2812.c @@ -70,7 +70,7 @@ void I2C_WriteBit(unsigned char c) // Inits bitbanging port, must be called before using the functions below // -void I2C_Init() +void I2C_Init(void) { I2C_PORT &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); @@ -82,7 +82,7 @@ void I2C_Init() // Send a START Condition // -void I2C_Start() +void I2C_Start(void) { // set both to high at the same time I2C_DDR &= ~ ((1 << I2C_DAT) | (1 << I2C_CLK)); @@ -97,7 +97,7 @@ void I2C_Start() // Send a STOP Condition // -void I2C_Stop() +void I2C_Stop(void) { I2C_CLOCK_HI(); _delay_us(I2C_DELAY); -- cgit v1.2.3 From d961c80df2391631f7b3f46afa595ce93f51f217 Mon Sep 17 00:00:00 2001 From: Nikolaus Wittenstein Date: Sun, 5 Feb 2017 19:41:08 -0500 Subject: Remove unused matrix_raw variable in matrix.c --- quantum/matrix.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index 07eb87bc36..fd312bffba 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -66,7 +66,6 @@ static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_raw[MATRIX_ROWS]; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; @@ -166,7 +165,6 @@ void matrix_init(void) { // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) { matrix[i] = 0; - matrix_raw[i] = 0; matrix_debouncing[i] = 0; } -- cgit v1.2.3 From 8cbf61c91923e5399b158f7f9258096cb0089ce2 Mon Sep 17 00:00:00 2001 From: Nikolaus Wittenstein Date: Sun, 5 Feb 2017 19:42:00 -0500 Subject: Add new DIODE_DIRECTION option The previous two options were COL2ROW, ROW2COL; this adds CUSTOM_MATRIX to disable the built-in matrix scanning code. Most notably, this obviates the need to set MATRIX_ROW_PINS or MATRIX_COL_PINS. --- quantum/config_common.h | 6 ++++-- quantum/matrix.c | 12 +++++++----- quantum/template/config.h | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) (limited to 'quantum') diff --git a/quantum/config_common.h b/quantum/config_common.h index 4bdb2065d9..28f68b9c70 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -2,8 +2,10 @@ #define CONFIG_DEFINITIONS_H /* diode directions */ -#define COL2ROW 0 -#define ROW2COL 1 +#define COL2ROW 0 +#define ROW2COL 1 +#define CUSTOM_MATRIX 2 /* Disables built-in matrix scanning code */ + /* I/O pins */ #ifndef F0 #define B0 0x30 diff --git a/quantum/matrix.c b/quantum/matrix.c index fd312bffba..ac523482ad 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -60,8 +60,10 @@ along with this program. If not, see . extern const matrix_row_t matrix_mask[]; #endif +#if (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +#endif /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; @@ -75,7 +77,7 @@ static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static void unselect_rows(void); static void select_row(uint8_t row); static void unselect_row(uint8_t row); -#else // ROW2COL +#elif (DIODE_DIRECTION == ROW2COL) static void init_rows(void); static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); static void unselect_cols(void); @@ -132,7 +134,7 @@ uint8_t matrix_cols(void) { // /* PORTxn */ // _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF); // } -// #else +// #elif (DIODE_DIRECTION == ROW2COL) // for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { // /* DDRxn */ // _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF); @@ -157,7 +159,7 @@ void matrix_init(void) { #if (DIODE_DIRECTION == COL2ROW) unselect_rows(); init_cols(); -#else // ROW2COL +#elif (DIODE_DIRECTION == ROW2COL) unselect_cols(); init_rows(); #endif @@ -192,7 +194,7 @@ uint8_t matrix_scan(void) } -#else // ROW2COL +#elif (DIODE_DIRECTION == ROW2COL) // Set col, read rows for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { @@ -334,7 +336,7 @@ static void unselect_rows(void) } } -#else // ROW2COL +#elif (DIODE_DIRECTION == ROW2COL) static void init_rows(void) { diff --git a/quantum/template/config.h b/quantum/template/config.h index b02f0c7ebc..c61c4a6181 100644 --- a/quantum/template/config.h +++ b/quantum/template/config.h @@ -46,7 +46,7 @@ along with this program. If not, see . #define MATRIX_COL_PINS { F1, F0, B0 } #define UNUSED_PINS -/* COL2ROW or ROW2COL */ +/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */ #define DIODE_DIRECTION COL2ROW // #define BACKLIGHT_PIN B7 -- cgit v1.2.3 From 0e548f8b5d6b89de877f098ea919eaea87511b6e Mon Sep 17 00:00:00 2001 From: dungdung Date: Mon, 6 Feb 2017 14:08:21 -0800 Subject: Christmas mode now works with even RGBED_NUM Added Christmas mode steps to reduce red and green colors blending into each other Added Christmas mode interval Increased green hue to 120 --- quantum/rgblight.c | 8 ++++---- quantum/rgblight.h | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 52a09817a1..f91f3caff5 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -237,7 +237,7 @@ void rgblight_mode(uint8_t mode) { #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_disable(); #endif - } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 23) { + } else if (rgblight_config.mode >= 2 && rgblight_config.mode <= 24) { // MODE 2-5, breathing // MODE 6-8, rainbow mood // MODE 9-14, rainbow swirl @@ -450,7 +450,7 @@ void rgblight_task(void) { } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) { // mode = 21 to 23, knight mode rgblight_effect_knight(rgblight_config.mode - 21); - } else { + } else if (rgblight_config.mode == 24) { // mode = 24, christmas mode rgblight_effect_christmas(); } @@ -604,13 +604,13 @@ void rgblight_effect_christmas(void) { static uint16_t last_timer = 0; uint16_t hue; uint8_t i; - if (timer_elapsed(last_timer) < 1000) { + if (timer_elapsed(last_timer) < RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL) { return; } last_timer = timer_read(); current_offset = (current_offset + 1) % 2; for (i = 0; i < RGBLED_NUM; i++) { - hue = 0 + ((RGBLED_NUM * (i + current_offset)) % 2) * 80; + hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + current_offset) % 2) * 120; sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); } rgblight_set(); diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 726b8de72e..12e8583057 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -22,6 +22,14 @@ #define RGBLIGHT_EFFECT_DUALKNIGHT_LENGTH 4 #endif +#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL +#define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 1000 +#endif + +#ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP +#define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2 +#endif + #ifndef RGBLIGHT_HUE_STEP #define RGBLIGHT_HUE_STEP 10 #endif -- cgit v1.2.3 From 5a1b68d562036ff26820069baafe40654eef70a3 Mon Sep 17 00:00:00 2001 From: dungdung Date: Mon, 6 Feb 2017 14:09:29 -0800 Subject: Added mode reverse step function --- quantum/rgblight.c | 8 ++++++++ quantum/rgblight.h | 1 + 2 files changed, 9 insertions(+) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index f91f3caff5..7e057b63e8 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -219,6 +219,14 @@ void rgblight_step(void) { } rgblight_mode(mode); } +void rgblight_step_reverse(void) { + uint8_t mode = 0; + mode = rgblight_config.mode - 1; + if (mode < 1) { + mode = RGBLIGHT_MODES; + } + rgblight_mode(mode); +} void rgblight_mode(uint8_t mode) { if (!rgblight_config.enable) { diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 12e8583057..a63b246047 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -73,6 +73,7 @@ void rgblight_decrease(void); void rgblight_toggle(void); void rgblight_enable(void); void rgblight_step(void); +void rgblight_step_reverse(void); void rgblight_mode(uint8_t mode); void rgblight_set(void); void rgblight_update_dword(uint32_t dword); -- cgit v1.2.3 From a7882b1ffceb6002dd1adf916a8fc32523227860 Mon Sep 17 00:00:00 2001 From: dungdung Date: Mon, 6 Feb 2017 14:14:56 -0800 Subject: Added non-animated gradient mode --- quantum/rgblight.c | 19 +++++++++++++++++++ quantum/rgblight.h | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'quantum') diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 7e057b63e8..dd1b91c63c 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -66,6 +66,8 @@ __attribute__ ((weak)) const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; __attribute__ ((weak)) const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20}; +__attribute__ ((weak)) +const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90}; rgblight_config_t rgblight_config; rgblight_config_t inmem_config; @@ -255,6 +257,12 @@ void rgblight_mode(uint8_t mode) { #ifdef RGBLIGHT_ANIMATIONS rgblight_timer_enable(); #endif + } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) { + // MODE 25-34, static gradient + + #ifdef RGBLIGHT_ANIMATIONS + rgblight_timer_disable(); + #endif } rgblight_sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } @@ -358,6 +366,17 @@ void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) { // rainbow mood and rainbow swirl, ignore the change of hue hue = rgblight_config.hue; + } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) { + // static gradient + uint16_t _hue; + int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1; + uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]); + for (uint8_t i = 0; i < RGBLED_NUM; i++) { + _hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360; + dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range); + sethsv(_hue, sat, val, (LED_TYPE *)&led[i]); + } + rgblight_set(); } } rgblight_config.hue = hue; diff --git a/quantum/rgblight.h b/quantum/rgblight.h index a63b246047..2b3e791bf8 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -2,7 +2,7 @@ #define RGBLIGHT_H #ifdef RGBLIGHT_ANIMATIONS - #define RGBLIGHT_MODES 24 + #define RGBLIGHT_MODES 34 #else #define RGBLIGHT_MODES 1 #endif -- cgit v1.2.3 From b4e30d392969b000eb9a87065fc1caaf33d670e1 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 7 Feb 2017 15:23:56 -0500 Subject: added functionality for just a port --- quantum/quantum.c | 94 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 32 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum.c b/quantum/quantum.c index d3905decf2..45ea8cb73c 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -594,34 +594,45 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN; # define COM1x1 COM1A1 # define OCR1x OCR1A #else -# error "Backlight pin not supported - use B5, B6, or B7" +# define NO_BACKLIGHT_CLOCK +#endif + +#ifndef BACKLIGHT_ON_STATE +#define BACKLIGHT_ON_STATE 0 #endif __attribute__ ((weak)) void backlight_init_ports(void) { - // Setup backlight pin as output and output low. + // Setup backlight pin as output and output to on state. // DDRx |= n _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); - // PORTx &= ~n - _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + #if BACKLIGHT_ON_STATE == 0 + // PORTx &= ~n + _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + #else + // PORTx |= n + _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); + #endif - // Use full 16-bit resolution. - ICR1 = 0xFFFF; + #ifndef NO_BACKLIGHT_CLOCK + // Use full 16-bit resolution. + ICR1 = 0xFFFF; - // I could write a wall of text here to explain... but TL;DW - // Go read the ATmega32u4 datasheet. - // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on + // I could write a wall of text here to explain... but TL;DW + // Go read the ATmega32u4 datasheet. + // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on - // Pin PB7 = OCR1C (Timer 1, Channel C) - // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 - // (i.e. start high, go low when counter matches.) - // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 - // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 + // Pin PB7 = OCR1C (Timer 1, Channel C) + // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 + // (i.e. start high, go low when counter matches.) + // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 + // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 - TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; - TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; + TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; + TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; + #endif backlight_init(); #ifdef BACKLIGHT_BREATHING @@ -633,24 +644,43 @@ __attribute__ ((weak)) void backlight_set(uint8_t level) { // Prevent backlight blink on lowest level - // PORTx &= ~n - _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + #if BACKLIGHT_ON_STATE == 0 + // PORTx &= ~n + _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + #else + // PORTx |= n + _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); + #endif if ( level == 0 ) { - // Turn off PWM control on backlight pin, revert to output low. - TCCR1A &= ~(_BV(COM1x1)); - OCR1x = 0x0; - } else if ( level == BACKLIGHT_LEVELS ) { - // Turn on PWM control of backlight pin - TCCR1A |= _BV(COM1x1); - // Set the brightness - OCR1x = 0xFFFF; - } else { - // Turn on PWM control of backlight pin - TCCR1A |= _BV(COM1x1); - // Set the brightness - OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); - } + #ifndef NO_BACKLIGHT_CLOCK + // Turn off PWM control on backlight pin, revert to output low. + TCCR1A &= ~(_BV(COM1x1)); + OCR1x = 0x0; + #else + #if BACKLIGHT_ON_STATE == 0 + // PORTx |= n + _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); + #else + // PORTx &= ~n + _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); + #endif + #endif + } + #ifndef NO_BACKLIGHT_CLOCK + else if ( level == BACKLIGHT_LEVELS ) { + // Turn on PWM control of backlight pin + TCCR1A |= _BV(COM1x1); + // Set the brightness + OCR1x = 0xFFFF; + } + else { + // Turn on PWM control of backlight pin + TCCR1A |= _BV(COM1x1); + // Set the brightness + OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); + } + #endif #ifdef BACKLIGHT_BREATHING breathing_intensity_default(); -- cgit v1.2.3 From 97816df7e7aa8710c8a0837b2abe008e0c765f2a Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Fri, 10 Feb 2017 06:06:59 +0700 Subject: Implement tap mod dual role for right side mods. --- quantum/keymap_common.c | 2 +- quantum/process_keycode/process_unicode.c | 2 +- quantum/quantum_keycodes.h | 28 +++++++++++++++++++++------- 3 files changed, 23 insertions(+), 9 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 5190f24e87..54b872d49e 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -120,7 +120,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) action.code = ACTION_MODS_ONESHOT(mod); break; case QK_MOD_TAP ... QK_MOD_TAP_MAX: - action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF); + action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0x1F, keycode & 0xFF); break; #ifdef BACKLIGHT_ENABLE case BL_0 ... BL_15: diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index 9995ba9bde..9d01a592d2 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -139,7 +139,7 @@ void unicode_map_input_error() {} bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) { const uint32_t* map = unicode_map; - uint16_t index = keycode & 0x7FF; + uint16_t index = keycode - QK_UNICODE_MAP; uint32_t code = pgm_read_dword_far(&map[index]); if (code > 0xFFFF && code <= 0x10ffff && input_mode == UC_OSX) { // Convert to UTF-16 surrogate pair diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 8a78a58c9f..e562c9a18b 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -39,14 +39,14 @@ enum quantum_keycodes { QK_CHORDING = 0x5600, QK_CHORDING_MAX = 0x56FF, #endif - QK_MOD_TAP = 0x6000, - QK_MOD_TAP_MAX = 0x6FFF, - QK_TAP_DANCE = 0x7100, - QK_TAP_DANCE_MAX = 0x71FF, + QK_TAP_DANCE = 0x5700, + QK_TAP_DANCE_MAX = 0x57FF, #ifdef UNICODEMAP_ENABLE - QK_UNICODE_MAP = 0x7800, - QK_UNICODE_MAP_MAX = 0x7FFF, + QK_UNICODE_MAP = 0x5800, + QK_UNICODE_MAP_MAX = 0x5FFF, #endif + QK_MOD_TAP = 0x6000, + QK_MOD_TAP_MAX = 0x7FFF, #ifdef UNICODE_ENABLE QK_UNICODE = 0x8000, QK_UNICODE_MAX = 0xFFFF, @@ -298,15 +298,29 @@ enum quantum_keycodes { #define OSM(mod) (mod | QK_ONE_SHOT_MOD) // M-od, T-ap - 256 keycode max -#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0xF) << 8)) +#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0x1F) << 8)) + #define CTL_T(kc) MT(MOD_LCTL, kc) +#define LCTL_T(kc) MT(MOD_LCTL, kc) +#define RCTL_T(kc) MT(MOD_RCTL, kc) + #define SFT_T(kc) MT(MOD_LSFT, kc) +#define LSFT_T(kc) MT(MOD_LSFT, kc) +#define RSFT_T(kc) MT(MOD_RSFT, kc) + #define ALT_T(kc) MT(MOD_LALT, kc) +#define LALT_T(kc) MT(MOD_LALT, kc) +#define RALT_T(kc) MT(MOD_RALT, kc) #define ALGR_T(kc) MT(MOD_RALT, kc) // dual-function AltGR + #define GUI_T(kc) MT(MOD_LGUI, kc) +#define LGUI_T(kc) MT(MOD_LGUI, kc) +#define RGUI_T(kc) MT(MOD_RGUI, kc) + #define C_S_T(kc) MT((MOD_LCTL | MOD_LSFT), kc) // Control + Shift e.g. for gnome-terminal #define MEH_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT), kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl #define LCAG_T(kc) MT((MOD_LCTL | MOD_LALT | MOD_LGUI), kc) // Left control alt and gui +#define RCAG_T(kc) MT((MOD_RCTL | MOD_RALT | MOD_RGUI), kc) // Right control alt and gui #define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ #define SCMD_T(kc) MT((MOD_LGUI | MOD_LSFT), kc) #define SWIN_T(kc) SCMD_T(kc) -- cgit v1.2.3 From b92515f139a80763b9b0b77ed4440cd9635fafac Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Sat, 11 Feb 2017 00:36:08 +0700 Subject: Make room for 'loose keycodes' by halving UNICODE_MAP range --- quantum/quantum_keycodes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index e562c9a18b..ab2e790269 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -43,7 +43,7 @@ enum quantum_keycodes { QK_TAP_DANCE_MAX = 0x57FF, #ifdef UNICODEMAP_ENABLE QK_UNICODE_MAP = 0x5800, - QK_UNICODE_MAP_MAX = 0x5FFF, + QK_UNICODE_MAP_MAX = 0x5BFF, #endif QK_MOD_TAP = 0x6000, QK_MOD_TAP_MAX = 0x7FFF, @@ -54,7 +54,7 @@ enum quantum_keycodes { // Loose keycodes - to be used directly - RESET = 0x7000, + RESET = 0x5C00, DEBUG, MAGIC_SWAP_CONTROL_CAPSLOCK, MAGIC_CAPSLOCK_TO_CONTROL, -- cgit v1.2.3 From c68e596f32c5d450a714627871408407e9988ef7 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Mon, 13 Feb 2017 08:03:07 +0700 Subject: Implement faux-clicky feature --- quantum/fauxclicky.c | 68 ++++++++++++++++++++++++++++++++++++ quantum/fauxclicky.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++ quantum/template/rules.mk | 1 + 3 files changed, 156 insertions(+) create mode 100644 quantum/fauxclicky.c create mode 100644 quantum/fauxclicky.h (limited to 'quantum') diff --git a/quantum/fauxclicky.c b/quantum/fauxclicky.c new file mode 100644 index 0000000000..13273e7058 --- /dev/null +++ b/quantum/fauxclicky.c @@ -0,0 +1,68 @@ +/* +Copyright 2017 Priyadi Iman Nurcahyo + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +__attribute__ ((weak)) +float fauxclicky_pressed_note[2] = MUSICAL_NOTE(_F3, 2); +__attribute__ ((weak)) +float fauxclicky_released_note[2] = MUSICAL_NOTE(_A3, 2); +__attribute__ ((weak)) +float fauxclicky_beep_note[2] = MUSICAL_NOTE(_C3, 2); + +bool fauxclicky_enabled = true; +uint16_t note_start = 0; +bool note_playing = false; +uint16_t note_period = 0; + +void fauxclicky_init() +{ + // Set port PC6 (OC3A and /OC4A) as output + DDRC |= _BV(PORTC6); + + // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); +} + +void fauxclicky_stop() +{ + FAUXCLICKY_DISABLE_OUTPUT; + note_playing = false; +} + +void fauxclicky_play(float note[2]) { + if (!fauxclicky_enabled) return; + if (note_playing) fauxclicky_stop(); + FAUXCLICKY_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (note[0] * FAUXCLICKY_CPU_PRESCALER)); + FAUXCLICKY_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (note[0] * FAUXCLICKY_CPU_PRESCALER)) / 2); + note_playing = true; + note_period = (note[1] / 16) * (60 / (float)FAUXCLICKY_TEMPO) * 100; // check this + note_start = timer_read(); + FAUXCLICKY_ENABLE_OUTPUT; +} + +void fauxclicky_check() { + if (!note_playing) return; + + if (timer_elapsed(note_start) > note_period) { + fauxclicky_stop(); + } +} diff --git a/quantum/fauxclicky.h b/quantum/fauxclicky.h new file mode 100644 index 0000000000..6cfc291c05 --- /dev/null +++ b/quantum/fauxclicky.h @@ -0,0 +1,87 @@ +/* +Copyright 2017 Priyadi Iman Nurcahyo + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#ifdef AUDIO_ENABLE +#error "AUDIO_ENABLE and FAUXCLICKY_ENABLE cannot be both enabled" +#endif + +#include "musical_notes.h" + +__attribute__ ((weak)) +float fauxclicky_pressed_note[2]; +__attribute__ ((weak)) +float fauxclicky_released_note[2]; +__attribute__ ((weak)) +float fauxclicky_beep_note[2]; + +// +// tempo in BPM +// + +#ifndef FAUXCLICKY_TEMPO +#define FAUXCLICKY_TEMPO TEMPO_DEFAULT +#endif + +// beep on press +#define FAUXCLICKY_ACTION_PRESS fauxclicky_play(fauxclicky_pressed_note) + +// beep on release +#define FAUXCLICKY_ACTION_RELEASE fauxclicky_play(fauxclicky_released_note) + +// general purpose beep +#define FAUXCLICKY_BEEP fauxclicky_play(fauxclicky_beep_note) + +// enable +#define FAUXCLICKY_ON fauxclicky_enabled = true + +// disable +#define FAUXCLICKY_OFF do { \ + fauxclicky_enabled = false; \ + fauxclicky_stop(); \ +} while (0) + +// +// pin configuration +// + +#ifndef FAUXCLICKY_CPU_PRESCALER +#define FAUXCLICKY_CPU_PRESCALER 8 +#endif + +#ifndef FAUXCLICKY_ENABLE_OUTPUT +#define FAUXCLICKY_ENABLE_OUTPUT TCCR3A |= _BV(COM3A1); +#endif + +#ifndef FAUXCLICKY_DISABLE_OUTPUT +#define FAUXCLICKY_DISABLE_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); +#endif + +#ifndef FAUXCLICKY_TIMER_PERIOD +#define FAUXCLICKY_TIMER_PERIOD ICR3 +#endif + +#ifndef FAUXCLICKY_DUTY_CYCLE +#define FAUXCLICKY_DUTY_CYCLE OCR3A +#endif + +// +// definitions +// + +void fauxclicky_init(void); +void fauxclicky_stop(void); +void fauxclicky_play(float note[2]); +void fauxclicky_check(void); + diff --git a/quantum/template/rules.mk b/quantum/template/rules.mk index 55898147dd..bad3387bf4 100644 --- a/quantum/template/rules.mk +++ b/quantum/template/rules.mk @@ -65,3 +65,4 @@ MIDI_ENABLE ?= no # MIDI controls UNICODE_ENABLE ?= no # Unicode BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE ?= no # Audio output on port C6 +FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches -- cgit v1.2.3 From 8c93c5d9ab8a0a69d84f707db71f417b66402693 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Mon, 13 Feb 2017 14:55:35 +0700 Subject: Add keycodes to turn on, turn off and toggle faux clicky --- quantum/fauxclicky.h | 12 ++++++++++++ quantum/quantum.c | 24 ++++++++++++++++++++++++ quantum/quantum_keycodes.h | 7 +++++++ 3 files changed, 43 insertions(+) (limited to 'quantum') diff --git a/quantum/fauxclicky.h b/quantum/fauxclicky.h index 6cfc291c05..109bd0d83e 100644 --- a/quantum/fauxclicky.h +++ b/quantum/fauxclicky.h @@ -18,6 +18,7 @@ along with this program. If not, see . #endif #include "musical_notes.h" +#include "stdbool.h" __attribute__ ((weak)) float fauxclicky_pressed_note[2]; @@ -26,6 +27,8 @@ float fauxclicky_released_note[2]; __attribute__ ((weak)) float fauxclicky_beep_note[2]; +bool fauxclicky_enabled; + // // tempo in BPM // @@ -52,6 +55,15 @@ float fauxclicky_beep_note[2]; fauxclicky_stop(); \ } while (0) +// toggle +#define FAUXCLICKY_TOGGLE do { \ + if (fauxclicky_enabled) { \ + FAUXCLICKY_OFF; \ + } else { \ + FAUXCLICKY_ON; \ + } \ +} while (0) + // // pin configuration // diff --git a/quantum/quantum.c b/quantum/quantum.c index 45ea8cb73c..2088c10c95 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -7,6 +7,10 @@ #define TAPPING_TERM 200 #endif +#ifdef FAUXCLICKY_ENABLE +#include "fauxclicky.h" +#endif + static void do_code16 (uint16_t code, void (*f) (uint8_t)) { switch (code) { case QK_MODS ... QK_MODS_MAX: @@ -196,6 +200,26 @@ bool process_record_quantum(keyrecord_t *record) { } return false; break; + #ifdef FAUXCLICKY_ENABLE + case FC_TOG: + if (record->event.pressed) { + FAUXCLICKY_TOGGLE; + } + return false; + break; + case FC_ON: + if (record->event.pressed) { + FAUXCLICKY_ON; + } + return false; + break; + case FC_OFF: + if (record->event.pressed) { + FAUXCLICKY_OFF; + } + return false; + break; + #endif #ifdef RGBLIGHT_ENABLE case RGB_TOG: if (record->event.pressed) { diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index ab2e790269..cc7a5013f6 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -86,6 +86,13 @@ enum quantum_keycodes { AU_OFF, AU_TOG, +#ifdef FAUXCLICKY_ENABLE + // Faux clicky + FC_ON, + FC_OFF, + FC_TOG, +#endif + // Music mode on/off/toggle MU_ON, MU_OFF, -- cgit v1.2.3