#include QMK_KEYBOARD_H enum shift_keycodes { L_BRI = SAFE_RANGE, //LED Brightness Increase L_BRD, //LED Brightness Decrease L_EDG_I, //LED Edge Brightness Increase L_EDG_D, //LED Edge Brightness Decrease L_EDG_M, //LED Edge lighting mode L_PTN, //LED Pattern Select Next L_PTP, //LED Pattern Select Previous L_PSI, //LED Pattern Speed Increase L_PSD, //LED Pattern Speed Decrease L_T_MD, //LED Toggle Mode L_T_ONF, //LED Toggle On / Off L_ON, //LED On L_OFF, //LED Off L_T_BR, //LED Toggle Breath Effect L_T_PTD, //LED Toggle Scrolling Pattern Direction and effect U_T_AGCR, //USB Toggle Automatic GCR control DBG_TOG, //DEBUG Toggle On / Off DBG_MTRX, //DEBUG Toggle Matrix Prints DBG_KBD, //DEBUG Toggle Keyboard Prints DBG_MOU, //DEBUG Toggle Mouse Prints DBG_FAC, //DEBUG Factory light testing (All on white) MD_BOOT, //Restart into bootloader after hold timeout L_RATIOI, // Increase Key to Underglow LED brightness Ratio L_RATIOD // Decrease Key to Underglow LED brightness Ratio }; #define TG_NKRO MAGIC_TOGGLE_NKRO // Toggle 6KRO / NKRO mode #define L_KC_GUI LM(1, MOD_LGUI) // While held, press the GUI modifier key and change to the GUI lighting layer #define KC_MICMT KC_F20 // F20 is used as the micmute key code, but this name is more descriptive ¯\_(ツ)_/¯ keymap_config_t keymap_config; /* In order to use function keys over KC_F12, `tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c` has to be altered. Usage Maximum and Logical Maximum are used to determine the highest keycode to still be sent. Bumping this number, allows for higher function key numbers to be transmitted to the operating system. */ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // Normal layout [0] = LAYOUT( KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MPLY, KC_MPRV, KC_MNXT, KC_MICMT,\ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NLCK, KC_PSLS, KC_PAST, KC_PSCR, \ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PMNS, \ MO(2), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, KC_PPLS, \ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_P1, KC_P2, KC_P3, \ KC_UP, KC_PENT, \ KC_LCTL, L_KC_GUI,KC_LALT, KC_SPC, KC_RALT, MO(2), KC_P0, KC_PDOT, \ KC_LEFT, KC_DOWN, KC_RGHT \ ), // Fully transparent layout for GUI lighting [1] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, \ _______, XXXXXXX, _______, _______, _______, _______, _______, _______, \ _______, _______, _______ \ ), // Fn layer [2] = LAYOUT( XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_SLCK, \ L_T_PTD, XXXXXXX, L_BRI, XXXXXXX, L_EDG_I, XXXXXXX, XXXXXXX, XXXXXXX, U_T_AGCR,XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \ XXXXXXX, L_PTP, L_BRD, L_PTN, L_EDG_D, XXXXXXX, XXXXXXX, L_RATIOD,L_RATIOI,XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \ XXXXXXX, L_T_MD, L_T_ONF, XXXXXXX, L_EDG_M, MD_BOOT, TG_NKRO, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \ KC_PGUP, XXXXXXX, \ XXXXXXX, _______, XXXXXXX, XXXXXXX, KC_APP, XXXXXXX, XXXXXXX, XXXXXXX, \ KC_HOME, KC_PGDN, KC_END \ ), /* [X] = LAYOUT( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, \ _______, _______, _______, _______, _______, _______, _______, _______, \ _______, _______, _______ \ ), */ }; // Runs just one time when the keyboard initializes. void matrix_init_user(void) { led_animation_direction = 1; led_animation_orientation = 1; led_animation_circular = 0; }; // Runs constantly in the background, in a loop. void matrix_scan_user(void) { }; // Function to test double shift caps toggle void test_caps_toggle(void) { if (get_mods() & MOD_BIT(KC_LSHIFT) && get_mods() & MOD_BIT(KC_RSHIFT)) { tap_code(KC_CAPS); } }; #define MODS_SHIFT (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT)) #define MODS_CTRL (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL)) #define MODS_ALT (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { static uint32_t key_timer; static uint8_t scroll_effect = 0; switch (keycode) { // Keyhandlers for double shift caps toggle case KC_LSFT: case KC_RSFT: test_caps_toggle(); return true; // Massdrop built-ins case L_BRI: if (record->event.pressed) { if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX; else gcr_desired += LED_GCR_STEP; if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; case L_BRD: if (record->event.pressed) { if (LED_GCR_STEP > gcr_desired) gcr_desired = 0; else gcr_desired -= LED_GCR_STEP; if (led_animation_breathing) gcr_breathe = gcr_desired; } return false; case L_EDG_M: if (record->event.pressed) { led_edge_mode++; if (led_edge_mode > LED_EDGE_MODE_MAX) { led_edge_mode = LED_EDGE_MODE_ALL; } } return false; case L_EDG_I: if (record->event.pressed) { led_edge_brightness += 0.1; if (led_edge_brightness > 1) { led_edge_brightness = 1; } } return false; case L_EDG_D: if (record->event.pressed) { led_edge_brightness -= 0.1; if (led_edge_brightness < 0) { led_edge_brightness = 0; } } return false; case L_RATIOI: if (record->event.pressed) { led_ratio_brightness += 0.2; if (led_ratio_brightness > 2.0) { led_ratio_brightness = 2.0; } } return false; case L_RATIOD: if (record->event.pressed) { led_ratio_brightness -= 0.2; if (led_ratio_brightness < 0.0) { led_ratio_brightness = 0.0; } } return false; case L_PTN: if (record->event.pressed) { led_mfg_test_mode = LED_MFG_TEST_MODE_OFF; if (led_animation_id == led_setups_count - 1) led_animation_id = 0; else led_animation_id++; } return false; case L_PTP: if (record->event.pressed) { led_mfg_test_mode = LED_MFG_TEST_MODE_OFF; if (led_animation_id == 0) led_animation_id = led_setups_count - 1; else led_animation_id--; } return false; case L_PSI: if (record->event.pressed) { led_animation_speed += ANIMATION_SPEED_STEP; } return false; case L_PSD: if (record->event.pressed) { led_animation_speed -= ANIMATION_SPEED_STEP; if (led_animation_speed < 0) led_animation_speed = 0; } return false; case L_T_MD: if (record->event.pressed) { led_lighting_mode++; if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL; } return false; case L_T_ONF: if (record->event.pressed) { //I2C3733_Control_Set(!I2C3733_Control_Get()); led_lighting_mode = ((led_lighting_mode == LED_MODE_INDICATORS_ONLY)? LED_MODE_NORMAL : LED_MODE_INDICATORS_ONLY); } return false; case L_ON: if (record->event.pressed) { I2C3733_Control_Set(1); } return false; case L_OFF: if (record->event.pressed) { I2C3733_Control_Set(0); } return false; case L_T_BR: if (record->event.pressed) { led_animation_breathing = !led_animation_breathing; if (led_animation_breathing) { gcr_breathe = gcr_desired; led_animation_breathe_cur = BREATHE_MIN_STEP; breathe_dir = 1; } } return false; case L_T_PTD: if (record->event.pressed) { scroll_effect++; if (scroll_effect == 1) { //Patterns with scroll move horizontal (Right to left) led_animation_direction = 1; led_animation_orientation = 0; led_animation_circular = 0; } else if (scroll_effect == 2) { //Patterns with scroll move vertical (Top to bottom) led_animation_direction = 1; led_animation_orientation = 1; led_animation_circular = 0; } else if (scroll_effect == 3) { //Patterns with scroll move vertical (Bottom to top) led_animation_direction = 0; led_animation_orientation = 1; led_animation_circular = 0; } else if (scroll_effect == 4) { //Patterns with scroll explode from center led_animation_direction = 0; led_animation_orientation = 0; led_animation_circular = 1; } else if (scroll_effect == 5) { //Patterns with scroll implode on center led_animation_direction = 1; led_animation_orientation = 0; led_animation_circular = 1; } else { //Patterns with scroll move horizontal (Left to right) scroll_effect = 0; led_animation_direction = 0; led_animation_orientation = 0; led_animation_circular = 0; } } return false; case U_T_AGCR: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode"); } return false; case DBG_FAC: if (record->event.pressed && MODS_SHIFT && MODS_CTRL) { led_mfg_test_mode = LED_MFG_TEST_MODE_ON; led_lighting_mode = LED_MODE_NORMAL; led_edge_brightness = 1; led_edge_mode = LED_EDGE_MODE_ALL; led_animation_breathing = 0; led_animation_id = 7; //led_programs.c led_setups leds_white index gcr_desired = LED_GCR_MAX; I2C3733_Control_Set(1); } return false; case DBG_TOG: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode"); } return false; case DBG_MTRX: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix"); } return false; case DBG_KBD: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard"); } return false; case DBG_MOU: if (record->event.pressed) { TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse"); } return false; case MD_BOOT: if (record->event.pressed) { key_timer = timer_read32(); } else { if (timer_elapsed32(key_timer) >= BOOTKEY_HOLD_MS) { reset_keyboard(); } } return false; default: return true; //Process all other keycodes normally } }; /* LED identifiers: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 18, 15, 19, 16, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102 EDGE_LED: ___ ... ___ ___ ___ ⋮ ⋮ ___ ___ ___ ... ___ NUM_LOCK 167 CAPS_LOCK 168 SCRL_LOCK 169 */ led_instruction_t led_instructions[] = { //LEDs are normally inactive, no processing is performed on theme //Flags are used in matching criteria for an LED to be active and indicate how to color it //Flags can be found in tmk_core/protocol/arm_atsam/led_matrix.h (prefixed with LED_FLAG_) //LED IDs can be found in config_led.h in the keyboard's directory // Highlight all options when holding down the modifier key // Enable LEDs on keys // Only on layer 0 // (id0 32 - 1: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF) // (id1 64 - 33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF) // (id2 96 - 65: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF) // (id3 128 - 97: 0000 0000 0000 0000 0000 0000 0011 1111 = 0x0000003F) // // Enable LEDs 23 - 32, 41, 42, 43, 59, 60, 61, 62, 64, 70, 75, 79, 90, 95, 100, 101, 102 // Only on layer 1 // (id0 32 - 1: 1111 1111 1100 0000 0000 0000 0000 0000 = 0xFFC00000) // (id1 64 - 33: 1011 1100 0000 0000 0000 0111 0000 0000 = 0xBC000700) // (id2 96 - 65: 0100 0010 0000 0000 0100 0100 0010 0000 = 0x42004420) // (id3 128 - 97: 0000 0000 0000 0000 0000 0000 0011 1000 = 0x00000038) // // Enable LED 78, 44 on layer 1 in orange // (id1 64 - 33: 0000 0000 0000 0000 0000 1000 0000 0000 = 0x00000800) // (id2 96 - 65: 0000 0000 0000 0000 0010 0000 0000 0000 = 0x00002000) // // Enable LED 67 on layer 1 in red // (id2 96 - 65: 0000 0000 0000 0000 0000 0000 0000 0100 = 0x00000004) // // Enable LEDs 18, 39, 40, 42, 44, 59, 60, 61, 62, 65, 66, 76, 77, 79, 80, 81, 90, 96, 100, 101, 102 // Only on layer 2 // (id0 32 - 1: 0000 0000 0000 0010 0000 0000 0000 0000 = 0x00020000) // (id1 64 - 33: 0011 1100 0000 0000 0000 1010 1100 0000 = 0x3C000AC0) // (id2 96 - 65: 1000 0010 0000 0001 1101 1000 0000 0011 = 0x8201D803) // (id3 128 - 97: 0000 0000 0000 0000 0000 0000 0011 1000 = 0x00000038) // // Always enable the edge: 166 - 103 // Always allow the indicator LEDs to be enabled if they want to: 169, 168, 167 // (id3 128 - 97: 1111 1111 1111 1111 1111 1111 1100 0000 = 0xFFFFFFC0) // (id4 160 - 129: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF) // (id5 192 - 161: 0000 0000 0000 0000 0000 0001 1111 1111 = 0x000001FF) { .flags = LED_FLAG_USE_ROTATE_PATTERN | LED_FLAG_MATCH_LAYER | LED_FLAG_MATCH_ID, .layer = 0, .id0 = 0xFFFFFFFF, .id1 = 0xFFFFFFFF, .id2 = 0xFFFFFFFF, .id3 = 0x0000003F }, { .flags = LED_FLAG_USE_RGB | LED_FLAG_MATCH_LAYER | LED_FLAG_MATCH_ID, .layer = 1, .r = 255, .g = 255, .b = 255, .id0 = 0xFFC00000, .id1 = 0xBC000700, .id2 = 0x42004420, .id3 = 0x00000038 }, { .flags = LED_FLAG_USE_RGB | LED_FLAG_MATCH_LAYER | LED_FLAG_MATCH_ID, .layer = 1, .r = 255, .g = 165, .b = 0, .id1 = 0x00000800, .id2 = 0x00002000 }, { .flags = LED_FLAG_USE_RGB | LED_FLAG_MATCH_LAYER | LED_FLAG_MATCH_ID, .layer = 1, .r = 255, .g = 0, .b = 0, .id2 = 0x00000004 }, { .flags = LED_FLAG_USE_RGB | LED_FLAG_MATCH_LAYER | LED_FLAG_MATCH_ID, .layer = 2, .r = 255, .g = 255, .b = 255, .id0 = 0x00020000, .id1 = 0x3C000AC0, .id2 = 0x8201D803, .id3 = 0x00000038 }, { .flags = LED_FLAG_USE_ROTATE_PATTERN | LED_FLAG_MATCH_ID, .id3 = 0xFFFFFFC0, .id4 = 0xFFFFFFFF, .id5 = 0x000001FF }, //end must be set to 1 to indicate end of instruction set { .end = 1 } };