diff options
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/config_common.h | 6 | ||||
| -rw-r--r-- | quantum/keymap_common.c | 7 | ||||
| -rwxr-xr-x | quantum/light_ws2812.c | 6 | ||||
| -rw-r--r-- | quantum/matrix.c | 14 | ||||
| -rw-r--r-- | quantum/process_keycode/process_combo.c | 134 | ||||
| -rw-r--r-- | quantum/process_keycode/process_combo.h | 43 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.c | 13 | ||||
| -rw-r--r-- | quantum/quantum.c | 167 | ||||
| -rw-r--r-- | quantum/quantum.h | 5 | ||||
| -rw-r--r-- | quantum/quantum_keycodes.h | 43 | ||||
| -rw-r--r-- | quantum/rgblight.c | 35 | ||||
| -rw-r--r-- | quantum/rgblight.h | 11 | ||||
| -rw-r--r-- | quantum/template/config.h | 2 | 
13 files changed, 421 insertions, 65 deletions
| 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/keymap_common.c b/quantum/keymap_common.c index eced3d2bba..54b872d49e 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); @@ -117,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/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); diff --git a/quantum/matrix.c b/quantum/matrix.c index 07eb87bc36..ac523482ad 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -60,13 +60,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.      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]; -static matrix_row_t matrix_raw[MATRIX_ROWS];  static matrix_row_t matrix_debouncing[MATRIX_ROWS]; @@ -76,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); @@ -133,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); @@ -158,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 @@ -166,7 +167,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;      } @@ -194,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++) { @@ -336,7 +336,7 @@ static void unselect_rows(void)      }  } -#else // ROW2COL +#elif (DIODE_DIRECTION == ROW2COL)  static void init_rows(void)  { diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c new file mode 100644 index 0000000000..e2189ad98b --- /dev/null +++ b/quantum/process_keycode/process_combo.c @@ -0,0 +1,134 @@ +#include "process_combo.h" +#include "print.h" + + +#define COMBO_TIMER_ELAPSED -1 + + +__attribute__ ((weak)) +combo_t key_combos[] = { + +}; + +__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) +{ +    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<<count)-1) == combo->state) +#define NO_COMBO_KEYS_ARE_DOWN      (0 == combo->state) +#define KEY_STATE_DOWN(key)         do{ combo->state |= (1<<key); } while(0) +#define KEY_STATE_UP(key)           do{ combo->state &= ~(1<<key); } while(0) +static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record)  +{ +    uint8_t count = 0; +    uint8_t index = -1; +    /* Find index of keycode and number of combo keys */ +    for (const uint16_t *keys = combo->keys; ;++count) { +        uint16_t key = pgm_read_word(&keys[count]); +        if (keycode == key) index = count; +        if (COMBO_END == key) break; +    } + +    /* Return if not a combo key */ +    if (-1 == (int8_t)index) return false; + +    /* The combos timer is used to signal whether the combo is active */ +    bool is_combo_active = COMBO_TIMER_ELAPSED == combo->timer ? false : true; + +    if (record->event.pressed) { +        KEY_STATE_DOWN(index); + +        if (is_combo_active) { +            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 (ALL_COMBO_KEYS_ARE_DOWN) { /* Combo was released */ +            send_combo(combo->keycode, false); +        } + +        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);         +    } + +    if (NO_COMBO_KEYS_ARE_DOWN) { +        combo->timer = 0; +    } + +    return is_combo_active; +} + +bool process_combo(uint16_t keycode, keyrecord_t *record) +{ +    bool is_combo_key = false; + +    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); +    }     + +    return !is_combo_key; +} + +void matrix_scan_combo(void) +{ +    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; + +#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 +        } +    } +} diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h new file mode 100644 index 0000000000..847f2b7376 --- /dev/null +++ b/quantum/process_keycode/process_combo.h @@ -0,0 +1,43 @@ +#ifndef PROCESS_COMBO_H +#define PROCESS_COMBO_H + +#include <stdint.h> +#include "progmem.h" +#include "quantum.h" + +typedef struct +{ +    const uint16_t *keys; +    uint16_t keycode;         +#ifdef EXTRA_EXTRA_LONG_COMBOS +    uint32_t state; +#elif EXTRA_LONG_COMBOS +    uint16_t state; +#else +    uint8_t state; +#endif +    uint16_t timer; +#ifdef COMBO_ALLOW_ACTION_KEYS +    keyrecord_t prev_record; +#else +    uint16_t prev_key; +#endif +} combo_t; + + +#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 +#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 diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index a30e93ae32..9d01a592d2 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -139,9 +139,18 @@ 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 && 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 { diff --git a/quantum/quantum.c b/quantum/quantum.c index 63ffe2074e..45ea8cb73c 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,4 +1,7 @@  #include "quantum.h" +#ifdef PROTOCOL_LUFA +#include "outputselect.h" +#endif  #ifndef TAPPING_TERM  #define TAPPING_TERM 200 @@ -33,14 +36,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) { +    add_weak_mods(MOD_BIT(kc)); +    send_keyboard_report(); +} + +static inline void qk_unregister_mods(uint8_t kc) { +    del_weak_mods(MOD_BIT(kc)); +    send_keyboard_report(); +} +  void register_code16 (uint16_t code) { -  do_code16 (code, register_code); +  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, unregister_code); +  if (IS_MOD(code) || code == KC_NO) { +      do_code16 (code, qk_unregister_mods); +  } else { +      do_code16 (code, qk_unregister_weak_mods); +  }  }  __attribute__ ((weak)) @@ -130,6 +161,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 @@ -212,6 +246,36 @@ bool process_record_quantum(keyrecord_t *record) {  	  return false;        break;  	#endif +    #ifdef PROTOCOL_LUFA +    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 +    #endif      case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:        if (record->event.pressed) {          // MAGIC actions (BOOTMAGIC without the boot) @@ -508,6 +572,11 @@ void matrix_scan_quantum() {    #ifdef TAP_DANCE_ENABLE      matrix_scan_tap_dance();    #endif + +  #ifdef COMBO_ENABLE +    matrix_scan_combo(); +  #endif +    matrix_scan_kb();  } @@ -525,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 @@ -564,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(); diff --git a/quantum/quantum.h b/quantum/quantum.h index e6adf974ab..18f072189d 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 <stddef.h> @@ -63,6 +62,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); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 4853655f95..ab2e790269 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    = 0x5BFF,  #endif +    QK_MOD_TAP            = 0x6000, +    QK_MOD_TAP_MAX        = 0x7FFF,  #ifdef UNICODE_ENABLE      QK_UNICODE            = 0x8000,      QK_UNICODE_MAX        = 0xFFFF, @@ -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, @@ -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  }; @@ -246,8 +256,10 @@ 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  #define LT(layer, kc) (kc | QK_LAYER_TAP | ((layer & 0xF) << 8)) @@ -286,14 +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) diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 52a09817a1..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; @@ -219,6 +221,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) { @@ -237,7 +247,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 @@ -247,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);  } @@ -350,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; @@ -450,7 +477,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 +631,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..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 @@ -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 @@ -65,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); 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 <http://www.gnu.org/licenses/>.  #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 | 
