diff options
Diffstat (limited to 'quantum')
33 files changed, 1346 insertions, 796 deletions
diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c index 648a37adf3..edda6ea0b6 100644 --- a/quantum/backlight/backlight_avr.c +++ b/quantum/backlight/backlight_avr.c @@ -191,7 +191,7 @@ void backlight_off(pin_t backlight_pin) {  #        define FOR_EACH_LED(x)                                 \              for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \ -                pin_t backlight_pin = backlight_pins[i];      \ +                pin_t backlight_pin = backlight_pins[i];        \                  { x }                                           \              } diff --git a/quantum/config_common.h b/quantum/config_common.h index f42df6357d..c1c1d4bd42 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -303,25 +303,26 @@                  UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \                  sei();                              \              } while (0) -#   elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)) -#      define SERIAL_UART_BAUD 115200 -#      define SERIAL_UART_DATA UDR1 -       /* UBRR should result in ~16 and set UCSR1A = _BV(U2X1) as per rn42 documentation. HC05 needs baudrate configured accordingly */ -#      define SERIAL_UART_UBRR (F_CPU / (8UL * SERIAL_UART_BAUD) - 1) -#      define SERIAL_UART_RXD_VECT USART1_RX_vect -#      define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) -#      define SERIAL_UART_INIT() do {               \ -            UCSR1A = _BV(U2X1);                     \ -            /* baud rate */                         \ -            UBRR1L = SERIAL_UART_UBRR;              \ -            /* baud rate */                         \ -            UBRR1H = SERIAL_UART_UBRR >> 8;         \ -            /* enable TX */                         \ -            UCSR1B = _BV(TXEN1);                    \ -            /* 8-bit data */                        \ -            UCSR1C = _BV(UCSZ11) | _BV(UCSZ10);     \ -            sei();                                  \ -        } while(0) +#    elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)) +#        define SERIAL_UART_BAUD 115200 +#        define SERIAL_UART_DATA UDR1 +/* UBRR should result in ~16 and set UCSR1A = _BV(U2X1) as per rn42 documentation. HC05 needs baudrate configured accordingly */ +#        define SERIAL_UART_UBRR (F_CPU / (8UL * SERIAL_UART_BAUD) - 1) +#        define SERIAL_UART_RXD_VECT USART1_RX_vect +#        define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) +#        define SERIAL_UART_INIT()                  \ +            do {                                    \ +                UCSR1A = _BV(U2X1);                 \ +                /* baud rate */                     \ +                UBRR1L = SERIAL_UART_UBRR;          \ +                /* baud rate */                     \ +                UBRR1H = SERIAL_UART_UBRR >> 8;     \ +                /* enable TX */                     \ +                UCSR1B = _BV(TXEN1);                \ +                /* 8-bit data */                    \ +                UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ +                sei();                              \ +            } while (0)  #    else  #        error "USART configuration is needed."  #    endif diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c index 3b5a8dadc9..ab74222d10 100644 --- a/quantum/dip_switch.c +++ b/quantum/dip_switch.c @@ -21,40 +21,33 @@  // for memcpy  #include <string.h> -  #if !defined(DIP_SWITCH_PINS) -#   error "No DIP switch pads defined by DIP_SWITCH_PINS" +#    error "No DIP switch pads defined by DIP_SWITCH_PINS"  #endif -#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad)/sizeof(pin_t)) -static pin_t dip_switch_pad[] = DIP_SWITCH_PINS; -static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; -static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; - +#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t)) +static pin_t dip_switch_pad[]                              = DIP_SWITCH_PINS; +static bool  dip_switch_state[NUMBER_OF_DIP_SWITCHES]      = {0}; +static bool  last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0}; -__attribute__((weak)) -void dip_switch_update_user(uint8_t index, bool active) {} +__attribute__((weak)) void dip_switch_update_user(uint8_t index, bool active) {} -__attribute__((weak)) -void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); } +__attribute__((weak)) void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); } -__attribute__((weak)) -void dip_switch_update_mask_user(uint32_t state) {} +__attribute__((weak)) void dip_switch_update_mask_user(uint32_t state) {} -__attribute__((weak)) -void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); } +__attribute__((weak)) void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); }  void dip_switch_init(void) { -  for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { -    setPinInputHigh(dip_switch_pad[i]); -  } -  dip_switch_read(true); +    for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { +        setPinInputHigh(dip_switch_pad[i]); +    } +    dip_switch_read(true);  } -  void dip_switch_read(bool forced) { -    bool has_dip_state_changed = false; -    uint32_t dip_switch_mask = 0; +    bool     has_dip_state_changed = false; +    uint32_t dip_switch_mask       = 0;      for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {          dip_switch_state[i] = !readPin(dip_switch_pad[i]); diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h index c7632c004b..fe9de6fa65 100644 --- a/quantum/dynamic_macro.h +++ b/quantum/dynamic_macro.h @@ -15,8 +15,10 @@   */  /* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ -#ifndef DYNAMIC_MACROS_H -#define DYNAMIC_MACROS_H +#pragma once + +/* Warn users that this is now deprecated and they should use the core feature instead. */ +#pragma message "Dynamic Macros is now a core feature. See updated documentation to see how to configure it: https://docs.qmk.fm/#/feature_dynamic_macros"  #include "action_layer.h" @@ -33,18 +35,6 @@  #    define DYNAMIC_MACRO_SIZE 128  #endif -/* DYNAMIC_MACRO_RANGE must be set as the last element of user's - * "planck_keycodes" enum prior to including this header. This allows - * us to 'extend' it. - */ -enum dynamic_macro_keycodes { -    DYN_REC_START1 = DYNAMIC_MACRO_RANGE, -    DYN_REC_START2, -    DYN_REC_STOP, -    DYN_MACRO_PLAY1, -    DYN_MACRO_PLAY2, -}; -  /* Blink the LEDs to notify the user about some event. */  void dynamic_macro_led_blink(void) {  #ifdef BACKLIGHT_ENABLE @@ -272,5 +262,3 @@ bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) {  #undef DYNAMIC_MACRO_CURRENT_SLOT  #undef DYNAMIC_MACRO_CURRENT_LENGTH  #undef DYNAMIC_MACRO_CURRENT_CAPACITY - -#endif diff --git a/quantum/encoder.c b/quantum/encoder.c index 36a6403b36..c41b89f495 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c @@ -38,14 +38,15 @@ static pin_t encoders_pad_b[] = ENCODERS_PAD_B;  static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};  static uint8_t encoder_state[NUMBER_OF_ENCODERS] = {0}; +static int8_t encoder_pulses[NUMBER_OF_ENCODERS] = {0};  #ifdef SPLIT_KEYBOARD  // right half encoders come over as second set of encoders -static int8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0}; +static uint8_t encoder_value[NUMBER_OF_ENCODERS * 2] = {0};  // row offsets for each hand  static uint8_t thisHand, thatHand;  #else -static int8_t encoder_value[NUMBER_OF_ENCODERS] = {0}; +static uint8_t encoder_value[NUMBER_OF_ENCODERS] = {0};  #endif  __attribute__((weak)) void encoder_update_user(int8_t index, bool clockwise) {} @@ -78,34 +79,47 @@ void encoder_init(void) {  }  static void encoder_update(int8_t index, uint8_t state) { -    encoder_value[index] += encoder_LUT[state & 0xF]; -    if (encoder_value[index] >= ENCODER_RESOLUTION) { -        encoder_update_kb(index, false); -    } -    if (encoder_value[index] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise +    uint8_t i = index; +#ifdef SPLIT_KEYBOARD +    index += thisHand; +#endif +    encoder_pulses[i] += encoder_LUT[state & 0xF]; +    if (encoder_pulses[i] >= ENCODER_RESOLUTION) { +        encoder_value[index]++;          encoder_update_kb(index, true);      } -    encoder_value[index] %= ENCODER_RESOLUTION; +    if (encoder_pulses[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise +        encoder_value[index]--; +        encoder_update_kb(index, false); +    } +    encoder_pulses[i] %= ENCODER_RESOLUTION;  }  void encoder_read(void) { -    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { +    for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) {          encoder_state[i] <<= 2;          encoder_state[i] |= (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); -#if SPLIT_KEYBOARD -        encoder_update(i + thisHand, encoder_state[i]); -#else          encoder_update(i, encoder_state[i]); -#endif      }  }  #ifdef SPLIT_KEYBOARD -void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, encoder_state, sizeof(encoder_state)); } +void encoder_state_raw(uint8_t* slave_state) { memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * NUMBER_OF_ENCODERS); }  void encoder_update_raw(uint8_t* slave_state) { -    for (int i = 0; i < NUMBER_OF_ENCODERS; i++) { -        encoder_update(i + thatHand, slave_state[i]); +    for (uint8_t i = 0; i < NUMBER_OF_ENCODERS; i++) { +        uint8_t index = i + thatHand; +        int8_t delta = slave_state[i] - encoder_value[index]; +        while (delta > 0) { +            delta--; +            encoder_value[index]++; +            encoder_update_kb(index, true); +        } +        while (delta < 0) { +            delta++; +            encoder_value[index]--; +            encoder_update_kb(index, false); +        }      }  }  #endif diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 4fa45ac37b..c82c446399 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -48,13 +48,10 @@ action_t action_for_key(uint8_t layer, keypos_t key) {      // keycode remapping      keycode = keycode_config(keycode); -    action_t action; +    action_t action = {};      uint8_t  action_layer, when, mod;      switch (keycode) { -        case KC_FN0 ... KC_FN31: -            action.code = keymap_function_id_to_action(FN_INDEX(keycode)); -            break;          case KC_A ... KC_EXSEL:          case KC_LCTRL ... KC_RGUI:              action.code = ACTION_KEY(keycode); @@ -65,9 +62,11 @@ action_t action_for_key(uint8_t layer, keypos_t key) {          case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN:              action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));              break; +#ifdef MOUSEKEY_ENABLE          case KC_MS_UP ... KC_MS_ACCEL2:              action.code = ACTION_MOUSEKEY(keycode);              break; +#endif          case KC_TRNS:              action.code = ACTION_TRANSPARENT;              break; @@ -76,17 +75,24 @@ action_t action_for_key(uint8_t layer, keypos_t key) {              // Split it up              action.code = ACTION_MODS_KEY(keycode >> 8, keycode & 0xFF);  // adds modifier to key              break; +#ifndef NO_ACTION_FUNCTION +        case KC_FN0 ... KC_FN31: +            action.code = keymap_function_id_to_action(FN_INDEX(keycode)); +            break;          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 = keymap_function_id_to_action((int)keycode & 0xFFF);              break; +#endif +#ifndef NO_ACTION_MACRO          case QK_MACRO ... QK_MACRO_MAX:              if (keycode & 0x800)  // tap macros have upper bit set                  action.code = ACTION_MACRO_TAP(keycode & 0xFF);              else                  action.code = ACTION_MACRO(keycode & 0xFF);              break; +#endif          case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:              action.code = ACTION_LAYER_TAP_KEY((keycode >> 0x8) & 0xF, keycode & 0xFF);              break; diff --git a/quantum/keymap_extras/keymap_italian.h b/quantum/keymap_extras/keymap_italian.h index a8c03b884f..063700aa0b 100644 --- a/quantum/keymap_extras/keymap_italian.h +++ b/quantum/keymap_extras/keymap_italian.h @@ -78,36 +78,36 @@  #define IT_MINS KC_SLSH  // - and _  // shifted characters -#define IT_DEGR LSFT(IT_AACC) // ° -#define IT_EXLM LSFT(KC_1) // ! -#define IT_DQOT LSFT(KC_2) // " -#define IT_STRL LSFT(KC_3) // £ -#define IT_DLR  LSFT(KC_4) // $ -#define IT_PERC LSFT(KC_5) // % -#define IT_AMPR LSFT(KC_6) // & -#define IT_SLSH LSFT(KC_7) // / -#define IT_LPRN LSFT(KC_8) // ( -#define IT_RPRN LSFT(KC_9) // ) -#define IT_EQL  LSFT(KC_0) // = -#define IT_QST  LSFT(IT_APOS) // ? -#define IT_CRC  LSFT(IT_IACC) // ^ -#define IT_ASTR LSFT(IT_PLUS) // * -#define IT_MORE LSFT(IT_LESS) // > -#define IT_COLN LSFT(IT_DOT) // : -#define IT_SCLN LSFT(IT_COMM) // ; -#define IT_UNDS LSFT(IT_MINS) // _ +#define IT_DEGR LSFT(IT_AACC)  // ° +#define IT_EXLM LSFT(KC_1)     // ! +#define IT_DQOT LSFT(KC_2)     // " +#define IT_STRL LSFT(KC_3)     // £ +#define IT_DLR LSFT(KC_4)      // $ +#define IT_PERC LSFT(KC_5)     // % +#define IT_AMPR LSFT(KC_6)     // & +#define IT_SLSH LSFT(KC_7)     // / +#define IT_LPRN LSFT(KC_8)     // ( +#define IT_RPRN LSFT(KC_9)     // ) +#define IT_EQL LSFT(KC_0)      // = +#define IT_QST LSFT(IT_APOS)   // ? +#define IT_CRC LSFT(IT_IACC)   // ^ +#define IT_ASTR LSFT(IT_PLUS)  // * +#define IT_MORE LSFT(IT_LESS)  // > +#define IT_COLN LSFT(IT_DOT)   // : +#define IT_SCLN LSFT(IT_COMM)  // ; +#define IT_UNDS LSFT(IT_MINS)  // _  // Alt Gr-ed characters -#define IT_LCBR ALGR(KC_7) // { -#define IT_LBRC ALGR(IT_EACC) // [ -#define IT_RBRC ALGR(IT_PLUS) // ] -#define IT_RCBR ALGR(KC_0) // } -#define IT_AT   ALGR(IT_OACC) 	// @ -#define IT_EURO ALGR(KC_E) 		// € -#define IT_PIPE LSFT(IT_BSLS) 	// | -#define	IT_SHRP	ALGR(IT_AACC) 	// # +#define IT_LCBR ALGR(KC_7)     // { +#define IT_LBRC ALGR(IT_EACC)  // [ +#define IT_RBRC ALGR(IT_PLUS)  // ] +#define IT_RCBR ALGR(KC_0)     // } +#define IT_AT ALGR(IT_OACC)    // @ +#define IT_EURO ALGR(KC_E)     // € +#define IT_PIPE LSFT(IT_BSLS)  // | +#define IT_SHRP ALGR(IT_AACC)  // #  // Deprecated -#define	IT_X_PLUS	X_RBRACKET 	// # +#define IT_X_PLUS X_RBRACKET  // #  #endif diff --git a/quantum/keymap_extras/keymap_italian_osx_ansi.h b/quantum/keymap_extras/keymap_italian_osx_ansi.h index 2b7160ff33..fa12d05dce 100644 --- a/quantum/keymap_extras/keymap_italian_osx_ansi.h +++ b/quantum/keymap_extras/keymap_italian_osx_ansi.h @@ -65,7 +65,7 @@  #define IT_COMM KC_COMM  // , and  ;  #define IT_APOS KC_MINS  // ' and  ?  #define IT_BSLS KC_NUBS  // \ and  | -#define IT_LESS KC_GRV // < and  > +#define IT_LESS KC_GRV   // < and  >  #define IT_MINS KC_SLSH  // - and  _  // accented vowels (regular, with shift, with option, with option and shift) @@ -77,37 +77,37 @@  #define IT_IACC KC_EQL   // ì, ^, ˆ, ±  // shifted characters -#define IT_EXLM LSFT(KC_1)  // ! -#define IT_DQOT LSFT(KC_2)  // " -#define IT_STRL LSFT(KC_3)  // £ -#define IT_DLR LSFT(KC_4)   // $ -#define IT_PERC LSFT(KC_5)  // % -#define IT_AMPR LSFT(KC_6)  // & -#define IT_SLSH LSFT(KC_7)  // / -#define IT_LPRN LSFT(KC_8)  // ( -#define IT_RPRN LSFT(KC_9)  // ) -#define IT_EQL LSFT(KC_0)   // = -#define IT_DEGR LSFT(IT_AACC) // ° -#define IT_QST LSFT(IT_APOS)  // ? -#define IT_CRC LSFT(IT_IACC)  // ^ -#define IT_ASTR LSFT(IT_PLUS) // * -#define IT_MORE LSFT(IT_LESS) // > -#define IT_COLN LSFT(IT_DOT)  // : -#define IT_SCLN LSFT(IT_COMM) // ; -#define IT_UNDS LSFT(IT_MINS) // _ -#define IT_LCBR LSFT(IT_LBRC) // { -#define IT_RCBR LSFT(IT_RBRC) // } -#define IT_PIPE LSFT(IT_BSLS) // | +#define IT_EXLM LSFT(KC_1)     // ! +#define IT_DQOT LSFT(KC_2)     // " +#define IT_STRL LSFT(KC_3)     // £ +#define IT_DLR LSFT(KC_4)      // $ +#define IT_PERC LSFT(KC_5)     // % +#define IT_AMPR LSFT(KC_6)     // & +#define IT_SLSH LSFT(KC_7)     // / +#define IT_LPRN LSFT(KC_8)     // ( +#define IT_RPRN LSFT(KC_9)     // ) +#define IT_EQL LSFT(KC_0)      // = +#define IT_DEGR LSFT(IT_AACC)  // ° +#define IT_QST LSFT(IT_APOS)   // ? +#define IT_CRC LSFT(IT_IACC)   // ^ +#define IT_ASTR LSFT(IT_PLUS)  // * +#define IT_MORE LSFT(IT_LESS)  // > +#define IT_COLN LSFT(IT_DOT)   // : +#define IT_SCLN LSFT(IT_COMM)  // ; +#define IT_UNDS LSFT(IT_MINS)  // _ +#define IT_LCBR LSFT(IT_LBRC)  // { +#define IT_RCBR LSFT(IT_RBRC)  // } +#define IT_PIPE LSFT(IT_BSLS)  // |  // Alt -ed characters -#define IT_LBRC LALT(IT_EACC)  // [ -#define IT_RBRC LALT(IT_PLUS)  // ] -#define IT_AT LALT(IT_OACC)    // @ -#define IT_EURO LALT(KC_E)     // € -#define IT_SHRP LALT(IT_AACC ) // # -#define IT_ACUT LALT(KC_8)     // ´ -#define IT_GRAVE LALT(KC_9)    // ` -#define IT_TILDE LALT(KC_5)    // ~ +#define IT_LBRC LALT(IT_EACC)        // [ +#define IT_RBRC LALT(IT_PLUS)        // ] +#define IT_AT LALT(IT_OACC)          // @ +#define IT_EURO LALT(KC_E)           // € +#define IT_SHRP LALT(IT_AACC)        // # +#define IT_ACUT LALT(KC_8)           // ´ +#define IT_GRAVE LALT(KC_9)          // ` +#define IT_TILDE LALT(KC_5)          // ~  #define IT_PLMN LALT(LSFT(IT_IACC))  // ±  #endif diff --git a/quantum/keymap_extras/keymap_italian_osx_iso.h b/quantum/keymap_extras/keymap_italian_osx_iso.h index 5c920014a1..a9b36f16e6 100644 --- a/quantum/keymap_extras/keymap_italian_osx_iso.h +++ b/quantum/keymap_extras/keymap_italian_osx_iso.h @@ -65,7 +65,7 @@  #define IT_COMM KC_COMM  // , and  ;  #define IT_APOS KC_MINS  // ' and  ?  #define IT_BSLS KC_GRV   // \ and  | -#define IT_LESS KC_NUBS// < and  > +#define IT_LESS KC_NUBS  // < and  >  #define IT_MINS KC_SLSH  // - and  _  // accented vowels (regular, with shift, with option, with option and shift) @@ -77,37 +77,37 @@  #define IT_IACC KC_EQL   // ì, ^, ˆ, ±  // shifted characters -#define IT_EXLM LSFT(KC_1)  // ! -#define IT_DQOT LSFT(KC_2)  // " -#define IT_STRL LSFT(KC_3)  // £ -#define IT_DLR LSFT(KC_4)   // $ -#define IT_PERC LSFT(KC_5)  // % -#define IT_AMPR LSFT(KC_6)  // & -#define IT_SLSH LSFT(KC_7)  // / -#define IT_LPRN LSFT(KC_8)  // ( -#define IT_RPRN LSFT(KC_9)  // ) -#define IT_EQL LSFT(KC_0)   // = -#define IT_DEGR LSFT(IT_AACC) // ° -#define IT_QST LSFT(IT_APOS)  // ? -#define IT_CRC LSFT(IT_IACC)  // ^ -#define IT_ASTR LSFT(IT_PLUS) // * -#define IT_MORE LSFT(IT_LESS) // > -#define IT_COLN LSFT(IT_DOT)  // : -#define IT_SCLN LSFT(IT_COMM) // ; -#define IT_UNDS LSFT(IT_MINS) // _ -#define IT_LCBR LSFT(IT_LBRC) // { -#define IT_RCBR LSFT(IT_RBRC) // } -#define IT_PIPE LSFT(IT_BSLS) // | +#define IT_EXLM LSFT(KC_1)     // ! +#define IT_DQOT LSFT(KC_2)     // " +#define IT_STRL LSFT(KC_3)     // £ +#define IT_DLR LSFT(KC_4)      // $ +#define IT_PERC LSFT(KC_5)     // % +#define IT_AMPR LSFT(KC_6)     // & +#define IT_SLSH LSFT(KC_7)     // / +#define IT_LPRN LSFT(KC_8)     // ( +#define IT_RPRN LSFT(KC_9)     // ) +#define IT_EQL LSFT(KC_0)      // = +#define IT_DEGR LSFT(IT_AACC)  // ° +#define IT_QST LSFT(IT_APOS)   // ? +#define IT_CRC LSFT(IT_IACC)   // ^ +#define IT_ASTR LSFT(IT_PLUS)  // * +#define IT_MORE LSFT(IT_LESS)  // > +#define IT_COLN LSFT(IT_DOT)   // : +#define IT_SCLN LSFT(IT_COMM)  // ; +#define IT_UNDS LSFT(IT_MINS)  // _ +#define IT_LCBR LSFT(IT_LBRC)  // { +#define IT_RCBR LSFT(IT_RBRC)  // } +#define IT_PIPE LSFT(IT_BSLS)  // |  // Alt -ed characters -#define IT_LBRC LALT(IT_EACC)  // [ -#define IT_RBRC LALT(IT_PLUS)  // ] -#define IT_AT LALT(IT_OACC)    // @ -#define IT_EURO LALT(KC_E)     // € -#define IT_SHRP LALT(IT_AACC ) // # -#define IT_ACUT LALT(KC_8)     // ´ -#define IT_GRAVE LALT(KC_9)    // ` -#define IT_TILDE LALT(KC_5)    // ~ +#define IT_LBRC LALT(IT_EACC)        // [ +#define IT_RBRC LALT(IT_PLUS)        // ] +#define IT_AT LALT(IT_OACC)          // @ +#define IT_EURO LALT(KC_E)           // € +#define IT_SHRP LALT(IT_AACC)        // # +#define IT_ACUT LALT(KC_8)           // ´ +#define IT_GRAVE LALT(KC_9)          // ` +#define IT_TILDE LALT(KC_5)          // ~  #define IT_PLMN LALT(LSFT(IT_IACC))  // ±  #endif diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk index 5102010c7b..24b2b2abd9 100644 --- a/quantum/mcu_selection.mk +++ b/quantum/mcu_selection.mk @@ -7,15 +7,15 @@ ifneq ($(findstring STM32F303, $(MCU)),)    # Linker script to use    # - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/ -  #   or <this_dir>/ld/ +  #   or <keyboard_dir>/ld/    MCU_LDSCRIPT ?= STM32F303xC    # Startup code to use    #  - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/    MCU_STARTUP ?= stm32f3xx -  # Board: it should exist either in <chibios>/os/hal/boards/ -  #  or <this_dir>/boards +  # Board: it should exist either in <chibios>/os/hal/boards/, +  # <keyboard_dir>/boards/, or drivers/boards/    BOARD ?= GENERIC_STM32_F303XC    # Cortex version @@ -27,7 +27,7 @@ ifneq ($(findstring STM32F303, $(MCU)),)    USE_FPU = yes    # Vector table for application -  # 0x00000000-0x00001000 area is occupied by bootlaoder.*/ +  # 0x00000000-0x00001000 area is occupied by bootloader.*/    # The CORTEX_VTOR... is needed only for MCHCK/Infinity KB    # OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000 @@ -75,6 +75,9 @@ ifneq (,$(filter $(MCU),atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 a  endif  ifneq (,$(filter $(MCU),atmega32a)) +  # MCU name for avrdude +  AVRDUDE_MCU = m32 +    PROTOCOL = VUSB    # Processor frequency. @@ -87,12 +90,12 @@ ifneq (,$(filter $(MCU),atmega32a))    # unsupported features for now    NO_UART ?= yes    NO_SUSPEND_POWER_DOWN ?= yes - -  # Programming options -  PROGRAM_CMD ?= ./util/atmega32a_program.py $(TARGET).hex  endif  ifneq (,$(filter $(MCU),atmega328p)) +  # MCU name for avrdude +  AVRDUDE_MCU = m328p +    PROTOCOL = VUSB    # Processor frequency. diff --git a/quantum/process_keycode/process_dynamic_macro.c b/quantum/process_keycode/process_dynamic_macro.c new file mode 100644 index 0000000000..2065f242db --- /dev/null +++ b/quantum/process_keycode/process_dynamic_macro.c @@ -0,0 +1,257 @@ +/* Copyright 2016 Jack Humbert + * Copyright 2019 Drashna Jael're (@drashna, aka Christopher Courtney) + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ +#include "process_dynamic_macro.h" + +// default feedback method +void dynamic_macro_led_blink(void) { +#ifdef BACKLIGHT_ENABLE +    backlight_toggle(); +    wait_ms(100); +    backlight_toggle(); +#endif +} + +/* User hooks for Dynamic Macros */ + +__attribute__((weak)) void dynamic_macro_record_start_user(void) { dynamic_macro_led_blink(); } + +__attribute__((weak)) void dynamic_macro_play_user(int8_t direction) { dynamic_macro_led_blink(); } + +__attribute__((weak)) void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record) { dynamic_macro_led_blink(); } + +__attribute__((weak)) void dynamic_macro_record_end_user(int8_t direction) { dynamic_macro_led_blink(); } + +/* Convenience macros used for retrieving the debug info. All of them + * need a `direction` variable accessible at the call site. + */ +#define DYNAMIC_MACRO_CURRENT_SLOT() (direction > 0 ? 1 : 2) +#define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) ((int)(direction * ((POINTER) - (BEGIN)))) +#define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) ((int)(direction * ((END2) - (BEGIN)) + 1)) + +/** + * Start recording of the dynamic macro. + * + * @param[out] macro_pointer The new macro buffer iterator. + * @param[in]  macro_buffer  The macro buffer used to initialize macro_pointer. + */ +void dynamic_macro_record_start(keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) { +    dprintln("dynamic macro recording: started"); + +    dynamic_macro_record_start_user(); + +    clear_keyboard(); +    layer_clear(); +    *macro_pointer = macro_buffer; +} + +/** + * Play the dynamic macro. + * + * @param macro_buffer[in] The beginning of the macro buffer being played. + * @param macro_end[in]    The element after the last macro buffer element. + * @param direction[in]    Either +1 or -1, which way to iterate the buffer. + */ +void dynamic_macro_play(keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) { +    dprintf("dynamic macro: slot %d playback\n", DYNAMIC_MACRO_CURRENT_SLOT()); + +    layer_state_t saved_layer_state = layer_state; + +    clear_keyboard(); +    layer_clear(); + +    while (macro_buffer != macro_end) { +        process_record(macro_buffer); +        macro_buffer += direction; +    } + +    clear_keyboard(); + +    layer_state = saved_layer_state; + +    dynamic_macro_play_user(direction); +} + +/** + * Record a single key in a dynamic macro. + * + * @param macro_buffer[in] The start of the used macro buffer. + * @param macro_pointer[in,out] The current buffer position. + * @param macro2_end[in] The end of the other macro. + * @param direction[in]  Either +1 or -1, which way to iterate the buffer. + * @param record[in]     The current keypress. + */ +void dynamic_macro_record_key(keyrecord_t *macro_buffer, keyrecord_t **macro_pointer, keyrecord_t *macro2_end, int8_t direction, keyrecord_t *record) { +    /* If we've just started recording, ignore all the key releases. */ +    if (!record->event.pressed && *macro_pointer == macro_buffer) { +        dprintln("dynamic macro: ignoring a leading key-up event"); +        return; +    } + +    /* The other end of the other macro is the last buffer element it +     * is safe to use before overwriting the other macro. +     */ +    if (*macro_pointer - direction != macro2_end) { +        **macro_pointer = *record; +        *macro_pointer += direction; +    } else { +        dynamic_macro_record_key_user(direction, record); +    } + +    dprintf("dynamic macro: slot %d length: %d/%d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, *macro_pointer), DYNAMIC_MACRO_CURRENT_CAPACITY(macro_buffer, macro2_end)); +} + +/** + * End recording of the dynamic macro. Essentially just update the + * pointer to the end of the macro. + */ +void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_pointer, int8_t direction, keyrecord_t **macro_end) { +    dynamic_macro_record_end_user(direction); + +    /* Do not save the keys being held when stopping the recording, +     * i.e. the keys used to access the layer DYN_REC_STOP is on. +     */ +    while (macro_pointer != macro_buffer && (macro_pointer - direction)->event.pressed) { +        dprintln("dynamic macro: trimming a trailing key-down event"); +        macro_pointer -= direction; +    } + +    dprintf("dynamic macro: slot %d saved, length: %d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer)); + +    *macro_end = macro_pointer; +} + +/* Handle the key events related to the dynamic macros. Should be + * called from process_record_user() like this: + * + *   bool process_record_user(uint16_t keycode, keyrecord_t *record) { + *       if (!process_record_dynamic_macro(keycode, record)) { + *           return false; + *       } + *       <...THE REST OF THE FUNCTION...> + *   } + */ +bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record) { +    /* Both macros use the same buffer but read/write on different +     * ends of it. +     * +     * Macro1 is written left-to-right starting from the beginning of +     * the buffer. +     * +     * Macro2 is written right-to-left starting from the end of the +     * buffer. +     * +     * ¯o_buffer   macro_end +     *  v                   v +     * +------------------------------------------------------------+ +     * |>>>>>> MACRO1 >>>>>>      <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| +     * +------------------------------------------------------------+ +     *                           ^                                 ^ +     *                         r_macro_end                  r_macro_buffer +     * +     * During the recording when one macro encounters the end of the +     * other macro, the recording is stopped. Apart from this, there +     * are no arbitrary limits for the macros' length in relation to +     * each other: for example one can either have two medium sized +     * macros or one long macro and one short macro. Or even one empty +     * and one using the whole buffer. +     */ +    static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; + +    /* Pointer to the first buffer element after the first macro. +     * Initially points to the very beginning of the buffer since the +     * macro is empty. */ +    static keyrecord_t *macro_end = macro_buffer; + +    /* The other end of the macro buffer. Serves as the beginning of +     * the second macro. */ +    static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; + +    /* Like macro_end but for the second macro. */ +    static keyrecord_t *r_macro_end = r_macro_buffer; + +    /* A persistent pointer to the current macro position (iterator) +     * used during the recording. */ +    static keyrecord_t *macro_pointer = NULL; + +    /* 0   - no macro is being recorded right now +     * 1,2 - either macro 1 or 2 is being recorded */ +    static uint8_t macro_id = 0; + +    if (macro_id == 0) { +        /* No macro recording in progress. */ +        if (!record->event.pressed) { +            switch (keycode) { +                case DYN_REC_START1: +                    dynamic_macro_record_start(¯o_pointer, macro_buffer); +                    macro_id = 1; +                    return false; +                case DYN_REC_START2: +                    dynamic_macro_record_start(¯o_pointer, r_macro_buffer); +                    macro_id = 2; +                    return false; +                case DYN_MACRO_PLAY1: +                    dynamic_macro_play(macro_buffer, macro_end, +1); +                    return false; +                case DYN_MACRO_PLAY2: +                    dynamic_macro_play(r_macro_buffer, r_macro_end, -1); +                    return false; +            } +        } +    } else { +        /* A macro is being recorded right now. */ +        switch (keycode) { +            case DYN_REC_STOP: +                /* Stop the macro recording. */ +                if (record->event.pressed) { /* Ignore the initial release +                                              * just after the recoding +                                              * starts. */ +                    switch (macro_id) { +                        case 1: +                            dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); +                            break; +                        case 2: +                            dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); +                            break; +                    } +                    macro_id = 0; +                } +                return false; +#ifdef DYNAMIC_MACRO_NO_NESTING +            case DYN_MACRO_PLAY1: +            case DYN_MACRO_PLAY2: +                dprintln("dynamic macro: ignoring macro play key while recording"); +                return false; +#endif +            default: +                /* Store the key in the macro buffer and process it normally. */ +                switch (macro_id) { +                    case 1: +                        dynamic_macro_record_key(macro_buffer, ¯o_pointer, r_macro_end, +1, record); +                        break; +                    case 2: +                        dynamic_macro_record_key(r_macro_buffer, ¯o_pointer, macro_end, -1, record); +                        break; +                } +                return true; +                break; +        } +    } + +    return true; +} diff --git a/quantum/process_keycode/process_dynamic_macro.h b/quantum/process_keycode/process_dynamic_macro.h new file mode 100644 index 0000000000..39036541b8 --- /dev/null +++ b/quantum/process_keycode/process_dynamic_macro.h @@ -0,0 +1,41 @@ +/* Copyright 2016 Jack Humbert + * Copyright 2019 Drashna Jael're (@drashna, aka Christopher Courtney) + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ +#pragma once + +#include "quantum.h" + +/* May be overridden with a custom value. Be aware that the effective + * macro length is half of this value: each keypress is recorded twice + * because of the down-event and up-event. This is not a bug, it's the + * intended behavior. + * + * Usually it should be fine to set the macro size to at least 256 but + * there have been reports of it being too much in some users' cases, + * so 128 is considered a safe default. + */ +#ifndef DYNAMIC_MACRO_SIZE +#    define DYNAMIC_MACRO_SIZE 128 +#endif + +void dynamic_macro_led_blink(void); +bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record); +void dynamic_macro_record_start_user(void); +void dynamic_macro_play_user(int8_t direction); +void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record); +void dynamic_macro_record_end_user(int8_t direction); diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c new file mode 100644 index 0000000000..44dd5f0579 --- /dev/null +++ b/quantum/process_keycode/process_magic.c @@ -0,0 +1,178 @@ +/* Copyright 2019 Jack Humbert + * + * 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 <http://www.gnu.org/licenses/>. + */ +#include "process_magic.h" + +#ifdef AUDIO_ENABLE +#    ifndef AG_NORM_SONG +#        define AG_NORM_SONG SONG(AG_NORM_SOUND) +#    endif +#    ifndef AG_SWAP_SONG +#        define AG_SWAP_SONG SONG(AG_SWAP_SOUND) +#    endif +#    ifndef CG_NORM_SONG +#        define CG_NORM_SONG SONG(AG_NORM_SOUND) +#    endif +#    ifndef CG_SWAP_SONG +#        define CG_SWAP_SONG SONG(AG_SWAP_SOUND) +#    endif +float ag_norm_song[][2] = AG_NORM_SONG; +float ag_swap_song[][2] = AG_SWAP_SONG; +float cg_norm_song[][2] = CG_NORM_SONG; +float cg_swap_song[][2] = CG_SWAP_SONG; +#endif + +/** + * MAGIC actions (BOOTMAGIC without the boot) + */ +bool process_magic(uint16_t keycode, keyrecord_t *record) { +    // skip anything that isn't a keyup +    if (record->event.pressed) { +        switch (keycode) { +            case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI: +            case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT: +                /* keymap config */ +                keymap_config.raw = eeconfig_read_keymap(); +                switch (keycode) { +                    case MAGIC_SWAP_CONTROL_CAPSLOCK: +                        keymap_config.swap_control_capslock = true; +                        break; +                    case MAGIC_CAPSLOCK_TO_CONTROL: +                        keymap_config.capslock_to_control = true; +                        break; +                    case MAGIC_SWAP_LALT_LGUI: +                        keymap_config.swap_lalt_lgui = true; +                        break; +                    case MAGIC_SWAP_RALT_RGUI: +                        keymap_config.swap_ralt_rgui = true; +                        break; +                    case MAGIC_SWAP_LCTL_LGUI: +                        keymap_config.swap_lctl_lgui = true; +                        break; +                    case MAGIC_SWAP_RCTL_RGUI: +                        keymap_config.swap_rctl_rgui = true; +                        break; +                    case MAGIC_NO_GUI: +                        keymap_config.no_gui = true; +                        break; +                    case MAGIC_SWAP_GRAVE_ESC: +                        keymap_config.swap_grave_esc = true; +                        break; +                    case MAGIC_SWAP_BACKSLASH_BACKSPACE: +                        keymap_config.swap_backslash_backspace = true; +                        break; +                    case MAGIC_HOST_NKRO: +                        clear_keyboard();  // clear first buffer to prevent stuck keys +                        keymap_config.nkro = true; +                        break; +                    case MAGIC_SWAP_ALT_GUI: +                        keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true; +#ifdef AUDIO_ENABLE +                        PLAY_SONG(ag_swap_song); +#endif +                        break; +                    case MAGIC_SWAP_CTL_GUI: +                        keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true; +#ifdef AUDIO_ENABLE +                        PLAY_SONG(cg_swap_song); +#endif +                        break; +                    case MAGIC_UNSWAP_CONTROL_CAPSLOCK: +                        keymap_config.swap_control_capslock = false; +                        break; +                    case MAGIC_UNCAPSLOCK_TO_CONTROL: +                        keymap_config.capslock_to_control = false; +                        break; +                    case MAGIC_UNSWAP_LALT_LGUI: +                        keymap_config.swap_lalt_lgui = false; +                        break; +                    case MAGIC_UNSWAP_RALT_RGUI: +                        keymap_config.swap_ralt_rgui = false; +                        break; +                    case MAGIC_UNSWAP_LCTL_LGUI: +                        keymap_config.swap_lctl_lgui = false; +                        break; +                    case MAGIC_UNSWAP_RCTL_RGUI: +                        keymap_config.swap_rctl_rgui = false; +                        break; +                    case MAGIC_UNNO_GUI: +                        keymap_config.no_gui = false; +                        break; +                    case MAGIC_UNSWAP_GRAVE_ESC: +                        keymap_config.swap_grave_esc = false; +                        break; +                    case MAGIC_UNSWAP_BACKSLASH_BACKSPACE: +                        keymap_config.swap_backslash_backspace = false; +                        break; +                    case MAGIC_UNHOST_NKRO: +                        clear_keyboard();  // clear first buffer to prevent stuck keys +                        keymap_config.nkro = false; +                        break; +                    case MAGIC_UNSWAP_ALT_GUI: +                        keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false; +#ifdef AUDIO_ENABLE +                        PLAY_SONG(ag_norm_song); +#endif +                        break; +                    case MAGIC_UNSWAP_CTL_GUI: +                        keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false; +#ifdef AUDIO_ENABLE +                        PLAY_SONG(cg_norm_song); +#endif +                        break; +                    case MAGIC_TOGGLE_ALT_GUI: +                        keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; +                        keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui; +#ifdef AUDIO_ENABLE +                        if (keymap_config.swap_ralt_rgui) { +                            PLAY_SONG(ag_swap_song); +                        } else { +                            PLAY_SONG(ag_norm_song); +                        } +#endif +                        break; +                    case MAGIC_TOGGLE_CTL_GUI: +                        keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui; +                        keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui; +#ifdef AUDIO_ENABLE +                        if (keymap_config.swap_rctl_rgui) { +                            PLAY_SONG(cg_swap_song); +                        } else { +                            PLAY_SONG(cg_norm_song); +                        } +#endif +                        break; +                    case MAGIC_TOGGLE_NKRO: +                        clear_keyboard();  // clear first buffer to prevent stuck keys +                        keymap_config.nkro = !keymap_config.nkro; +                        break; +                    case MAGIC_EE_HANDS_LEFT: +                        eeconfig_update_handedness(true); +                        break; +                    case MAGIC_EE_HANDS_RIGHT: +                        eeconfig_update_handedness(false); +                        break; +                } + +                eeconfig_update_keymap(keymap_config.raw); +                clear_keyboard();  // clear to prevent stuck keys + +                return false; +        } +    } + +    // Not a magic keycode so continue processing +    return true; +} diff --git a/quantum/process_keycode/process_magic.h b/quantum/process_keycode/process_magic.h new file mode 100644 index 0000000000..1eb39f1455 --- /dev/null +++ b/quantum/process_keycode/process_magic.h @@ -0,0 +1,20 @@ +/* Copyright 2019 + * + * 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 <http://www.gnu.org/licenses/>. + */ +#pragma once + +#include "quantum.h" + +bool process_magic(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index 8f3f3ff3c6..09ceef74d8 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -63,10 +63,10 @@ typedef struct {          { .fn = {qk_tap_dance_pair_on_each_tap, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset}, .user_data = (void *)&((qk_tap_dance_pair_t){kc1, kc2}), }  #    define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) \ -        { .fn = { qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer, layer_move }),  } +        { .fn = {qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset}, .user_data = (void *)&((qk_tap_dance_dual_role_t){kc, layer, layer_move}), }  #    define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer) \ -        { .fn = { NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer, layer_invert }), } +        { .fn = {NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset}, .user_data = (void *)&((qk_tap_dance_dual_role_t){kc, layer, layer_invert}), }  #    define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) @@ -79,8 +79,6 @@ typedef struct {  #    define ACTION_TAP_DANCE_FN_ADVANCED_TIME(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset, tap_specific_tapping_term) \          { .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset}, .user_data = NULL, .custom_tapping_term = tap_specific_tapping_term, } - -  extern qk_tap_dance_action_t tap_dance_actions[];  /* To be used internally */ diff --git a/quantum/process_keycode/process_terminal.c b/quantum/process_keycode/process_terminal.c index f48f3d702d..7d1eefa9ed 100644 --- a/quantum/process_keycode/process_terminal.c +++ b/quantum/process_keycode/process_terminal.c @@ -61,7 +61,7 @@ void enable_terminal(void) {      memset(cmd_buffer, 0, CMD_BUFF_SIZE * 80);      for (int i = 0; i < 6; i++) strcpy(arguments[i], "");      // select all text to start over -    // SEND_STRING(SS_LCTRL("a")); +    // SEND_STRING(SS_LCTL("a"));      send_string(terminal_prompt);  } diff --git a/quantum/quantum.c b/quantum/quantum.c index 571dda4c5b..2def99ac84 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -26,7 +26,7 @@  #ifdef BACKLIGHT_ENABLE  #    include "backlight.h" -    extern backlight_config_t backlight_config; +extern backlight_config_t backlight_config;  #endif  #ifdef FAUXCLICKY_ENABLE @@ -57,23 +57,7 @@  #    ifndef GOODBYE_SONG  #        define GOODBYE_SONG SONG(GOODBYE_SOUND)  #    endif -#    ifndef AG_NORM_SONG -#        define AG_NORM_SONG SONG(AG_NORM_SOUND) -#    endif -#    ifndef AG_SWAP_SONG -#        define AG_SWAP_SONG SONG(AG_SWAP_SOUND) -#    endif -#    ifndef CG_NORM_SONG -#        define CG_NORM_SONG SONG(AG_NORM_SOUND) -#    endif -#    ifndef CG_SWAP_SONG -#        define CG_SWAP_SONG SONG(AG_SWAP_SOUND) -#    endif  float goodbye_song[][2] = GOODBYE_SONG; -float ag_norm_song[][2] = AG_NORM_SONG; -float ag_swap_song[][2] = AG_SWAP_SONG; -float cg_norm_song[][2] = CG_NORM_SONG; -float cg_swap_song[][2] = CG_SWAP_SONG;  #    ifdef DEFAULT_LAYER_SONGS  float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;  #    endif @@ -89,7 +73,7 @@ static void do_code16(uint16_t code, void (*f)(uint8_t)) {      uint8_t mods_to_send = 0; -    if (code & QK_RMODS_MIN) { // Right mod flag is set +    if (code & QK_RMODS_MIN) {  // Right mod flag is set          if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL);          if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT);          if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT); @@ -164,11 +148,6 @@ void reset_keyboard(void) {      bootloader_jump();  } -/* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise. - * Used to ensure that the correct keycode is released if the key is released. - */ -static bool grave_esc_was_shifted = false; -  /* Convert record into usable keycode via the contained event. */  uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); } @@ -222,6 +201,10 @@ bool process_record_quantum(keyrecord_t *record) {              // Must run first to be able to mask key_up events.              process_key_lock(&keycode, record) &&  #endif +#if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL) +            // Must run asap to ensure all keypresses are recorded. +            process_dynamic_macro(keycode, record) && +#endif  #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)              process_clicky(keycode, record) &&  #endif  // AUDIO_CLICKY @@ -268,402 +251,226 @@ bool process_record_quantum(keyrecord_t *record) {  #ifdef SPACE_CADET_ENABLE              process_space_cadet(keycode, record) &&  #endif +#ifdef MAGIC_KEYCODE_ENABLE +            process_magic(keycode, record) && +#endif              true)) {          return false;      } -    // Shift / paren setup - -    switch (keycode) { -        case RESET: -            if (record->event.pressed) { +    if (record->event.pressed) { +        switch (keycode) { +            case RESET:                  reset_keyboard(); -            } -            return false; -        case DEBUG: -            if (record->event.pressed) { +                return false; +#ifndef NO_DEBUG +            case DEBUG:                  debug_enable ^= 1;                  if (debug_enable) {                      print("DEBUG: enabled.\n");                  } else {                      print("DEBUG: disabled.\n");                  } -            } -            return false; -        case EEPROM_RESET: -            if (record->event.pressed) { +#endif +                return false; +            case EEPROM_RESET:                  eeconfig_init(); -            } -            return false; +                return false;  #ifdef FAUXCLICKY_ENABLE -        case FC_TOG: -            if (record->event.pressed) { +            case FC_TOG:                  FAUXCLICKY_TOGGLE; -            } -            return false; -        case FC_ON: -            if (record->event.pressed) { +                return false; +            case FC_ON:                  FAUXCLICKY_ON; -            } -            return false; -        case FC_OFF: -            if (record->event.pressed) { +                return false; +            case FC_OFF:                  FAUXCLICKY_OFF; -            } -            return false; +                return false; +#endif +#ifdef VELOCIKEY_ENABLE +            case VLK_TOG: +                velocikey_toggle(); +                return false; +#endif +#ifdef BLUETOOTH_ENABLE +        case OUT_AUTO: +                set_output(OUTPUT_AUTO); +                return false; +        case OUT_USB: +                set_output(OUTPUT_USB); +                return false; +        case OUT_BT: +                set_output(OUTPUT_BLUETOOTH); +                return false; +#endif +#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING) +        case BL_BRTG: +                backlight_toggle_breathing(); +                return false;  #endif +        } +    } +  #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) -        case RGB_TOG: -// Split keyboards need to trigger on key-up for edge-case issue  #    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { +    if (record->event.pressed) {  #    else -            if (!record->event.pressed) { +    // Split keyboards need to trigger on key-up for edge-case issue +    if (!record->event.pressed) {  #    endif +        uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)); +        switch (keycode) { +            case RGB_TOG:                  rgblight_toggle(); -            } -            return false; -        case RGB_MODE_FORWARD: -            if (record->event.pressed) { -                uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)); +                return false; +            case RGB_MODE_FORWARD:                  if (shifted) {                      rgblight_step_reverse();                  } else {                      rgblight_step();                  } -            } -            return false; -        case RGB_MODE_REVERSE: -            if (record->event.pressed) { -                uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)); +                return false; +            case RGB_MODE_REVERSE:                  if (shifted) {                      rgblight_step();                  } else {                      rgblight_step_reverse();                  } -            } -            return false; -        case RGB_HUI: -// Split keyboards need to trigger on key-up for edge-case issue -#    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { -#    else -            if (!record->event.pressed) { -#    endif -                rgblight_increase_hue(); -            } -            return false; -        case RGB_HUD: -// Split keyboards need to trigger on key-up for edge-case issue -#    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { -#    else -            if (!record->event.pressed) { -#    endif -                rgblight_decrease_hue(); -            } -            return false; -        case RGB_SAI: -// Split keyboards need to trigger on key-up for edge-case issue -#    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { -#    else -            if (!record->event.pressed) { -#    endif -                rgblight_increase_sat(); -            } -            return false; -        case RGB_SAD: -// Split keyboards need to trigger on key-up for edge-case issue -#    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { -#    else -            if (!record->event.pressed) { -#    endif -                rgblight_decrease_sat(); -            } -            return false; -        case RGB_VAI: -// Split keyboards need to trigger on key-up for edge-case issue -#    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { -#    else -            if (!record->event.pressed) { -#    endif -                rgblight_increase_val(); -            } -            return false; -        case RGB_VAD: -// Split keyboards need to trigger on key-up for edge-case issue -#    ifndef SPLIT_KEYBOARD -            if (record->event.pressed) { -#    else -            if (!record->event.pressed) { -#    endif -                rgblight_decrease_val(); -            } -            return false; -        case RGB_SPI: -            if (record->event.pressed) { -                rgblight_increase_speed(); -            } -            return false; -        case RGB_SPD: -            if (record->event.pressed) { -                rgblight_decrease_speed(); -            } -            return false; -        case RGB_MODE_PLAIN: -            if (record->event.pressed) { +                return false; +            case RGB_HUI: +                if (shifted) { +                    rgblight_decrease_hue(); +                } else { +                    rgblight_increase_hue(); +                } +                return false; +            case RGB_HUD: +                if (shifted) { +                    rgblight_increase_hue(); +                } else { +                    rgblight_decrease_hue(); +                } +                return false; +            case RGB_SAI: +                if (shifted) { +                    rgblight_decrease_sat(); +                } else { +                    rgblight_increase_sat(); +                } +                return false; +            case RGB_SAD: +                if (shifted) { +                    rgblight_increase_sat(); +                } else { +                    rgblight_decrease_sat(); +                } +                return false; +            case RGB_VAI: +                if (shifted) { +                    rgblight_decrease_val(); +                } else { +                    rgblight_increase_val(); +                } +                return false; +            case RGB_VAD: +                if (shifted) { +                    rgblight_increase_val(); +                } else { +                    rgblight_decrease_val(); +                } +                return false; +            case RGB_SPI: +                if (shifted) { +                    rgblight_decrease_speed(); +                } else { +                    rgblight_increase_speed(); +                } +                return false; +            case RGB_SPD: +                if (shifted) { +                    rgblight_increase_speed(); +                } else { +                    rgblight_decrease_speed(); +                } +                return false; +            case RGB_MODE_PLAIN:                  rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); -            } -            return false; -        case RGB_MODE_BREATHE: +                return false; +            case RGB_MODE_BREATHE:  #    ifdef RGBLIGHT_EFFECT_BREATHING -            if (record->event.pressed) {                  if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {                      rgblight_step();                  } else {                      rgblight_mode(RGBLIGHT_MODE_BREATHING);                  } -            }  #    endif -            return false; +                return false;          case RGB_MODE_RAINBOW:  #    ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD -            if (record->event.pressed) {                  if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {                      rgblight_step();                  } else {                      rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);                  } -            }  #    endif -            return false; -        case RGB_MODE_SWIRL: +            case RGB_MODE_SWIRL:  #    ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL -            if (record->event.pressed) {                  if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {                      rgblight_step();                  } else {                      rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);                  } -            }  #    endif -            return false; -        case RGB_MODE_SNAKE: +                return false; +            case RGB_MODE_SNAKE:  #    ifdef RGBLIGHT_EFFECT_SNAKE -            if (record->event.pressed) {                  if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {                      rgblight_step();                  } else {                      rgblight_mode(RGBLIGHT_MODE_SNAKE);                  } -            }  #    endif -            return false; -        case RGB_MODE_KNIGHT: +                return false; +            case RGB_MODE_KNIGHT:  #    ifdef RGBLIGHT_EFFECT_KNIGHT -            if (record->event.pressed) {                  if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {                      rgblight_step();                  } else {                      rgblight_mode(RGBLIGHT_MODE_KNIGHT);                  } -            }  #    endif -            return false; -        case RGB_MODE_XMAS: +                return false; +            case RGB_MODE_XMAS:  #    ifdef RGBLIGHT_EFFECT_CHRISTMAS -            if (record->event.pressed) {                  rgblight_mode(RGBLIGHT_MODE_CHRISTMAS); -            }  #    endif -            return false; -        case RGB_MODE_GRADIENT: +                return false; +            case RGB_MODE_GRADIENT:  #    ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT -            if (record->event.pressed) {                  if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {                      rgblight_step();                  } else {                      rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);                  } -            }  #    endif -            return false; -        case RGB_MODE_RGBTEST: +                return false; +            case RGB_MODE_RGBTEST:  #    ifdef RGBLIGHT_EFFECT_RGB_TEST -            if (record->event.pressed) {                  rgblight_mode(RGBLIGHT_MODE_RGB_TEST); -            } -#    endif -            return false; -#endif  // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) -#ifdef VELOCIKEY_ENABLE -        case VLK_TOG: -            if (record->event.pressed) { -                velocikey_toggle(); -            } -            return false; -#endif -#ifdef PROTOCOL_LUFA -        case OUT_AUTO: -            if (record->event.pressed) { -                set_output(OUTPUT_AUTO); -            } -            return false; -        case OUT_USB: -            if (record->event.pressed) { -                set_output(OUTPUT_USB); -            } -            return false; -#    ifdef BLUETOOTH_ENABLE -        case OUT_BT: -            if (record->event.pressed) { -                set_output(OUTPUT_BLUETOOTH); -            } -            return false;  #    endif -#endif -        case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI: -        case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT: -            if (record->event.pressed) { -                // MAGIC actions (BOOTMAGIC without the boot) -                if (!eeconfig_is_enabled()) { -                    eeconfig_init(); -                } -                /* keymap config */ -                keymap_config.raw = eeconfig_read_keymap(); -                switch (keycode) { -                    case MAGIC_SWAP_CONTROL_CAPSLOCK: -                        keymap_config.swap_control_capslock = true; -                        break; -                    case MAGIC_CAPSLOCK_TO_CONTROL: -                        keymap_config.capslock_to_control = true; -                        break; -                    case MAGIC_SWAP_LALT_LGUI: -                        keymap_config.swap_lalt_lgui = true; -                        break; -                    case MAGIC_SWAP_RALT_RGUI: -                        keymap_config.swap_ralt_rgui = true; -                        break; -                    case MAGIC_SWAP_LCTL_LGUI: -                        keymap_config.swap_lctl_lgui = true; -                        break; -                    case MAGIC_SWAP_RCTL_RGUI: -                        keymap_config.swap_rctl_rgui = true; -                        break; -                    case MAGIC_NO_GUI: -                        keymap_config.no_gui = true; -                        break; -                    case MAGIC_SWAP_GRAVE_ESC: -                        keymap_config.swap_grave_esc = true; -                        break; -                    case MAGIC_SWAP_BACKSLASH_BACKSPACE: -                        keymap_config.swap_backslash_backspace = true; -                        break; -                    case MAGIC_HOST_NKRO: -                        clear_keyboard(); // clear first buffer to prevent stuck keys -                        keymap_config.nkro = true; -                        break; -                    case MAGIC_SWAP_ALT_GUI: -                        keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true; -#ifdef AUDIO_ENABLE -                        PLAY_SONG(ag_swap_song); -#endif -                        break; -                    case MAGIC_SWAP_CTL_GUI: -                        keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true; -#ifdef AUDIO_ENABLE -                        PLAY_SONG(cg_swap_song); -#endif -                        break; -                    case MAGIC_UNSWAP_CONTROL_CAPSLOCK: -                        keymap_config.swap_control_capslock = false; -                        break; -                    case MAGIC_UNCAPSLOCK_TO_CONTROL: -                        keymap_config.capslock_to_control = false; -                        break; -                    case MAGIC_UNSWAP_LALT_LGUI: -                        keymap_config.swap_lalt_lgui = false; -                        break; -                    case MAGIC_UNSWAP_RALT_RGUI: -                        keymap_config.swap_ralt_rgui = false; -                        break; -                    case MAGIC_UNSWAP_LCTL_LGUI: -                        keymap_config.swap_lctl_lgui = false; -                        break; -                    case MAGIC_UNSWAP_RCTL_RGUI: -                        keymap_config.swap_rctl_rgui = false; -                        break; -                    case MAGIC_UNNO_GUI: -                        keymap_config.no_gui = false; -                        break; -                    case MAGIC_UNSWAP_GRAVE_ESC: -                        keymap_config.swap_grave_esc = false; -                        break; -                    case MAGIC_UNSWAP_BACKSLASH_BACKSPACE: -                        keymap_config.swap_backslash_backspace = false; -                        break; -                    case MAGIC_UNHOST_NKRO: -                        clear_keyboard(); // clear first buffer to prevent stuck keys -                        keymap_config.nkro = false; -                        break; -                    case MAGIC_UNSWAP_ALT_GUI: -                        keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false; -#ifdef AUDIO_ENABLE -                        PLAY_SONG(ag_norm_song); -#endif -                        break; -                    case MAGIC_UNSWAP_CTL_GUI: -                        keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false; -#ifdef AUDIO_ENABLE -                        PLAY_SONG(cg_norm_song); -#endif -                        break; -                    case MAGIC_TOGGLE_ALT_GUI: -                        keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; -                        keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui; -#ifdef AUDIO_ENABLE -                        if (keymap_config.swap_ralt_rgui) { -                            PLAY_SONG(ag_swap_song); -                        } else { -                            PLAY_SONG(ag_norm_song); -                        } -#endif -                        break; -                    case MAGIC_TOGGLE_CTL_GUI: -                        keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui; -                        keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui; -#ifdef AUDIO_ENABLE -                        if (keymap_config.swap_rctl_rgui) { -                            PLAY_SONG(cg_swap_song); -                        } else { -                            PLAY_SONG(cg_norm_song); -                        } -#endif -                        break; -                    case MAGIC_TOGGLE_NKRO: -                        clear_keyboard(); // clear first buffer to prevent stuck keys -                        keymap_config.nkro = !keymap_config.nkro; -                        break; -                    case MAGIC_EE_HANDS_LEFT: -                        eeconfig_update_handedness(true); -                        break; -                    case MAGIC_EE_HANDS_RIGHT: -                        eeconfig_update_handedness(false); -                        break; -                    default: -                        break; -                } -                eeconfig_update_keymap(keymap_config.raw); -                clear_keyboard();  // clear to prevent stuck keys -                  return false; -            } -            break; +        } +    } +#endif +    // keycodes that depend on both pressed and non-pressed state +    switch (keycode) {          case GRAVE_ESC: { +            /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise. +            * Used to ensure that the correct keycode is released if the key is released. +            */ +            static bool grave_esc_was_shifted = false; +              uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)));  #ifdef GRAVE_ESC_ALT_OVERRIDE @@ -707,14 +514,6 @@ bool process_record_quantum(keyrecord_t *record) {              return false;          } -#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING) -        case BL_BRTG: { -            if (record->event.pressed) { -                backlight_toggle_breathing(); -            } -            return false; -        } -#endif      }      return process_action_kb(record); @@ -1066,10 +865,30 @@ void api_send_unicode(uint32_t unicode) {  #endif  } +/** \brief Lock LED set callback - keymap/user level + * + * \deprecated Use led_update_user() instead. + */  __attribute__((weak)) void led_set_user(uint8_t usb_led) {} +/** \brief Lock LED set callback - keyboard level + * + * \deprecated Use led_update_kb() instead. + */  __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } +/** \brief Lock LED update callback - keymap/user level + * + * \return True if led_update_kb() should run its own code, false otherwise. + */ +__attribute__((weak)) bool led_update_user(led_t led_state) { return true; } + +/** \brief Lock LED update callback - keyboard level + * + * \return Ignored for now. + */ +__attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); } +  __attribute__((weak)) void led_init_ports(void) {}  __attribute__((weak)) void led_set(uint8_t usb_led) { @@ -1092,6 +911,7 @@ __attribute__((weak)) void led_set(uint8_t usb_led) {  #endif      led_set_kb(usb_led); +    led_update_kb((led_t)usb_led);  }  //------------------------------------------------------------------------------ diff --git a/quantum/quantum.h b/quantum/quantum.h index 01abe1c0a1..2ee261e60d 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -133,6 +133,10 @@ extern layer_state_t layer_state;  #    include "process_space_cadet.h"  #endif +#ifdef MAGIC_KEYCODE_ENABLE +#    include "process_magic.h" +#endif +  #ifdef HD44780_ENABLE  #    include "hd44780.h"  #endif @@ -146,9 +150,12 @@ extern layer_state_t layer_state;  #endif  #ifdef DIP_SWITCH_ENABLE -    #include "dip_switch.h" +#    include "dip_switch.h"  #endif +#ifdef DYNAMIC_MACRO_ENABLE +#    include "process_dynamic_macro.h" +#endif  // Function substitutions to ease GPIO manipulation  #if defined(__AVR__) @@ -179,30 +186,8 @@ typedef ioline_t pin_t;  #    define readPin(pin) palReadLine(pin)  #endif -// Send string macros -#define STRINGIZE(z) #z -#define ADD_SLASH_X(y) STRINGIZE(\x##y) -#define SYMBOL_STR(x) ADD_SLASH_X(x) - -#define SS_TAP_CODE 1 -#define SS_DOWN_CODE 2 -#define SS_UP_CODE 3 - -#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode) -#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode) -#define SS_UP(keycode) "\3" SYMBOL_STR(keycode) - -// `string` arguments must not be parenthesized -#define SS_LCTRL(string) SS_DOWN(X_LCTRL) string SS_UP(X_LCTRL) -#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI) -#define SS_LCMD(string) SS_LGUI(string) -#define SS_LWIN(string) SS_LGUI(string) -#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT) -#define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT) -#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT) -#define SS_ALGR(string) SS_RALT(string) -  #define SEND_STRING(string) send_string_P(PSTR(string)) +#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)  extern const bool    ascii_to_shift_lut[128];  extern const bool    ascii_to_altgr_lut[128]; @@ -285,5 +270,7 @@ uint16_t hex_to_keycode(uint8_t hex);  void led_set_user(uint8_t usb_led);  void led_set_kb(uint8_t usb_led); +bool led_update_user(led_t led_state); +bool led_update_kb(led_t led_state);  void api_send_unicode(uint32_t unicode); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 5fac6a5cae..c8d0e354b0 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -505,6 +505,13 @@ enum quantum_keycodes {      MAGIC_EE_HANDS_LEFT,      MAGIC_EE_HANDS_RIGHT, +    // Dynamic Macros +    DYN_REC_START1, +    DYN_REC_START2, +    DYN_REC_STOP, +    DYN_MACRO_PLAY1, +    DYN_MACRO_PLAY2, +      // always leave at the end      SAFE_RANGE  }; @@ -648,14 +655,43 @@ enum quantum_keycodes {  // L-ayer, T-ap - 256 keycode max, 16 layer max  #define LT(layer, kc) (QK_LAYER_TAP | (((layer)&0xF) << 8) | ((kc)&0xFF)) -#define AG_SWAP MAGIC_SWAP_ALT_GUI -#define AG_NORM MAGIC_UNSWAP_ALT_GUI -#define AG_TOGG MAGIC_TOGGLE_ALT_GUI +#define CL_SWAP MAGIC_SWAP_CONTROL_CAPSLOCK +#define CL_NORM MAGIC_UNSWAP_CONTROL_CAPSLOCK +#define CL_CTRL MAGIC_CAPSLOCK_TO_CONTROL +#define CL_CAPS MAGIC_UNCAPSLOCK_TO_CONTROL +#define LCG_SWP MAGIC_SWAP_LCTL_LGUI +#define LCG_NRM MAGIC_UNSWAP_LCTL_LGUI +#define RCG_SWP MAGIC_SWAP_RCTL_RGUI +#define RCG_NRM MAGIC_UNSWAP_RCTL_RGUI  #define CG_SWAP MAGIC_SWAP_CTL_GUI  #define CG_NORM MAGIC_UNSWAP_CTL_GUI  #define CG_TOGG MAGIC_TOGGLE_CTL_GUI +#define LAG_SWP MAGIC_SWAP_LALT_LGUI +#define LAG_NRM MAGIC_UNSWAP_LALT_LGUI +#define RAG_SWP MAGIC_SWAP_RALT_RGUI +#define RAG_NRM MAGIC_UNSWAP_RALT_RGUI +#define AG_SWAP MAGIC_SWAP_ALT_GUI +#define AG_NORM MAGIC_UNSWAP_ALT_GUI +#define AG_TOGG MAGIC_TOGGLE_ALT_GUI + +#define GUI_OFF MAGIC_NO_GUI +#define GUI_ON  MAGIC_UNNO_GUI + +#define GE_SWAP MAGIC_SWAP_GRAVE_ESC +#define GE_NORM MAGIC_UNSWAP_GRAVE_ESC + +#define BS_SWAP MAGIC_SWAP_BACKSLASH_BACKSPACE +#define BS_NORM MAGIC_UNSWAP_BACKSLASH_BACKSPACE + +#define NK_ON   MAGIC_HOST_NKRO +#define NK_OFF  MAGIC_UNHOST_NKRO +#define NK_TOGG MAGIC_TOGGLE_NKRO + +#define EH_LEFT MAGIC_EE_HANDS_LEFT +#define EH_RGHT MAGIC_EE_HANDS_RIGHT +  // GOTO layer - 16 layers max  // when:  // ON_PRESS    = 1 @@ -757,4 +793,11 @@ enum quantum_keycodes {  #    define SH_OFF (QK_SWAP_HANDS | OP_SH_OFF)  #endif +// Dynamic Macros aliases +#define DM_REC1 DYN_REC_START1 +#define DM_REC2 DYN_REC_START2 +#define DM_RSTP DYN_REC_STOP +#define DM_PLY1 DYN_MACRO_PLAY1 +#define DM_PLY2 DYN_MACRO_PLAY2 +  #endif  // QUANTUM_KEYCODES_H diff --git a/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h b/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h index 4f69456c3a..1cd4ed2acf 100644 --- a/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h +++ b/quantum/rgb_matrix_animations/rainbow_pinwheels_anim.h @@ -1,13 +1,13 @@  #ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS -RGB_MATRIX_EFFECT(PINWHEELS) +RGB_MATRIX_EFFECT(RAINBOW_PINWHEELS)  #    ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS -static HSV PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { +static HSV RAINBOW_PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) {      hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 3 * cos + (56 - abs8(g_led_config.point[i].x - k_rgb_matrix_center.x)) * 3 * sin) / 128;      return hsv;  } -bool PINWHEELS(effect_params_t* params) { return effect_runner_sin_cos_i(params, &PINWHEELS_math); } +bool RAINBOW_PINWHEELS(effect_params_t* params) { return effect_runner_sin_cos_i(params, &RAINBOW_PINWHEELS_math); }  #    endif  // RGB_MATRIX_CUSTOM_EFFECT_IMPLS  #endif      // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index 503f97014f..9729a3064e 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -112,6 +112,9 @@ static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {      led[i].r = r;      led[i].g = g;      led[i].b = b; +#    ifdef RGBW +    led[i].w = 0; +#    endif  }  static void setled_all(uint8_t r, uint8_t g, uint8_t b) { diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 1c197827f2..7949bb688e 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -126,6 +126,9 @@ void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {      (*led1).r = r;      (*led1).g = g;      (*led1).b = b; +#ifdef RGBW +    (*led1).w = 0; +#endif  }  void rgblight_check_config(void) { @@ -186,7 +189,6 @@ void rgblight_init(void) {          return;      } -    debug_enable = 1;  // Debug ON!      dprintf("rgblight_init called.\n");      dprintf("rgblight_init start!\n");      if (!eeconfig_is_enabled()) { @@ -514,6 +516,9 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {          led[i].r = r;          led[i].g = g;          led[i].b = b; +#ifdef RGBW +        led[i].w = 0; +#endif      }      rgblight_set();  } @@ -526,6 +531,9 @@ void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {      led[index].r = r;      led[index].g = g;      led[index].b = b; +#ifdef RGBW +    led[index].w = 0; +#endif      rgblight_set();  } @@ -560,6 +568,9 @@ void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8          led[i].r = r;          led[i].g = g;          led[i].b = b; +#ifdef RGBW +        led[i].w = 0; +#endif      }      rgblight_set();      wait_ms(1); @@ -595,6 +606,9 @@ void rgblight_set(void) {              led[i].r = 0;              led[i].g = 0;              led[i].b = 0; +#    ifdef RGBW +            led[i].w = 0; +#    endif          }      }  #    ifdef RGBLIGHT_LED_MAP @@ -606,11 +620,7 @@ void rgblight_set(void) {  #    else      start_led = led + clipping_start_pos;  #    endif -#    ifdef RGBW -    ws2812_setleds_rgbw(start_led, num_leds); -#    else      ws2812_setleds(start_led, num_leds); -#    endif  }  #endif @@ -908,6 +918,9 @@ void rgblight_effect_snake(animation_status_t *anim) {          ledp->r        = 0;          ledp->g        = 0;          ledp->b        = 0; +#    ifdef RGBW +        ledp->w = 0; +#    endif          for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {              k = pos + j * increment;              if (k > RGBLED_NUM) { @@ -965,6 +978,9 @@ void rgblight_effect_knight(animation_status_t *anim) {          led[i].r = 0;          led[i].g = 0;          led[i].b = 0; +#    ifdef RGBW +        led[i].w = 0; +#    endif      }      // Determine which LEDs should be lit up      for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { @@ -976,6 +992,9 @@ void rgblight_effect_knight(animation_status_t *anim) {              led[cur].r = 0;              led[cur].g = 0;              led[cur].b = 0; +#    ifdef RGBW +            led[cur].w = 0; +#    endif          }      }      rgblight_set(); diff --git a/quantum/send_string_keycodes.h b/quantum/send_string_keycodes.h index e71790a1dc..fc6467a741 100644 --- a/quantum/send_string_keycodes.h +++ b/quantum/send_string_keycodes.h @@ -1,207 +1,374 @@ -#ifndef SEND_STRING_KEYCODES -#define SEND_STRING_KEYCODES - -#define X_NO 00 -#define X_ROLL_OVER 01 -#define X_POST_FAIL 02 -#define X_UNDEFINED 03 -#define X_A 04 -#define X_B 05 -#define X_C 06 -#define X_D 07 -#define X_E 08 -#define X_F 09 -#define X_G 0a -#define X_H 0b -#define X_I 0c -#define X_J 0d -#define X_K 0e -#define X_L 0f -#define X_M 10 -#define X_N 11 -#define X_O 12 -#define X_P 13 -#define X_Q 14 -#define X_R 15 -#define X_S 16 -#define X_T 17 -#define X_U 18 -#define X_V 19 -#define X_W 1a -#define X_X 1b -#define X_Y 1c -#define X_Z 1d -#define X_1 1e -#define X_2 1f -#define X_3 20 -#define X_4 21 -#define X_5 22 -#define X_6 23 -#define X_7 24 -#define X_8 25 -#define X_9 26 -#define X_0 27 -#define X_ENTER 28 -#define X_ESCAPE 29 -#define X_BSPACE 2a -#define X_TAB 2b -#define X_SPACE 2c -#define X_MINUS 2d -#define X_EQUAL 2e -#define X_LBRACKET 2f -#define X_RBRACKET 30 -#define X_BSLASH 31 -#define X_NONUS_HASH 32 -#define X_SCOLON 33 -#define X_QUOTE 34 -#define X_GRAVE 35 -#define X_COMMA 36 -#define X_DOT 37 -#define X_SLASH 38 -#define X_CAPSLOCK 39 -#define X_F1 3a -#define X_F2 3b -#define X_F3 3c -#define X_F4 3d -#define X_F5 3e -#define X_F6 3f -#define X_F7 40 -#define X_F8 41 -#define X_F9 42 -#define X_F10 43 -#define X_F11 44 -#define X_F12 45 -#define X_PSCREEN 46 -#define X_SCROLLLOCK 47 -#define X_PAUSE 48 -#define X_INSERT 49 -#define X_HOME 4a -#define X_PGUP 4b -#define X_DELETE 4c -#define X_END 4d -#define X_PGDOWN 4e -#define X_RIGHT 4f -#define X_LEFT 50 -#define X_DOWN 51 -#define X_UP 52 -#define X_NUMLOCK 53 -#define X_KP_SLASH 54 -#define X_KP_ASTERISK 55 -#define X_KP_MINUS 56 -#define X_KP_PLUS 57 -#define X_KP_ENTER 58 -#define X_KP_1 59 -#define X_KP_2 5a -#define X_KP_3 5b -#define X_KP_4 5c -#define X_KP_5 5d -#define X_KP_6 5e -#define X_KP_7 5f -#define X_KP_8 60 -#define X_KP_9 61 -#define X_KP_0 62 -#define X_KP_DOT 63 -#define X_NONUS_BSLASH 64 -#define X_APPLICATION 65 -#define X_POWER 66 -#define X_KP_EQUAL 67 -#define X_F13 68 -#define X_F14 69 -#define X_F15 6a -#define X_F16 6b -#define X_F17 6c -#define X_F18 6d -#define X_F19 6e -#define X_F20 6f -#define X_F21 70 -#define X_F22 71 -#define X_F23 72 -#define X_F24 73 -#define X_EXECUTE 74 -#define X_HELP 75 -#define X_MENU 76 -#define X_SELECT 77 -#define X_STOP 78 -#define X_AGAIN 79 -#define X_UNDO 7a -#define X_CUT 7b -#define X_COPY 7c -#define X_PASTE 7d -#define X_FIND 7e -#define X__MUTE 7f -#define X__VOLUP 80 -#define X__VOLDOWN 81 -#define X_LOCKING_CAPS 82 -#define X_LOCKING_NUM 83 -#define X_LOCKING_SCROLL 84 -#define X_KP_COMMA 85 -#define X_KP_EQUAL_AS400 86 -#define X_INT1 87 -#define X_INT2 88 -#define X_INT3 89 -#define X_INT4 8a -#define X_INT5 8b -#define X_INT6 8c -#define X_INT7 8d -#define X_INT8 8e -#define X_INT9 8f -#define X_LANG1 90 -#define X_LANG2 91 -#define X_LANG3 92 -#define X_LANG4 93 -#define X_LANG5 94 -#define X_LANG6 95 -#define X_LANG7 96 -#define X_LANG8 97 -#define X_LANG9 98 -#define X_ALT_ERASE 99 -#define X_SYSREQ 9a -#define X_CANCEL 9b -#define X_CLEAR 9c -#define X_PRIOR 9d -#define X_RETURN 9e -#define X_SEPARATOR 9f -#define X_OUT a0 -#define X_OPER a1 -#define X_CLEAR_AGAIN a2 -#define X_CRSEL a3 -#define X_EXSEL a4 +/* Copyright 2019 + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#pragma once + +// clang-format off + +/* Punctuation */ +#define X_ENT  X_ENTER +#define X_ESC  X_ESCAPE +#define X_BSPC X_BSPACE +#define X_SPC  X_SPACE +#define X_MINS X_MINUS +#define X_EQL  X_EQUAL +#define X_LBRC X_LBRACKET +#define X_RBRC X_RBRACKET +#define X_BSLS X_BSLASH +#define X_NUHS X_NONUS_HASH +#define X_SCLN X_SCOLON +#define X_QUOT X_QUOTE +#define X_GRV  X_GRAVE +#define X_COMM X_COMMA +#define X_SLSH X_SLASH +#define X_NUBS X_NONUS_BSLASH + +/* Lock Keys */ +#define X_CLCK X_CAPSLOCK +#define X_CAPS X_CAPSLOCK +#define X_SLCK X_SCROLLLOCK +#define X_NLCK X_NUMLOCK +#define X_LCAP X_LOCKING_CAPS +#define X_LNUM X_LOCKING_NUM +#define X_LSCR X_LOCKING_SCROLL + +/* Commands */ +#define X_PSCR X_PSCREEN +#define X_PAUS X_PAUSE +#define X_BRK  X_PAUSE +#define X_INS  X_INSERT +#define X_DEL  X_DELETE +#define X_PGDN X_PGDOWN +#define X_RGHT X_RIGHT +#define X_APP  X_APPLICATION +#define X_EXEC X_EXECUTE +#define X_SLCT X_SELECT +#define X_AGIN X_AGAIN +#define X_PSTE X_PASTE +#define X_ERAS X_ALT_ERASE +#define X_CLR  X_CLEAR + +/* Keypad */ +#define X_PSLS X_KP_SLASH +#define X_PAST X_KP_ASTERISK +#define X_PMNS X_KP_MINUS +#define X_PPLS X_KP_PLUS +#define X_PENT X_KP_ENTER +#define X_P1   X_KP_1 +#define X_P2   X_KP_2 +#define X_P3   X_KP_3 +#define X_P4   X_KP_4 +#define X_P5   X_KP_5 +#define X_P6   X_KP_6 +#define X_P7   X_KP_7 +#define X_P8   X_KP_8 +#define X_P9   X_KP_9 +#define X_P0   X_KP_0 +#define X_PDOT X_KP_DOT +#define X_PEQL X_KP_EQUAL +#define X_PCMM X_KP_COMMA + +/* Japanese specific */ +#define X_ZKHK X_GRAVE +#define X_RO   X_INT1 +#define X_KANA X_INT2 +#define X_JYEN X_INT3 +#define X_HENK X_INT4 +#define X_MHEN X_INT5 + +/* Korean specific */ +#define X_HAEN X_LANG1 +#define X_HANJ X_LANG2 + +/* Modifiers */ +#define X_LCTL X_LCTRL +#define X_LSFT X_LSHIFT +#define X_LCMD X_LGUI +#define X_LWIN X_LGUI +#define X_RCTL X_RCTRL +#define X_RSFT X_RSHIFT +#define X_ALGR X_RALT +#define X_RCMD X_RGUI +#define X_RWIN X_RGUI + +/* Generic Desktop Page (0x01) */ +#define X_PWR  X_SYSTEM_POWER +#define X_SLEP X_SYSTEM_SLEEP +#define X_WAKE X_SYSTEM_WAKE + +/* Consumer Page (0x0C) */ +#define X_MUTE X_AUDIO_MUTE +#define X_VOLU X_AUDIO_VOL_UP +#define X_VOLD X_AUDIO_VOL_DOWN +#define X_MNXT X_MEDIA_NEXT_TRACK +#define X_MPRV X_MEDIA_PREV_TRACK +#define X_MSTP X_MEDIA_STOP +#define X_MPLY X_MEDIA_PLAY_PAUSE +#define X_MSEL X_MEDIA_SELECT +#define X_EJCT X_MEDIA_EJECT +#define X_CALC X_CALCULATOR +#define X_MYCM X_MY_COMPUTER +#define X_WSCH X_WWW_SEARCH +#define X_WHOM X_WWW_HOME +#define X_WBAK X_WWW_BACK +#define X_WFWD X_WWW_FORWARD +#define X_WSTP X_WWW_STOP +#define X_WREF X_WWW_REFRESH +#define X_WFAV X_WWW_FAVORITES +#define X_MFFD X_MEDIA_FAST_FORWARD +#define X_MRWD X_MEDIA_REWIND +#define X_BRIU X_BRIGHTNESS_UP +#define X_BRID X_BRIGHTNESS_DOWN + +/* System Specific */ +#define X_BRMU X_PAUSE +#define X_BRMD X_SCROLLLOCK + +/* Keyboard/Keypad Page (0x07) */ +#define X_A                  04 +#define X_B                  05 +#define X_C                  06 +#define X_D                  07 +#define X_E                  08 +#define X_F                  09 +#define X_G                  0a +#define X_H                  0b +#define X_I                  0c +#define X_J                  0d +#define X_K                  0e +#define X_L                  0f +#define X_M                  10 +#define X_N                  11 +#define X_O                  12 +#define X_P                  13 +#define X_Q                  14 +#define X_R                  15 +#define X_S                  16 +#define X_T                  17 +#define X_U                  18 +#define X_V                  19 +#define X_W                  1a +#define X_X                  1b +#define X_Y                  1c +#define X_Z                  1d +#define X_1                  1e +#define X_2                  1f +#define X_3                  20 +#define X_4                  21 +#define X_5                  22 +#define X_6                  23 +#define X_7                  24 +#define X_8                  25 +#define X_9                  26 +#define X_0                  27 +#define X_ENTER              28 +#define X_ESCAPE             29 +#define X_BSPACE             2a +#define X_TAB                2b +#define X_SPACE              2c +#define X_MINUS              2d +#define X_EQUAL              2e +#define X_LBRACKET           2f +#define X_RBRACKET           30 +#define X_BSLASH             31 +#define X_NONUS_HASH         32 +#define X_SCOLON             33 +#define X_QUOTE              34 +#define X_GRAVE              35 +#define X_COMMA              36 +#define X_DOT                37 +#define X_SLASH              38 +#define X_CAPSLOCK           39 +#define X_F1                 3a +#define X_F2                 3b +#define X_F3                 3c +#define X_F4                 3d +#define X_F5                 3e +#define X_F6                 3f +#define X_F7                 40 +#define X_F8                 41 +#define X_F9                 42 +#define X_F10                43 +#define X_F11                44 +#define X_F12                45 +#define X_PSCREEN            46 +#define X_SCROLLLOCK         47 +#define X_PAUSE              48 +#define X_INSERT             49 +#define X_HOME               4a +#define X_PGUP               4b +#define X_DELETE             4c +#define X_END                4d +#define X_PGDOWN             4e +#define X_RIGHT              4f +#define X_LEFT               50 +#define X_DOWN               51 +#define X_UP                 52 +#define X_NUMLOCK            53 +#define X_KP_SLASH           54 +#define X_KP_ASTERISK        55 +#define X_KP_MINUS           56 +#define X_KP_PLUS            57 +#define X_KP_ENTER           58 +#define X_KP_1               59 +#define X_KP_2               5a +#define X_KP_3               5b +#define X_KP_4               5c +#define X_KP_5               5d +#define X_KP_6               5e +#define X_KP_7               5f +#define X_KP_8               60 +#define X_KP_9               61 +#define X_KP_0               62 +#define X_KP_DOT             63 +#define X_NONUS_BSLASH       64 +#define X_APPLICATION        65 +#define X_POWER              66 +#define X_KP_EQUAL           67 +#define X_F13                68 +#define X_F14                69 +#define X_F15                6a +#define X_F16                6b +#define X_F17                6c +#define X_F18                6d +#define X_F19                6e +#define X_F20                6f +#define X_F21                70 +#define X_F22                71 +#define X_F23                72 +#define X_F24                73 +#define X_EXECUTE            74 +#define X_HELP               75 +#define X_MENU               76 +#define X_SELECT             77 +#define X_STOP               78 +#define X_AGAIN              79 +#define X_UNDO               7a +#define X_CUT                7b +#define X_COPY               7c +#define X_PASTE              7d +#define X_FIND               7e +#define X__MUTE              7f +#define X__VOLUP             80 +#define X__VOLDOWN           81 +#define X_LOCKING_CAPS       82 +#define X_LOCKING_NUM        83 +#define X_LOCKING_SCROLL     84 +#define X_KP_COMMA           85 +#define X_KP_EQUAL_AS400     86 +#define X_INT1               87 +#define X_INT2               88 +#define X_INT3               89 +#define X_INT4               8a +#define X_INT5               8b +#define X_INT6               8c +#define X_INT7               8d +#define X_INT8               8e +#define X_INT9               8f +#define X_LANG1              90 +#define X_LANG2              91 +#define X_LANG3              92 +#define X_LANG4              93 +#define X_LANG5              94 +#define X_LANG6              95 +#define X_LANG7              96 +#define X_LANG8              97 +#define X_LANG9              98 +#define X_ALT_ERASE          99 +#define X_SYSREQ             9a +#define X_CANCEL             9b +#define X_CLEAR              9c +#define X_PRIOR              9d +#define X_RETURN             9e +#define X_SEPARATOR          9f +#define X_OUT                a0 +#define X_OPER               a1 +#define X_CLEAR_AGAIN        a2 +#define X_CRSEL              a3 +#define X_EXSEL              a4  /* Modifiers */ -#define X_LCTRL e0 -#define X_LSHIFT e1 -#define X_LALT e2 -#define X_LGUI e3 -#define X_RCTRL e4 -#define X_RSHIFT e5 -#define X_RALT e6 -#define X_RGUI e7 - -/* System Control */ -#define X_SYSTEM_POWER a5 -#define X_SYSTEM_SLEEP a6 -#define X_SYSTEM_WAKE a7 - -/* Media Control */ -#define X_AUDIO_MUTE a8 -#define X_AUDIO_VOL_UP a9 -#define X_AUDIO_VOL_DOWN aa -#define X_MEDIA_NEXT_TRACK ab -#define X_MEDIA_PREV_TRACK ac -#define X_MEDIA_STOP ad -#define X_MEDIA_PLAY_PAUSE ae -#define X_MEDIA_SELECT af -#define X_MEDIA_EJECT b0 -#define X_MAIL b1 -#define X_CALCULATOR b2 -#define X_MY_COMPUTER b3 -#define X_WWW_SEARCH b4 -#define X_WWW_HOME b5 -#define X_WWW_BACK b6 -#define X_WWW_FORWARD b7 -#define X_WWW_STOP b8 -#define X_WWW_REFRESH b9 -#define X_WWW_FAVORITES ba +#define X_LCTRL              e0 +#define X_LSHIFT             e1 +#define X_LALT               e2 +#define X_LGUI               e3 +#define X_RCTRL              e4 +#define X_RSHIFT             e5 +#define X_RALT               e6 +#define X_RGUI               e7 + +/* Media and Function keys */ +/* Generic Desktop Page (0x01) */ +#define X_SYSTEM_POWER       a5 +#define X_SYSTEM_SLEEP       a6 +#define X_SYSTEM_WAKE        a7 + +/* Consumer Page (0x0C) */ +#define X_AUDIO_MUTE         a8 +#define X_AUDIO_VOL_UP       a9 +#define X_AUDIO_VOL_DOWN     aa +#define X_MEDIA_NEXT_TRACK   ab +#define X_MEDIA_PREV_TRACK   ac +#define X_MEDIA_STOP         ad +#define X_MEDIA_PLAY_PAUSE   ae +#define X_MEDIA_SELECT       af +#define X_MEDIA_EJECT        b0 +#define X_MAIL               b1 +#define X_CALCULATOR         b2 +#define X_MY_COMPUTER        b3 +#define X_WWW_SEARCH         b4 +#define X_WWW_HOME           b5 +#define X_WWW_BACK           b6 +#define X_WWW_FORWARD        b7 +#define X_WWW_STOP           b8 +#define X_WWW_REFRESH        b9 +#define X_WWW_FAVORITES      ba  #define X_MEDIA_FAST_FORWARD bb -#define X_MEDIA_REWIND bc -#endif +#define X_MEDIA_REWIND       bc +#define X_BRIGHTNESS_UP      bd +#define X_BRIGHTNESS_DOWN    be + +// Send string macros +#define STRINGIZE(z) #z +#define ADD_SLASH_X(y) STRINGIZE(\x##y) +#define SYMBOL_STR(x) ADD_SLASH_X(x) + +#define SS_TAP_CODE 1 +#define SS_DOWN_CODE 2 +#define SS_UP_CODE 3 + +#define SS_TAP(keycode) "\1" SYMBOL_STR(keycode) +#define SS_DOWN(keycode) "\2" SYMBOL_STR(keycode) +#define SS_UP(keycode) "\3" SYMBOL_STR(keycode) + +// `string` arguments must not be parenthesized +#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL) +#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT) +#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT) +#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI) +#define SS_LCMD(string) SS_LGUI(string) +#define SS_LWIN(string) SS_LGUI(string) + +#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL) +#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT) +#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT) +#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI) +#define SS_ALGR(string) SS_RALT(string) +#define SS_RCMD(string) SS_RGUI(string) +#define SS_RWIN(string) SS_RGUI(string) + +// DEPRECATED +#define SS_LCTRL(string) SS_LCTL(string) diff --git a/quantum/split_common/post_config.h b/quantum/split_common/post_config.h index 5c0b414fb3..4ae1d52732 100644 --- a/quantum/split_common/post_config.h +++ b/quantum/split_common/post_config.h @@ -1,4 +1,4 @@ -#if defined(USE_I2C) || defined(EH) +#if defined(USE_I2C)  // When using I2C, using rgblight implicitly involves split support.  #    if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT)  #        define RGBLIGHT_SPLIT diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 5c548de059..076f186649 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -33,9 +33,11 @@ bool waitForUsb(void) {          wait_ms(100);      } -#if defined(__AVR__)      // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow +#if defined(__AVR__)      (USBCON &= ~(_BV(USBE) | _BV(OTGPADE))); +#else +    usbStop(&USBD1);  #endif      return false; @@ -76,7 +78,7 @@ __attribute__((weak)) bool is_keyboard_master(void) {  }  static void keyboard_master_setup(void) { -#if defined(USE_I2C) || defined(EH) +#if defined(USE_I2C)  #    ifdef SSD1306OLED      matrix_master_OLED_init();  #    endif diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 3c783dc568..ab421adc4a 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -21,7 +21,7 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A;  #    define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t))  #endif -#if defined(USE_I2C) || defined(EH) +#if defined(USE_I2C)  #    include "i2c_master.h"  #    include "i2c_slave.h" diff --git a/quantum/stm32/chconf.h b/quantum/stm32/chconf.h index f7b1b077d3..6b691950a6 100644 --- a/quantum/stm32/chconf.h +++ b/quantum/stm32/chconf.h @@ -419,34 +419,39 @@   * @note    It is invoked from within @p chThdInit() and implicitly from all   *          the threads creation APIs.   */ -#    define CH_CFG_THREAD_INIT_HOOK(tp) \ -        { /* Add threads initialization code here.*/ } +#    define CH_CFG_THREAD_INIT_HOOK(tp)              \ +        { /* Add threads initialization code here.*/ \ +        }  /**   * @brief   Threads finalization hook.   * @details User finalization code added to the @p chThdExit() API.   */ -#    define CH_CFG_THREAD_EXIT_HOOK(tp) \ -        { /* Add threads finalization code here.*/ } +#    define CH_CFG_THREAD_EXIT_HOOK(tp)            \ +        { /* Add threads finalization code here.*/ \ +        }  /**   * @brief   Context switch hook.   * @details This hook is invoked just before switching between threads.   */  #    define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ -        { /* Context switch code here.*/ } +        { /* Context switch code here.*/         \ +        }  /**   * @brief   ISR enter hook.   */  #    define CH_CFG_IRQ_PROLOGUE_HOOK() \ -        { /* IRQ prologue code here.*/ } +        { /* IRQ prologue code here.*/ \ +        }  /**   * @brief   ISR exit hook.   */  #    define CH_CFG_IRQ_EPILOGUE_HOOK() \ -        { /* IRQ epilogue code here.*/ } +        { /* IRQ epilogue code here.*/ \ +        }  /**   * @brief   Idle thread enter hook. @@ -455,7 +460,8 @@   * @note    This macro can be used to activate a power saving mode.   */  #    define CH_CFG_IDLE_ENTER_HOOK() \ -        { /* Idle-enter code here.*/ } +        { /* Idle-enter code here.*/ \ +        }  /**   * @brief   Idle thread leave hook. @@ -464,22 +470,25 @@   * @note    This macro can be used to deactivate a power saving mode.   */  #    define CH_CFG_IDLE_LEAVE_HOOK() \ -        { /* Idle-leave code here.*/ } +        { /* Idle-leave code here.*/ \ +        }  /**   * @brief   Idle Loop hook.   * @details This hook is continuously invoked by the idle thread loop.   */  #    define CH_CFG_IDLE_LOOP_HOOK() \ -        { /* Idle loop code here.*/ } +        { /* Idle loop code here.*/ \ +        }  /**   * @brief   System tick event hook.   * @details This hook is invoked in the system tick handler immediately   *          after processing the virtual timers queue.   */ -#    define CH_CFG_SYSTEM_TICK_HOOK() \ -        { /* System tick event code here.*/ } +#    define CH_CFG_SYSTEM_TICK_HOOK()       \ +        { /* System tick event code here.*/ \ +        }  /**   * @brief   System halt hook. @@ -487,7 +496,8 @@   *          the system is halted.   */  #    define CH_CFG_SYSTEM_HALT_HOOK(reason) \ -        { /* System halt code here.*/ } +        { /* System halt code here.*/       \ +        }  /**   * @brief   Trace hook. @@ -495,7 +505,8 @@   *          trace buffer.   */  #    define CH_CFG_TRACE_HOOK(tep) \ -        { /* Trace code here.*/ } +        { /* Trace code here.*/    \ +        }  /** @} */ diff --git a/quantum/stm32/proton_c.mk b/quantum/stm32/proton_c.mk index 193e09ca1e..ff28a4cb5d 100644 --- a/quantum/stm32/proton_c.mk +++ b/quantum/stm32/proton_c.mk @@ -2,7 +2,7 @@  # These are defaults based on what has been implemented for ARM boards  AUDIO_ENABLE = yes -RGBLIGHT_ENABLE = no +WS2812_DRIVER = bitbang  # Force task driven PWM until ARM can provide automatic configuration  ifneq ($(strip $(BACKLIGHT_ENABLE)), no) diff --git a/quantum/template/avr/config.h b/quantum/template/avr/config.h index 304a54ae59..7e4a014495 100644 --- a/quantum/template/avr/config.h +++ b/quantum/template/avr/config.h @@ -190,9 +190,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  //#define NO_ACTION_LAYER  //#define NO_ACTION_TAPPING  //#define NO_ACTION_ONESHOT -//#define NO_ACTION_MACRO -//#define NO_ACTION_FUNCTION +/* disable these deprecated features by default */ +#ifndef LINK_TIME_OPTIMIZATION_ENABLE +  #define NO_ACTION_MACRO +  #define NO_ACTION_FUNCTION +#endif  /*   * MIDI options   */ diff --git a/quantum/template/base/keyboard.c b/quantum/template/base/keyboard.c index 55e4fffd3a..fc31c294a2 100644 --- a/quantum/template/base/keyboard.c +++ b/quantum/template/base/keyboard.c @@ -42,9 +42,9 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {      return process_record_user(keycode, record);  } -void led_set_kb(uint8_t usb_led) { +bool led_update_kb(led_t led_state) {      // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here -    led_set_user(usb_led); +    return led_update_user(led_state);  }  */ diff --git a/quantum/template/base/keymaps/default/keymap.c b/quantum/template/base/keymaps/default/keymap.c index 4d5bac7b2f..af35ccec15 100644 --- a/quantum/template/base/keymaps/default/keymap.c +++ b/quantum/template/base/keymaps/default/keymap.c @@ -52,7 +52,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {          case QMKURL:              if (record->event.pressed) {                  // when keycode QMKURL is pressed -                SEND_STRING("https://qmk.fm/" SS_TAP(X_ENTER)); +                SEND_STRING("https://qmk.fm/\n");              } else {                  // when keycode QMKURL is released              } @@ -70,7 +70,7 @@ void matrix_scan_user(void) {  } -void led_set_user(uint8_t usb_led) { - +bool led_update_user(led_t led_state) { +    return true;  }  */ diff --git a/quantum/template/ps2avrgb/config.h b/quantum/template/ps2avrgb/config.h index f6d7c25e04..d93512bca6 100644 --- a/quantum/template/ps2avrgb/config.h +++ b/quantum/template/ps2avrgb/config.h @@ -22,7 +22,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define VENDOR_ID 0x20A0  #define PRODUCT_ID 0x422D  #define DEVICE_VER 0x0001 -#define MANUFACTURER You +#define MANUFACTURER %YOUR_NAME%  #define PRODUCT %KEYBOARD%  #define DESCRIPTION A custom keyboard @@ -44,6 +44,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define NO_UART 1 +/* disable these deprecated features by default */ +#ifndef LINK_TIME_OPTIMIZATION_ENABLE +  #define NO_ACTION_MACRO +  #define NO_ACTION_FUNCTION +#endif +  /* key combination for magic key command */  /* defined by default; to change, uncomment and set to the combination you want */  // #define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT) diff --git a/quantum/template/ps2avrgb/usbconfig.h b/quantum/template/ps2avrgb/usbconfig.h index 9ef232f045..83ad06544d 100644 --- a/quantum/template/ps2avrgb/usbconfig.h +++ b/quantum/template/ps2avrgb/usbconfig.h @@ -98,20 +98,10 @@ section at the end of this file).   * (e.g. HID), but never want to send any data. This option saves a couple   * of bytes in flash memory and the transmit buffers in RAM.   */ -#define USB_CFG_INTR_POLL_INTERVAL 1 -/* If you compile a version with endpoint 1 (interrupt-in), this is the poll - * interval. The value is in milliseconds and must not be less than 10 ms for - * low speed devices. - */  #define USB_CFG_IS_SELF_POWERED 0  /* Define this to 1 if the device has its own power supply. Set it to 0 if the   * device is powered from the USB bus.   */ -#define USB_CFG_MAX_BUS_POWER 500 -/* Set this variable to the maximum USB bus power consumption of your device. - * The value is in milliamperes. [It will be divided by two since USB - * communicates power requirements in units of 2 mA.] - */  #define USB_CFG_IMPLEMENT_FN_WRITE 1  /* Set this to 1 if you want usbFunctionWrite() to be called for control-out   * transfers. Set it to 0 if you don't need it and want to save a couple of @@ -227,7 +217,7 @@ section at the end of this file).   * with libusb: 0x16c0/0x5dc.  Use this VID/PID pair ONLY if you understand   * the implications!   */ -#define USB_CFG_DEVICE_VERSION 0x00, 0x02 +#define USB_CFG_DEVICE_VERSION (DEVICE_VER & 0xFF), ((DEVICE_VER >> 8) & 0xFF)  /* Version number of the device: Minor number first, then major number.   */  #define USB_CFG_VENDOR_NAME 'w', 'i', 'n', 'k', 'e', 'y', 'l', 'e', 's', 's', '.', 'k', 'r'  | 
