diff options
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/dynamic_macro.h | 9 | ||||
-rw-r--r-- | quantum/keycode_config.h | 5 | ||||
-rw-r--r-- | quantum/keymap.h | 14 | ||||
-rw-r--r-- | quantum/keymap_extras/keymap_br_abnt2.h | 58 | ||||
-rw-r--r-- | quantum/keymap_extras/keymap_canadian_multilingual.h | 255 | ||||
-rw-r--r-- | quantum/keymap_extras/keymap_dvorak.h | 4 | ||||
-rw-r--r-- | quantum/keymap_extras/keymap_dvp.h | 82 | ||||
-rw-r--r-- | quantum/matrix.c | 326 | ||||
-rw-r--r-- | quantum/process_keycode/process_midi.c | 4 | ||||
-rw-r--r-- | quantum/process_keycode/process_tap_dance.c | 1 | ||||
-rw-r--r-- | quantum/process_keycode/process_tap_dance.h | 10 | ||||
-rw-r--r-- | quantum/process_keycode/process_unicode.c | 52 | ||||
-rw-r--r-- | quantum/process_keycode/process_unicode.h | 13 | ||||
-rw-r--r-- | quantum/quantum.c | 125 | ||||
-rw-r--r-- | quantum/rgblight.c | 61 | ||||
-rw-r--r-- | quantum/rgblight.h | 6 | ||||
-rw-r--r-- | quantum/variable_trace.c | 110 | ||||
-rw-r--r-- | quantum/variable_trace.h | 34 |
18 files changed, 985 insertions, 184 deletions
diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h index a3ad61bc7..e6dbc5b9c 100644 --- a/quantum/dynamic_macro.h +++ b/quantum/dynamic_macro.h @@ -8,8 +8,13 @@ /* 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. */ -#define DYNAMIC_MACRO_SIZE 256 + * 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. + */ +#define DYNAMIC_MACRO_SIZE 128 #endif /* DYNAMIC_MACRO_RANGE must be set as the last element of user's diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h index 6216eefc9..c15b0d32f 100644 --- a/quantum/keycode_config.h +++ b/quantum/keycode_config.h @@ -1,6 +1,9 @@ #include "eeconfig.h" #include "keycode.h" +#ifndef KEYCODE_CONFIG_H +#define KEYCODE_CONFIG_H + uint16_t keycode_config(uint16_t keycode); /* NOTE: Not portable. Bit field order depends on implementation */ @@ -19,3 +22,5 @@ typedef union { } keymap_config_t; extern keymap_config_t keymap_config; + +#endif /* KEYCODE_CONFIG_H */ diff --git a/quantum/keymap.h b/quantum/keymap.h index f2d94d75c..a01bbfbd1 100644 --- a/quantum/keymap.h +++ b/quantum/keymap.h @@ -84,6 +84,10 @@ enum quantum_keycodes { QK_MOD_TAP_MAX = 0x6FFF, QK_TAP_DANCE = 0x7100, QK_TAP_DANCE_MAX = 0x71FF, +#ifdef UNICODEMAP_ENABLE + QK_UNICODE_MAP = 0x7800, + QK_UNICODE_MAP_MAX = 0x7FFF, +#endif #ifdef UNICODE_ENABLE QK_UNICODE = 0x8000, QK_UNICODE_MAX = 0xFFFF, @@ -111,6 +115,7 @@ enum quantum_keycodes { MAGIC_UNSWAP_BACKSLASH_BACKSPACE, MAGIC_UNHOST_NKRO, MAGIC_UNSWAP_ALT_GUI, + MAGIC_TOGGLE_NKRO, // Leader key #ifndef DISABLE_LEADER @@ -190,6 +195,7 @@ enum quantum_keycodes { #define HYPR(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI) #define MEH(kc) (kc | QK_LCTL | QK_LSFT | QK_LALT) #define LCAG(kc) (kc | QK_LCTL | QK_LALT | QK_LGUI) +#define ALTG(kc) (kc | QK_RCTL | QK_RALT) #define MOD_HYPR 0xf #define MOD_MEH 0x7 @@ -294,7 +300,10 @@ enum quantum_keycodes { // ON_PRESS = 1 // ON_RELEASE = 2 // Unless you have a good reason not to do so, prefer ON_PRESS (1) as your default. -#define TO(layer, when) (layer | QK_TO | (when << 0x4)) +// In fact, we changed it to assume ON_PRESS for sanity/simplicity. If needed, you can add your own +// keycode modeled after the old version, kept below for this. +/* #define TO(layer, when) (layer | QK_TO | (when << 0x4)) */ +#define TO(layer) (layer | QK_TO | (ON_PRESS << 0x4)) // Momentary switch layer - 256 layer max #define MO(layer) (layer | QK_MOMENTARY) @@ -334,5 +343,8 @@ enum quantum_keycodes { #define UC(n) UNICODE(n) #endif +#ifdef UNICODEMAP_ENABLE + #define X(n) (n | QK_UNICODE_MAP) +#endif #endif diff --git a/quantum/keymap_extras/keymap_br_abnt2.h b/quantum/keymap_extras/keymap_br_abnt2.h new file mode 100644 index 000000000..0df177721 --- /dev/null +++ b/quantum/keymap_extras/keymap_br_abnt2.h @@ -0,0 +1,58 @@ +#ifndef KEYMAP_BR_ABNT2_H +#define KEYMAP_BR_ABNT2_H + +#include "keymap_common.h" + +/* Scan codes for the Brazilian ABNT2 keyboard layout */ + +#define BR_CCDL KC_SCLN // Ç same scancode as ;: on US layout +#define BR_SCLN KC_SLSH // ;: same scancode as /? on US layout +#define BR_QUOT KC_GRV // '" same scancode as `~ on US layout +#define BR_TILD KC_QUOT // ~^ dead keys, same scancode as '" on US layout +#define BR_ACUT KC_LBRC // ´` dead keys, same scancode as [{ on US layout +#define BR_LBRC KC_RBRC // [{ same scancode as ]} on US layout +#define BR_RBRC KC_BSLS // ]} same scancode as \| on US layout +#define BR_BSLS KC_NUBS // \| uses the non-US hash scancode (#~, sometimes §±) +#define BR_SLSH KC_INT1 // /? uses the INTL1 scancode + +#define BR_COLN LSFT(BR_SCLN) // shifted : +#define BR_DQT LSFT(BR_QUOT) // shifted " +#define BR_CIRC LSFT(BR_TILD) // shifted ^ (dead key) +#define BR_GRAV LSFT(BR_ACUT) // shifted ` (dead key) +#define BR_LCBR LSFT(BR_LBRC) // shifted { +#define BR_RCBR LSFT(BR_RBRC) // shifted } +#define BR_PIPE LSFT(BR_BSLS) // shifted | +#define BR_QUES LSFT(BR_SLSH) // shifted ? +#define BR_TRMA LSFT(KC_6) // shifted ¨ (dead key - trema accent) + +// On the ABNT2 the keypad comma and the keypad dot scancodes are switched +// (presumably because in Brazil comma is used as the decimal separator) +#define BR_KPDT KC_KP_COMMA // keypad . +#define BR_KPCM KC_KP_DOT // keypad , + +#define BR_1UP LALT(KC_1) // 1 superscript ¹ alt+1 +#define BR_2UP LALT(KC_2) // 2 superscript ² alt+2 +#define BR_3UP LALT(KC_3) // 3 superscript ³ alt+3 +#define BR_PND LALT(KC_4) // Pound sign £ alt+4 +#define BR_CENT LALT(KC_5) // Cent sign ¢ alt+5 +#define BR_NOT LALT(KC_6) // Not sign ¬ alt+6 +#define BR_SECT LALT(KC_EQL) // Section sign § alt+= +#define BR_FORD LALT(BR_LBRC) // Feminine Ordinal Sign ª alt+[ +#define BR_MORD LALT(BR_RBRC) // Masculine Ordinal Sign º alt+] +#define BR_DGRE LALT(BR_SLSH) // Degree sign ° alt+/ + +#define BR_EURO LALT(KC_E) // Euro sign € alt+e +#define BR_NDTD LALT(BR_TILD) // Non-dead key tilde ~ alt+~ +#define BR_NDAC LALT(BR_ACUT) // Non-dead key acute accent ´ alt+´ +#define BR_NDGV LALT(BR_QUOT) // Non-dead key grave accent ` alt+' +#define BR_NDCR LALT(BR_CIRC) // Non-dead key circumflex accent ^ alt+^ (alt+shift+~) +#define BR_NDTR LALT(BR_TRMA) // Non-dead key trema accent ¨ alt+¨ (alt+shift+6) + +// For 101-key keyboard layouts, the ABNT2 layout allows +// the slash and question mark to be typed using alt+q and alt+w. +// The shortcuts are provided here for completeness' sake, +// but it's recommended to use BR_SLSH and BR_QUES instead +#define BR_ASLS LALT(KC_Q) +#define BR_AQST LALT(KC_W) + +#endif diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h new file mode 100644 index 000000000..0bc20c7b9 --- /dev/null +++ b/quantum/keymap_extras/keymap_canadian_multilingual.h @@ -0,0 +1,255 @@ +#ifndef KEYMAP_CANADIAN_MULTILINGUAG_H +#define KEYMAP_CANADIAN_MULTILINGUAG_H + +#include "keymap.h" + +// Alt gr +#ifndef ALTGR +#define ALTGR(kc) RALT(kc) +#endif +#ifndef ALGR +#define ALGR(kc) ALTGR(kc) +#endif + +#define CSA_ALTGR KC_RALT +#define CSA_ALGR CSA_ALTGR + +#ifndef GR2A +#define GR2A(kc) RCTL(kc) +#endif + +// Normal characters +// First row +#define CSA_SLASH KC_GRV // / +#define CSA_SLSH CSA_SLASH + +// Second row +#define CSA_DEAD_CIRCUMFLEX KC_LBRACKET // dead ^ +#define CSA_DCRC CSA_DEAD_CIRCUMFLEX +#define CSA_C_CEDILLA KC_RBRACKET // Ç +#define CSA_CCED CSA_C_CEDILLA + +// Third row +#define CSA_E_GRAVE KC_QUOT // è +#define CSA_EGRV CSA_E_GRAVE +#define CSA_A_GRAVE KC_BSLASH // à +#define CSA_AGRV CSA_A_GRAVE + +// Fourth row +#define CSA_U_GRAVE KC_NONUS_BSLASH // ù +#define CSA_UGRV CSA_U_GRAVE +#define CSA_E_ACUTE KC_SLSH // é +#define CSA_ECUT CSA_E_ACUTE + +// Shifted characters +// First row +#define CSA_BACKSLASH LSFT(CSA_SLASH) /* \ */ +#define CSA_BSLS CSA_BACKSLASH +#define CSA_QUESTION LSFT(KC_6) // ? +#define CSA_QEST CSA_QUESTION + +// Second row +#define CSA_DEAD_TREMA LSFT(CSA_DEAD_CIRCUMFLEX) // dead trema/umlaut/diaresis for ä ë ï ö ü +#define CSA_DTRM CSA_DEAD_TREMA + +// Third row +// all same as US-QWERTY, or capitalised character of the non-shifted key + +// Fourth row +#define CSA_APOSTROPHE LSFT(KC_COMMA) // ' +#define CSA_APOS CSA_APOSTROPHE +#define CSA_DOUBLE_QUOTE LSFT(KC_DOT) // " +#define CSA_DQOT CSA_DOUBLE_QUOTE + +// Alt Gr-ed characters +// First row +#define CSA_PIPE ALTGR(CSA_SLASH) // | +#define CSA_CURRENCY ALTGR(KC_4) // ¤ +#define CSA_CURR CSA_CURRENCY +#define CSA_LEFT_CURLY_BRACE ALTGR(KC_7) // { +#define CSA_LCBR CSA_LEFT_CURLY_BRACE +#define CSA_RIGHT_CURLY_BRACE ALTGR(KC_8) // } +#define CSA_RCBR CSA_RIGHT_CURLY_BRACE +#define CSA_LBRACKET ALTGR(KC_9) // [ +#define CSA_LBRC CSA_LBRACKET +#define CSA_RBRACKET ALTGR(KC_0) // ] +#define CSA_RBRC CSA_RBRACKET +#define CSA_NEGATION ALTGR(KC_EQUAL) // ¬ +#define CSA_NEGT CSA_NEGATION + +// Second row +// euro symbol not available on Linux? (X.org) +#define CSA_EURO ALTGR(KC_E) // € +#define CSA_DEAD_GRAVE ALTGR(CSA_DEAD_CIRCUMFLEX) +#define CSA_DGRV CSA_DEAD_GRAVE // dead ` +#define CSA_DEAD_TILDE ALTGR(CSA_C_CEDILLA) // ~ +#define CSA_DTLD CSA_DEAD_TILDE + +// Third row +#define CSA_DEGREE ALTGR(KC_SCOLON) // ° +#define CSA_DEGR CSA_DEGREE + +// Fourth row +#define CSA_LEFT_GUILLEMET ALTGR(KC_Z) // « +#define CSA_LGIL CSA_LEFT_GUILLEMET +#define CSA_RIGHT_GUILLEMET ALTGR(KC_X) // » +#define CSA_RGIL CSA_RIGHT_GUILLEMET +#define CSA_LESS ALTGR(KC_COMMA) // < +#define CSA_GREATER ALTGR(KC_DOT) // > +#define CSA_GRTR CSA_GREATER + +// Space bar +#define CSA_NON_BREAKING_SPACE ALTGR(KC_SPACE) +#define CSA_NBSP CSA_NON_BREAKING_SPACE + +// GR2A-ed characters +// First row +#define CSA_SUPERSCRIPT_ONE GR2A(KC_1) // ¹ +#define CSA_SUP1 CSA_SUPERSCRIPT_ONE +#define CSA_SUPERSCRIPT_TWO GR2A(KC_2) // ² +#define CSA_SUP2 CSA_SUPERSCRIPT_TWO +#define CSA_SUPERSCRIPT_THREE GR2A(KC_3) // ³ +#define CSA_SUP3 CSA_SUPERSCRIPT_THREE +#define CSA_ONE_QUARTER GR2A(KC_4) // ¼ +#define CSA_1QRT CSA_ONE_QUARTER +#define CSA_ONE_HALF GR2A(KC_5) // ½ +#define CSA_1HLF CSA_ONE_HALF +#define CSA_THREE_QUARTERS GR2A(KC_6) // ¾ +#define CSA_3QRT CSA_THREE_QUARTERS +// nothing on 7-0 and - +#define CSA_DEAD_CEDILLA GR2A(KC_EQUAL) // dead ¸ +#define CSA_DCED CSA_DEAD_CEDILLA + +// Second row +#define CSA_OMEGA GR2A(KC_Q) // ω +#define CSA_OMEG CSA_OMEGA +#define CSA_L_STROKE GR2A(KC_W) // ł +#define CSA_LSTK CSA_L_STROKE +#define CSA_OE_LIGATURE GR2A(KC_E) // œ +#define CSA_OE CSA_OE_LIGATURE +#define CSA_PARAGRAPH GR2A(KC_R) // ¶ +#define CSA_PARG CSA_PARAGRAPH +#define CSA_T_STROKE GR2A(KC_T) // ŧ +#define CSA_LEFT_ARROW GR2A(KC_Y) // ← +#define CSA_LARW CSA_LEFT_ARROW +#define CSA_DOWN_ARROW GR2A(KC_U) // ↓ +#define CSA_DARW CSA_DOWN_ARROW +#define CSA_RIGHT_ARROW GR2A(KC_I) // → +#define CSA_RARW CSA_RIGHT_ARROW +#define CSA_O_STROKE GR2A(KC_O) // ø +#define CSA_OSTK CSA_O_STROKE +#define CSA_THORN GR2A(KC_P) // þ +#define CSA_THRN CSA_THORN +// nothing on ^ +#define CSA_TILDE GR2A(CSA_C_CEDILLA) // dead ~ +#define CSA_TILD CSA_TILDE + +// Third row +#define CSA_AE_LIGATURE GR2A(KC_A) // æ +#define CSA_AE CSA_AE_LIGATURE +#define CSA_SHARP_S GR2A(KC_S) // ß +#define CSA_SRPS CSA_SHARP_S +#define CSA_ETH GR2A(KC_D) // ð +// nothing on F +#define CSA_ENG GR2A(KC_G) // ŋ +#define CSA_H_SRTOKE GR2A(KC_H) // ħ +#define CSA_HSTK CSA_H_SRTOKE +#define CSA_IJ_LIGATURE GR2A(KC_J) // ij +#define CSA_IJ CSA_IJ_LIGATURE +#define CSA_KRA GR2A(KC_K) // ĸ +#define CSA_L_FLOWN_DOT GR2A(KC_L) // ŀ +#define CSA_LFLD CSA_L_FLOWN_DOT +#define CSA_DEAD_ACUTE GR2A(KC_SCLN) // dead acute accent +#define CSA_DACT CSA_DEAD_ACUTE +// nothing on È & À + +// Fourth row +#define CSA_CENT GR2A(KC_C) // ¢ +#define CSA_LEFT_DOUBLE_QUOTE GR2A(KC_V) // “ +#define CSA_LDQT CSA_LEFT_DOUBLE_QUOTE +#define CSA_RIGHT_DOUBLE_QUOTE GR2A(KC_B) // ” +#define CSA_RDQT CSA_RIGHT_DOUBLE_QUOTE +#define CSA_N_APOSTROPHE GR2A(KC_N) // ʼn (deprecated unicode codepoint) +#define CSA_NAPO CSA_N_APOSTROPHE +#define CSA_MU GR2A(KC_M) // μ +#define CSA_HORIZONTAL_BAR GR2A(KC_COMMA) // ― +#define CSA_HZBR CSA_HORIZONTAL_BAR +#define CSA_DEAD_DOT_ABOVE GR2A(KC_DOT) // dead ˙ +#define CSA_DDTA CSA_DEAD_DOT_ABOVE + +// GR2A-shifted characters (different from capitalised GR2A-ed characters) +// First row +#define CSA_SOFT_HYPHEN GR2A(LSFT(CSA_SLASH)) // soft-hyphen, appears as a hyphen in wrapped word +#define CSA_SHYP CSA_SOFT_HYPHEN +#define CSA_INVERTED_EXCLAIM GR2A(KC_EXCLAIM) // ¡ +#define CSA_IXLM CSA_INVERTED_EXCLAIM +// nothing on 2 +#define CSA_POUND GR2A(LSFT(KC_3)) // £ +#define CSA_GBP CSA_POUND_SIGN +// already on ALTGR(KC_E) +#define CSA_EURO_BIS GR2A(LSFT(KC_4)) // € +#define CSA_EURB CSA_EURO_BIS +#define CSA_THREE_EIGHTHS GR2A(LSFT(KC_5)) // ⅜ +#define CSA_3ON8 CSA_THREE_EIGHTHS +#define CSA_FIVE_EIGHTHS GR2A(LSFT(KC_6)) // ⅝ +#define CSA_5ON8 CSA_FIVE_EIGHTHS +#define CSA_SEVEN_EIGHTHS GR2A(LSFT(KC_7)) // ⅞ +#define CSA_7ON8 CSA_SEVEN_EIGHTHS +#define CSA_TRADEMARK GR2A(LSFT(KC_8)) // ™ +#define CSA_TM CSA_TRADEMARK +#define CSA_PLUS_MINUS GR2A(LSFT(KC_9)) // ± +#define CSA_PSMS CSA_PLUS_MINUS +// nothing on 0 +#define CSA_INVERTED_QUESTION GR2A(LSFT(KC_MINUS)) // ¿ +#define CSA_IQST CSA_INVERTED_QUESTION +#define CSA_DEAD_OGONEK GR2A(LSFT(KC_EQUAL)) // dead ˛ +#define CSA_DOGO CSA_DEAD_OGONEK + +// Second row +#define CSA_REGISTERED_TRADEMARK GR2A(LSFT(KC_R)) // ® +#define CSA_RTM CSA_REGISTERED_TRADEMARK +#define CSA_YEN GR2A(LSFT(KC_Y)) // ¥ +#define CSA_YUAN CSA_YEN +#define CSA_UP_ARROW LSFT(CSA_DOWN_ARROW) // ↑ +#define CSA_DOTLESS_I GR2A(LSFT(KC_I)) // ı +#define CSA_DLSI CSA_DOTLESS_I +#define CSA_DEAD_RING GR2A(LSFT(CSA_DCRC)) // dead ° +#define CSA_DRNG CSA_DEAD_RING +#define CSA_DEAD_MACRON GR2A(LSFT(CSA_C_CEDILLA)) // dead ¯ +#define CSA_DMCR CSA_DEAD_MACRON + +// Third row +#define CSA_SECTION GR2A(LSFT(KC_S)) // § +#define CSA_SECT CSA_SECTION +#define CSA_ORDINAL_INDICATOR_A GR2A(LSFT(KC_F)) // ª +#define CSA_ORDA CSA_ORDINAL_INDICATOR_A +#define CSA_DEAD_DOUBLE_ACUTE LSFT(CSA_DEAD_ACUTE) // ˝ +#define CSA_DDCT CSA_DEAD_DOUBLE_ACUTE +#define CSA_DEAD_CARON GR2A(LSFT(CSA_E_GRAVE)) // dead ˇ +#define CSA_DCAR CSA_DEAD_CARON +#define CSA_DEAD_BREVE GR2A(LSFT(CSA_A_GRAVE)) // dead ˘ +#define CSA_DBRV CSA_DEAD_BREVE + +// Fourth row +#define CSA_BROKEN_PIPE GR2A(LSFT(CSA_U_GRAVE)) // ¦ +#define CSA_BPIP CSA_BROKEN_PIPE +#define CSA_COPYRIGHT GR2A(LSFT(KC_C)) // © +#define CSA_CPRT CSA_COPYRIGHT +#define CSA_LEFT_QUOTE GR2A(LSFT(KC_V)) // ‘ +#define CSA_LQOT CSA_LEFT_QUOTE +#define CSA_RIGHT_QUOTE GR2A(LSFT(KC_B)) // ’ +#define CSA_RQOT CSA_RIGHT_QUOTE +#define CSA_EIGHTH_NOTE GR2A(LSFT(KC_N)) // ♪ +#define CSA_8NOT CSA_EIGHTH_NOTE +#define CSA_ORDINAL_INDICATOR_O GR2A(LSFT(KC_M)) // º +#define CSA_ORDO CSA_ORDINAL_INDICATOR_O +#define CSA_TIMES GR2A(LSFT(KC_COMMA)) // × +#define CSA_TIMS CSA_TIMES +#define CSA_OBELUS GR2A(LSFT(KC_DOT)) // ÷ +#define CSA_OBEL CSA_OBELUS +// more conventional name of the symbol +#define CSA_DIVISION_SIGN CSA_OBELUS +#define CSA_DVSN CSA_DIVISION_SIGN +// TODO GR2A(LSFT(CSA_E_ACUTE)) + +#endif diff --git a/quantum/keymap_extras/keymap_dvorak.h b/quantum/keymap_extras/keymap_dvorak.h index 17f205977..a0feed850 100644 --- a/quantum/keymap_extras/keymap_dvorak.h +++ b/quantum/keymap_extras/keymap_dvorak.h @@ -70,6 +70,10 @@ #define DV_LCBR LSFT(DV_LBRC) #define DV_RCBR LSFT(DV_RBRC) +#define DV_DQUO LSFT(DV_QUOT) +#define DV_LABK LSFT(DV_COMM) +#define DV_RABK LSFT(DV_DOT) + #define DV_QUES LSFT(DV_SLSH) #define DV_PLUS LSFT(DV_EQL) #define DV_PIPE LSFT(DV_BSLS) diff --git a/quantum/keymap_extras/keymap_dvp.h b/quantum/keymap_extras/keymap_dvp.h new file mode 100644 index 000000000..83f49a52b --- /dev/null +++ b/quantum/keymap_extras/keymap_dvp.h @@ -0,0 +1,82 @@ +#ifndef KEYMAP_DVP_H +#define KEYMAP_DVP_H + +#include "keymap.h" + +// Normal characters +#define DP_DLR KC_GRV +#define DP_AMPR KC_1 +#define DP_LBRC KC_2 +#define DP_LCBR KC_3 +#define DP_RCBR KC_4 +#define DP_LPRN KC_5 +#define DP_EQL KC_6 +#define DP_ASTR KC_7 +#define DP_RPRN KC_8 +#define DP_PLUS KC_9 +#define DP_RBRC KC_0 +#define DP_EXLM KC_MINS +#define DP_HASH KC_EQL + +#define DP_SCLN KC_Q +#define DP_COMM KC_W +#define DP_DOT KC_E +#define DP_P KC_R +#define DP_Y KC_T +#define DP_F KC_Y +#define DP_G KC_U +#define DP_C KC_I +#define DP_R KC_O +#define DP_L KC_P +#define DP_SLSH KC_LBRC +#define DP_AT KC_RBRC +#define DP_BSLS KC_BSLS + +#define DP_A KC_A +#define DP_O KC_S +#define DP_E KC_D +#define DP_U KC_F +#define DP_I KC_G +#define DP_D KC_H +#define DP_H KC_J +#define DP_T KC_K +#define DP_N KC_L +#define DP_S KC_SCLN +#define DP_MINS KC_QUOT + +#define DP_QUOT KC_Z +#define DP_Q KC_X +#define DP_J KC_C +#define DP_K KC_V +#define DP_X KC_B +#define DP_B KC_N +#define DP_M KC_M +#define DP_W KC_COMM +#define DP_V KC_DOT +#define DP_Z KC_SLSH + +// Shifted characters +#define DP_TILD LSFT(DP_DLR) +#define DP_PERC LSFT(DP_AMPR) +#define DP_7 LSFT(DP_LBRC) +#define DP_5 LSFT(DP_LCBR) +#define DP_3 LSFT(DP_RCBR) +#define DP_1 LSFT(DP_LPRN) +#define DP_9 LSFT(DP_EQL) +#define DP_0 LSFT(DP_ASTR) +#define DP_2 LSFT(DP_RPRN) +#define DP_4 LSFT(DP_PLUS) +#define DP_6 LSFT(DP_RBRC) +#define DP_8 LSFT(DP_EXLM) +#define DP_GRV LSFT(DP_HASH) + +#define DP_COLN LSFT(DP_SCLN) +#define DP_LABK LSFT(DP_COMM) +#define DP_RABK LSFT(DP_DOT) +#define DP_QUES LSFT(DP_SLSH) +#define DP_CIRC LSFT(DP_AT) +#define DP_PIPE LSFT(DP_BSLS) +#define DP_UNDS LSFT(DP_MINS) +#define DP_DQUO LSFT(DP_QUOT) + +#endif diff --git a/quantum/matrix.c b/quantum/matrix.c index 3174e0739..07eb87bc3 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -25,37 +25,65 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "debug.h" #include "util.h" #include "matrix.h" +#include "timer.h" + /* Set 0 if debouncing isn't needed */ #ifndef DEBOUNCING_DELAY # define DEBOUNCING_DELAY 5 #endif -static uint8_t debouncing = DEBOUNCING_DELAY; + +#if (DEBOUNCING_DELAY > 0) + static uint16_t debouncing_time; + static bool debouncing = false; +#endif + +#if (MATRIX_COLS <= 8) +# define print_matrix_header() print("\nr/c 01234567\n") +# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop(matrix[i]) +# define ROW_SHIFTER ((uint8_t)1) +#elif (MATRIX_COLS <= 16) +# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") +# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop16(matrix[i]) +# define ROW_SHIFTER ((uint16_t)1) +#elif (MATRIX_COLS <= 32) +# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") +# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) +# define matrix_bitpop(i) bitpop32(matrix[i]) +# define ROW_SHIFTER ((uint32_t)1) +#endif + +#ifdef MATRIX_MASKED + extern const matrix_row_t matrix_mask[]; +#endif static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; + +static matrix_row_t matrix_raw[MATRIX_ROWS]; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; -#if DIODE_DIRECTION == ROW2COL - static matrix_row_t matrix_reversed[MATRIX_COLS]; - static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; -#endif -#if MATRIX_COLS > 16 - #define SHIFTER 1UL -#else - #define SHIFTER 1 +#if (DIODE_DIRECTION == COL2ROW) + static void init_cols(void); + static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); + static void unselect_rows(void); + static void select_row(uint8_t row); + static void unselect_row(uint8_t row); +#else // ROW2COL + static void init_rows(void); + static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); + static void unselect_cols(void); + static void unselect_col(uint8_t col); + static void select_col(uint8_t col); #endif -static matrix_row_t read_cols(void); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); - __attribute__ ((weak)) void matrix_init_quantum(void) { matrix_init_kb(); @@ -95,7 +123,7 @@ uint8_t matrix_cols(void) { } // void matrix_power_up(void) { -// #if DIODE_DIRECTION == COL2ROW +// #if (DIODE_DIRECTION == COL2ROW) // for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { // /* DDRxn */ // _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF); @@ -119,19 +147,26 @@ uint8_t matrix_cols(void) { // } void matrix_init(void) { + // To use PORTF disable JTAG with writing JTD bit twice within four cycles. - #ifdef __AVR_ATmega32U4__ + #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__)) MCUCR |= _BV(JTD); MCUCR |= _BV(JTD); #endif // initialize row and col +#if (DIODE_DIRECTION == COL2ROW) unselect_rows(); init_cols(); +#else // ROW2COL + unselect_cols(); + init_rows(); +#endif // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) { matrix[i] = 0; + matrix_raw[i] = 0; matrix_debouncing[i] = 0; } @@ -141,71 +176,60 @@ void matrix_init(void) { uint8_t matrix_scan(void) { -#if DIODE_DIRECTION == COL2ROW - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(i); - wait_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCING_DELAY; - } - unselect_rows(); - } +#if (DIODE_DIRECTION == COL2ROW) - if (debouncing) { - if (--debouncing) { - wait_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; + // Set row, read cols + for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { +# if (DEBOUNCING_DELAY > 0) + bool matrix_changed = read_cols_on_row(matrix_debouncing, current_row); + + if (matrix_changed) { + debouncing = true; + debouncing_time = timer_read(); } - } + +# else + read_cols_on_row(matrix, current_row); +# endif + } -#else - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - select_row(i); - wait_us(30); // without this wait read unstable value. - matrix_row_t rows = read_cols(); - if (matrix_reversed_debouncing[i] != rows) { - matrix_reversed_debouncing[i] = rows; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); + +#else // ROW2COL + + // Set col, read rows + for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { +# if (DEBOUNCING_DELAY > 0) + bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col); + if (matrix_changed) { + debouncing = true; + debouncing_time = timer_read(); } - debouncing = DEBOUNCING_DELAY; - } - unselect_rows(); +# else + read_rows_on_col(matrix, current_col); +# endif + } - if (debouncing) { - if (--debouncing) { - wait_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - matrix_reversed[i] = matrix_reversed_debouncing[i]; +#endif + +# if (DEBOUNCING_DELAY > 0) + if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = matrix_debouncing[i]; } + debouncing = false; } - } - for (uint8_t y = 0; y < MATRIX_ROWS; y++) { - matrix_row_t row = 0; - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - row |= ((matrix_reversed[x] & (1<<y)) >> y) << x; - } - matrix[y] = row; - } -#endif +# endif matrix_scan_quantum(); - return 1; } bool matrix_is_modified(void) { +#if (DEBOUNCING_DELAY > 0) if (debouncing) return false; +#endif return true; } @@ -218,15 +242,22 @@ bool matrix_is_on(uint8_t row, uint8_t col) inline matrix_row_t matrix_get_row(uint8_t row) { + // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a + // switch blocker installed and the switch is always pressed. +#ifdef MATRIX_MASKED + return matrix[row] & matrix_mask[row]; +#else return matrix[row]; +#endif } void matrix_print(void) { - print("\nr/c 0123456789ABCDEF\n"); + print_matrix_header(); + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { phex(row); print(": "); - pbin_reverse16(matrix_get_row(row)); + print_matrix_row(row); print("\n"); } } @@ -235,63 +266,148 @@ uint8_t matrix_key_count(void) { uint8_t count = 0; for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - count += bitpop16(matrix[i]); + count += matrix_bitpop(i); } return count; } + + +#if (DIODE_DIRECTION == COL2ROW) + static void init_cols(void) { -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_COLS; x++) { - int pin = col_pins[x]; -#else - for(int x = 0; x < MATRIX_ROWS; x++) { - int pin = row_pins[x]; -#endif - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); + for(uint8_t x = 0; x < MATRIX_COLS; x++) { + uint8_t pin = col_pins[x]; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI } } -static matrix_row_t read_cols(void) +static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { - matrix_row_t result = 0; + // Store last value of row prior to reading + matrix_row_t last_row_value = current_matrix[current_row]; -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_COLS; x++) { - int pin = col_pins[x]; -#else - for(int x = 0; x < MATRIX_ROWS; x++) { - int pin = row_pins[x]; -#endif - result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x); + // Clear data in matrix row + current_matrix[current_row] = 0; + + // Select row and wait for row selecton to stabilize + select_row(current_row); + wait_us(30); + + // For each col... + for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { + + // Select the col pin to read (active low) + uint8_t pin = col_pins[col_index]; + uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)); + + // Populate the matrix row with the state of the col pin + current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index); } - return result; + + // Unselect row + unselect_row(current_row); + + return (last_row_value != current_matrix[current_row]); +} + +static void select_row(uint8_t row) +{ + uint8_t pin = row_pins[row]; + _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT + _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW +} + +static void unselect_row(uint8_t row) +{ + uint8_t pin = row_pins[row]; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI } static void unselect_rows(void) { -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_ROWS; x++) { - int pin = row_pins[x]; -#else - for(int x = 0; x < MATRIX_COLS; x++) { - int pin = col_pins[x]; -#endif - _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); - _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); + for(uint8_t x = 0; x < MATRIX_ROWS; x++) { + uint8_t pin = row_pins[x]; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI } } -static void select_row(uint8_t row) +#else // ROW2COL + +static void init_rows(void) { + for(uint8_t x = 0; x < MATRIX_ROWS; x++) { + uint8_t pin = row_pins[x]; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI + } +} -#if DIODE_DIRECTION == COL2ROW - int pin = row_pins[row]; -#else - int pin = col_pins[row]; -#endif - _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); - _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); +static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) +{ + bool matrix_changed = false; + + // Select col and wait for col selecton to stabilize + select_col(current_col); + wait_us(30); + + // For each row... + for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) + { + + // Store last value of row prior to reading + matrix_row_t last_row_value = current_matrix[row_index]; + + // Check row pin state + if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0) + { + // Pin LO, set col bit + current_matrix[row_index] |= (ROW_SHIFTER << current_col); + } + else + { + // Pin HI, clear col bit + current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); + } + + // Determine if the matrix changed state + if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) + { + matrix_changed = true; + } + } + + // Unselect col + unselect_col(current_col); + + return matrix_changed; } + +static void select_col(uint8_t col) +{ + uint8_t pin = col_pins[col]; + _SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF); // OUT + _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW +} + +static void unselect_col(uint8_t col) +{ + uint8_t pin = col_pins[col]; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI +} + +static void unselect_cols(void) +{ + for(uint8_t x = 0; x < MATRIX_COLS; x++) { + uint8_t pin = col_pins[x]; + _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN + _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF); // HI + } +} + +#endif diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c index 8784e64f3..577dad43a 100644 --- a/quantum/process_keycode/process_midi.c +++ b/quantum/process_keycode/process_midi.c @@ -7,7 +7,9 @@ int midi_offset = 7; bool process_midi(uint16_t keycode, keyrecord_t *record) { if (keycode == MI_ON && record->event.pressed) { midi_activated = true; +#ifdef AUDIO_ENABLE music_scale_user(); +#endif return false; } @@ -63,4 +65,4 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { return false; } return true; -}
\ No newline at end of file +} diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 79ade4d00..6ae362c4c 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -70,6 +70,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { action->state.keycode = keycode; action->state.count++; action->state.timer = timer_read(); + process_tap_dance_action_on_each_tap (action); if (last_td && last_td != keycode) { qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE]; diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index d7b857bdc..f753cbba6 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h @@ -39,15 +39,17 @@ typedef struct #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ - .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }) \ + .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \ } #define ACTION_TAP_DANCE_FN(user_fn) { \ - .fn = { NULL, user_fn, NULL } \ + .fn = { NULL, user_fn, NULL }, \ + .user_data = NULL, \ } -#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \ - .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ +#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset) { \ + .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset }, \ + .user_data = NULL, \ } extern qk_tap_dance_action_t tap_dance_actions[]; diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c index a5d7dca21..cd3a610b4 100644 --- a/quantum/process_keycode/process_unicode.c +++ b/quantum/process_keycode/process_unicode.c @@ -2,6 +2,7 @@ static uint8_t input_mode; +__attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) { if (hex == 0x0) { @@ -41,6 +42,11 @@ void unicode_input_start (void) { register_code(KC_PPLS); unregister_code(KC_PPLS); break; + case UC_WINC: + register_code(KC_RALT); + unregister_code(KC_RALT); + register_code(KC_U); + unregister_code(KC_U); } wait_ms(UNICODE_TYPE_DELAY); } @@ -77,6 +83,52 @@ bool process_unicode(uint16_t keycode, keyrecord_t *record) { return true; } +#ifdef UNICODEMAP_ENABLE +__attribute__((weak)) +const uint32_t PROGMEM unicode_map[] = { +}; + +void register_hex32(uint32_t hex) { + uint8_t onzerostart = 1; + for(int i = 7; i >= 0; i--) { + if (i <= 3) { + onzerostart = 0; + } + uint8_t digit = ((hex >> (i*4)) & 0xF); + if (digit == 0) { + if (onzerostart == 0) { + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + } + } else { + register_code(hex_to_keycode(digit)); + unregister_code(hex_to_keycode(digit)); + onzerostart = 0; + } + } +} + +__attribute__((weak)) +void unicode_map_input_error() {} + +bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { + if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) { + const uint32_t* map = unicode_map; + uint16_t index = keycode & 0x7FF; + uint32_t code = pgm_read_dword_far(&map[index]); + if ((code > 0xFFFF && input_mode == UC_OSX) || (code > 0xFFFFF && input_mode == UC_LNX)) { + // when character is out of range supported by the OS + unicode_map_input_error(); + } else { + unicode_input_start(); + register_hex32(code); + unicode_input_finish(); + } + } + return true; +} +#endif + #ifdef UCIS_ENABLE qk_ucis_state_t qk_ucis_state; diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h index 27f8072ee..065eeb5f6 100644 --- a/quantum/process_keycode/process_unicode.h +++ b/quantum/process_keycode/process_unicode.h @@ -3,10 +3,11 @@ #include "quantum.h" -#define UC_OSX 0 -#define UC_LNX 1 -#define UC_WIN 2 -#define UC_BSD 3 +#define UC_OSX 0 // Mac OS X +#define UC_LNX 1 // Linux +#define UC_WIN 2 // Windows 'HexNumpad' +#define UC_BSD 3 // BSD (not implemented) +#define UC_WINC 4 // WinCompose https://github.com/samhocevar/wincompose #ifndef UNICODE_TYPE_DELAY #define UNICODE_TYPE_DELAY 10 @@ -20,6 +21,10 @@ void register_hex(uint16_t hex); bool process_unicode(uint16_t keycode, keyrecord_t *record); +#ifdef UNICODEMAP_ENABLE +bool process_unicode_map(uint16_t keycode, keyrecord_t *record); +#endif + #ifdef UCIS_ENABLE #ifndef UCIS_MAX_SYMBOL_LENGTH #define UCIS_MAX_SYMBOL_LENGTH 32 diff --git a/quantum/quantum.c b/quantum/quantum.c index e3a20f43e..b5e2d60b9 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -1,5 +1,9 @@ #include "quantum.h" +#ifndef TAPPING_TERM +#define TAPPING_TERM 200 +#endif + static void do_code16 (uint16_t code, void (*f) (uint8_t)) { switch (code) { case QK_MODS ... QK_MODS_MAX: @@ -75,6 +79,7 @@ void reset_keyboard(void) { #endif static bool shift_interrupted[2] = {0, 0}; +static uint16_t scs_timer = 0; bool process_record_quantum(keyrecord_t *record) { @@ -129,6 +134,9 @@ bool process_record_quantum(keyrecord_t *record) { #ifdef UCIS_ENABLE process_ucis(keycode, record) && #endif + #ifdef UNICODEMAP_ENABLE + process_unicode_map(keycode, record) && + #endif true)) { return false; } @@ -199,7 +207,7 @@ bool process_record_quantum(keyrecord_t *record) { return false; break; #endif - case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_UNSWAP_ALT_GUI: + case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: if (record->event.pressed) { // MAGIC actions (BOOTMAGIC without the boot) if (!eeconfig_is_enabled()) { @@ -207,54 +215,80 @@ bool process_record_quantum(keyrecord_t *record) { } /* keymap config */ keymap_config.raw = eeconfig_read_keymap(); - if (keycode == MAGIC_SWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 1; - } else if (keycode == MAGIC_CAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 1; - } else if (keycode == MAGIC_SWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 1; - } else if (keycode == MAGIC_SWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 1; - } else if (keycode == MAGIC_NO_GUI) { - keymap_config.no_gui = 1; - } else if (keycode == MAGIC_SWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 1; - } else if (keycode == MAGIC_SWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 1; - } else if (keycode == MAGIC_HOST_NKRO) { - keymap_config.nkro = 1; - } else if (keycode == MAGIC_SWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 1; - keymap_config.swap_ralt_rgui = 1; - } - /* UNs */ - else if (keycode == MAGIC_UNSWAP_CONTROL_CAPSLOCK) { - keymap_config.swap_control_capslock = 0; - } else if (keycode == MAGIC_UNCAPSLOCK_TO_CONTROL) { - keymap_config.capslock_to_control = 0; - } else if (keycode == MAGIC_UNSWAP_LALT_LGUI) { - keymap_config.swap_lalt_lgui = 0; - } else if (keycode == MAGIC_UNSWAP_RALT_RGUI) { - keymap_config.swap_ralt_rgui = 0; - } else if (keycode == MAGIC_UNNO_GUI) { - keymap_config.no_gui = 0; - } else if (keycode == MAGIC_UNSWAP_GRAVE_ESC) { - keymap_config.swap_grave_esc = 0; - } else if (keycode == MAGIC_UNSWAP_BACKSLASH_BACKSPACE) { - keymap_config.swap_backslash_backspace = 0; - } else if (keycode == MAGIC_UNHOST_NKRO) { - keymap_config.nkro = 0; - } else if (keycode == MAGIC_UNSWAP_ALT_GUI) { - keymap_config.swap_lalt_lgui = 0; - keymap_config.swap_ralt_rgui = 0; + 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_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: + keymap_config.nkro = true; + break; + case MAGIC_SWAP_ALT_GUI: + keymap_config.swap_lalt_lgui = true; + keymap_config.swap_ralt_rgui = true; + 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_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: + keymap_config.nkro = false; + break; + case MAGIC_UNSWAP_ALT_GUI: + keymap_config.swap_lalt_lgui = false; + keymap_config.swap_ralt_rgui = false; + break; + case MAGIC_TOGGLE_NKRO: + keymap_config.nkro = !keymap_config.nkro; + break; + default: + break; } eeconfig_update_keymap(keymap_config.raw); + clear_keyboard(); // clear to prevent stuck keys + return false; } break; case KC_LSPO: { if (record->event.pressed) { shift_interrupted[0] = false; + scs_timer = timer_read (); register_mods(MOD_BIT(KC_LSFT)); } else { @@ -264,19 +298,20 @@ bool process_record_quantum(keyrecord_t *record) { shift_interrupted[1] = true; } #endif - if (!shift_interrupted[0]) { + if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) { register_code(LSPO_KEY); unregister_code(LSPO_KEY); } unregister_mods(MOD_BIT(KC_LSFT)); } return false; - break; + // break; } case KC_RSPC: { if (record->event.pressed) { shift_interrupted[1] = false; + scs_timer = timer_read (); register_mods(MOD_BIT(KC_RSFT)); } else { @@ -286,14 +321,14 @@ bool process_record_quantum(keyrecord_t *record) { shift_interrupted[1] = true; } #endif - if (!shift_interrupted[1]) { + if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) { register_code(RSPC_KEY); unregister_code(RSPC_KEY); } unregister_mods(MOD_BIT(KC_RSFT)); } return false; - break; + // break; } default: { shift_interrupted[0] = true; diff --git a/quantum/rgblight.c b/quantum/rgblight.c index f82e3ec55..d550c5866 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -6,24 +6,37 @@ #include "rgblight.h" #include "debug.h" +// Lightness curve using the CIE 1931 lightness formula +//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm const uint8_t DIM_CURVE[] PROGMEM = { - 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, - 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, - 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, - 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, - 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, - 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, - 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, - 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, - 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, - 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255 -}; + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, + 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, + 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, + 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, + 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, + 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, + 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, + 34, 34, 35, 36, 37, 37, 38, 39, 39, 40, + 41, 42, 43, 43, 44, 45, 46, 47, 47, 48, + 49, 50, 51, 52, 53, 54, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 70, 71, 72, 73, 74, 75, 76, 77, 79, + 80, 81, 82, 83, 85, 86, 87, 88, 90, 91, + 92, 94, 95, 96, 98, 99, 100, 102, 103, 105, + 106, 108, 109, 110, 112, 113, 115, 116, 118, 120, + 121, 123, 124, 126, 128, 129, 131, 132, 134, 136, + 138, 139, 141, 143, 145, 146, 148, 150, 152, 154, + 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, + 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, + 196, 198, 200, 202, 204, 207, 209, 211, 214, 216, + 218, 220, 223, 225, 228, 230, 232, 235, 237, 240, + 242, 245, 247, 250, 252, 255, + }; + const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = { 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 9, 10, 11, 12, 14, 15, 17, 18, 20, 21, 23, 25, 27, 29, 31, 33, 35, @@ -42,10 +55,16 @@ const uint8_t RGBLED_BREATHING_TABLE[] PROGMEM = { 37, 35, 33, 31, 29, 27, 25, 23, 21, 20, 18, 17, 15, 14, 12, 11, 10, 9, 7, 6, 5, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0 }; + +__attribute__ ((weak)) const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; +__attribute__ ((weak)) const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; +__attribute__ ((weak)) const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; +__attribute__ ((weak)) const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; +__attribute__ ((weak)) const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {100, 50, 20}; rgblight_config_t rgblight_config; @@ -55,13 +74,8 @@ uint8_t rgblight_inited = 0; void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { - // Convert hue, saturation, and value (HSV/HSB) to RGB. DIM_CURVE is used only - // on value and saturation (inverted). This looks the most natural. uint8_t r = 0, g = 0, b = 0, base, color; - val = pgm_read_byte(&DIM_CURVE[val]); - sat = 255 - pgm_read_byte(&DIM_CURVE[255 - sat]); - if (sat == 0) { // Acromatic color (gray). Hue doesn't mind. r = val; g = val; @@ -103,6 +117,9 @@ void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1) { break; } } + r = pgm_read_byte(&DIM_CURVE[r]); + g = pgm_read_byte(&DIM_CURVE[g]); + b = pgm_read_byte(&DIM_CURVE[b]); setrgb(r, g, b, led1); } diff --git a/quantum/rgblight.h b/quantum/rgblight.h index def26c428..17f04ffcf 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -40,6 +40,12 @@ #include "eeconfig.h" #include "light_ws2812.h" +extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; +extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM; +extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM; +extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM; +extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM; + typedef union { uint32_t raw; struct { diff --git a/quantum/variable_trace.c b/quantum/variable_trace.c new file mode 100644 index 000000000..de580244c --- /dev/null +++ b/quantum/variable_trace.c @@ -0,0 +1,110 @@ +#include "variable_trace.h" +#include <stddef.h> +#include <string.h> + +#ifdef NO_PRINT +#error "You need undef NO_PRINT to use the variable trace feature" +#endif + +#ifndef CONSOLE_ENABLE +#error "The console needs to be enabled in the makefile to use the variable trace feature" +#endif + + +#define NUM_TRACED_VARIABLES 1 +#ifndef MAX_VARIABLE_TRACE_SIZE + #define MAX_VARIABLE_TRACE_SIZE 4 +#endif + +typedef struct { + const char* name; + void* addr; + unsigned size; + const char* func; + int line; + uint8_t last_value[MAX_VARIABLE_TRACE_SIZE]; + +} traced_variable_t; + +static traced_variable_t traced_variables[NUM_TRACED_VARIABLES]; + +void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line) { + verify_traced_variables(func, line); + if (size > MAX_VARIABLE_TRACE_SIZE) { +#if defined(__AVR__) + xprintf("Traced variable \"%S\" exceeds the maximum size %d\n", name, size); +#else + xprintf("Traced variable \"%s\" exceeds the maximum size %d\n", name, size); +#endif + size = MAX_VARIABLE_TRACE_SIZE; + } + int index = -1; + for (int i = 0; i < NUM_TRACED_VARIABLES; i++) { + if (index == -1 && traced_variables[i].addr == NULL){ + index = i; + } + else if (strcmp_P(name, traced_variables[i].name)==0) { + index = i; + break; + } + } + + if (index == -1) { + xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES); + return; + } + + traced_variable_t* t = &traced_variables[index]; + t->name = name; + t->addr = addr; + t->size = size; + t->func = func; + t->line = line; + memcpy(&t->last_value[0], addr, size); + +} + +void remove_traced_variable(const char* name, const char* func, int line) { + verify_traced_variables(func, line); + for (int i = 0; i < NUM_TRACED_VARIABLES; i++) { + if (strcmp_P(name, traced_variables[i].name)==0) { + traced_variables[i].name = 0; + traced_variables[i].addr = NULL; + break; + } + } +} + +void verify_traced_variables(const char* func, int line) { + for (int i = 0; i < NUM_TRACED_VARIABLES; i++) { + traced_variable_t* t = &traced_variables[i]; + if (t->addr != NULL && t->name != NULL) { + if (memcmp(t->last_value, t->addr, t->size)!=0){ +#if defined(__AVR__) + xprintf("Traced variable \"%S\" has been modified\n", t->name); + xprintf("Between %S:%d\n", t->func, t->line); + xprintf("And %S:%d\n", func, line); + +#else + xprintf("Traced variable \"%s\" has been modified\n", t->name); + xprintf("Between %s:%d\n", t->func, t->line); + xprintf("And %s:%d\n", func, line); +#endif + xprintf("Previous value "); + for (int j=0; j<t->size;j++) { + print_hex8(t->last_value[j]); + } + xprintf("\nNew value "); + uint8_t* addr = (uint8_t*)(t->addr); + for (int j=0; j<t->size;j++) { + print_hex8(addr[j]); + } + xprintf("\n"); + memcpy(t->last_value, addr, t->size); + } + } + + t->func = func; + t->line = line; + } +} diff --git a/quantum/variable_trace.h b/quantum/variable_trace.h new file mode 100644 index 000000000..46bd82786 --- /dev/null +++ b/quantum/variable_trace.h @@ -0,0 +1,34 @@ +#ifndef VARIABLE_TRACE_H +#define VARIABLE_TRACE_H + +// For more information about the variable tracing see the readme. + +#include "print.h" + +#ifdef NUM_TRACED_VARIABLES + +// Start tracing a variable at the memory address addr +// The name can be anything and is used only for reporting +// The size should usually be the same size as the variable you are interested in +#define ADD_TRACED_VARIABLE(name, addr, size) \ + add_traced_variable(PSTR(name), (void*)addr, size, PSTR(__FILE__), __LINE__) + +// Stop tracing the variable with the given name +#define REMOVE_TRACED_VARIABLE(name) remove_traced_variable(PSTR(name), PSTR(__FILE__), __LINE__) + +// Call to get messages when the variable has been changed +#define VERIFY_TRACED_VARIABLES() verify_traced_variables(PSTR(__FILE__), __LINE__) + +#else + +#define ADD_TRACED_VARIABLE(name, addr, size) +#define REMOVE_TRACED_VARIABLE(name) +#define VERIFY_TRACED_VARIABLES() + +#endif + +// Don't call directly, use the macros instead +void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line); +void remove_traced_variable(const char* name, const char* func, int line); +void verify_traced_variables(const char* func, int line); +#endif |