moonlander.c (12002B)
1 /* Copyright 2020 ZSA Technology Labs, Inc <@zsa> 2 * Copyright 2020 Jack Humbert <jack.humb@gmail.com> 3 * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com> 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include "moonlander.h" 20 21 keyboard_config_t keyboard_config; 22 23 bool mcp23018_leds[3] = {0, 0, 0}; 24 bool is_launching = false; 25 26 #if defined(DEFERRED_EXEC_ENABLE) 27 # if defined(DYNAMIC_MACRO_ENABLE) 28 deferred_token dynamic_macro_token = INVALID_DEFERRED_TOKEN; 29 30 static uint32_t dynamic_macro_led(uint32_t trigger_time, void *cb_arg) { 31 static bool led_state = true; 32 if (!is_launching) { 33 led_state = !led_state; 34 ML_LED_3(led_state); 35 } 36 return 100; 37 } 38 39 bool dynamic_macro_record_start_kb(int8_t direction) { 40 if (!dynamic_macro_record_start_user(direction)) { 41 return false; 42 } 43 if (dynamic_macro_token == INVALID_DEFERRED_TOKEN) { 44 ML_LED_3(true); 45 dynamic_macro_token = defer_exec(100, dynamic_macro_led, NULL); 46 } 47 return true; 48 } 49 50 bool dynamic_macro_record_end_kb(int8_t direction) { 51 if (!dynamic_macro_record_end_user(direction)) { 52 return false; 53 } 54 if (cancel_deferred_exec(dynamic_macro_token)) { 55 dynamic_macro_token = INVALID_DEFERRED_TOKEN; 56 ML_LED_3(false); 57 } 58 return false; 59 } 60 # endif 61 62 static uint32_t startup_exec(uint32_t trigger_time, void *cb_arg) { 63 static uint8_t startup_loop = 0; 64 65 switch (startup_loop++) { 66 case 0: 67 ML_LED_1(true); 68 ML_LED_2(false); 69 ML_LED_3(false); 70 ML_LED_4(false); 71 ML_LED_5(false); 72 ML_LED_6(false); 73 break; 74 case 1: 75 ML_LED_2(true); 76 break; 77 case 2: 78 ML_LED_3(true); 79 break; 80 case 3: 81 ML_LED_4(true); 82 break; 83 case 4: 84 ML_LED_5(true); 85 break; 86 case 5: 87 ML_LED_6(true); 88 break; 89 case 6: 90 ML_LED_1(false); 91 break; 92 case 7: 93 ML_LED_2(false); 94 break; 95 case 8: 96 ML_LED_3(false); 97 break; 98 case 9: 99 ML_LED_4(false); 100 break; 101 case 10: 102 ML_LED_5(false); 103 break; 104 case 11: 105 ML_LED_6(false); 106 break; 107 case 12: 108 is_launching = false; 109 layer_state_set_kb(layer_state); 110 return 0; 111 } 112 return 250; 113 } 114 #endif 115 116 void keyboard_pre_init_kb(void) { 117 gpio_set_pin_output(B5); 118 gpio_set_pin_output(B4); 119 gpio_set_pin_output(B3); 120 121 gpio_write_pin_low(B5); 122 gpio_write_pin_low(B4); 123 gpio_write_pin_low(B3); 124 125 keyboard_pre_init_user(); 126 } 127 128 #if !defined(MOONLANDER_USER_LEDS) 129 layer_state_t layer_state_set_kb(layer_state_t state) { 130 state = layer_state_set_user(state); 131 if (is_launching || !keyboard_config.led_level) return state; 132 bool LED_1 = false; 133 bool LED_2 = false; 134 bool LED_3 = false; 135 bool LED_4 = false; 136 bool LED_5 = false; 137 #if !defined(CAPS_LOCK_STATUS) 138 bool LED_6 = false; 139 #endif 140 141 uint8_t layer = get_highest_layer(state); 142 switch (layer) { 143 case 1: 144 LED_1 = true; 145 LED_4 = true; 146 break; 147 case 2: 148 LED_2 = true; 149 LED_5 = true; 150 break; 151 case 3: 152 LED_3 = true; 153 #if !defined(CAPS_LOCK_STATUS) 154 LED_6 = true; 155 #endif 156 break; 157 case 4: 158 LED_4 = true; 159 break; 160 case 5: 161 LED_5 = true; 162 break; 163 case 6: 164 #if !defined(CAPS_LOCK_STATUS) 165 LED_6 = true; 166 #endif 167 break; 168 default: 169 break; 170 } 171 172 ML_LED_1(LED_1); 173 ML_LED_2(LED_2); 174 ML_LED_3(LED_3); 175 ML_LED_4(LED_4); 176 ML_LED_5(LED_5); 177 #if !defined(CAPS_LOCK_STATUS) 178 ML_LED_6(LED_6); 179 #endif 180 181 return state; 182 } 183 #endif 184 185 #ifdef RGB_MATRIX_ENABLE 186 // clang-format off 187 const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { 188 {0, C3_2, C1_1, C4_2}, 189 {0, C2_2, C1_2, C4_3}, 190 {0, C2_3, C1_3, C3_3}, 191 {0, C2_4, C1_4, C3_4}, 192 {0, C2_5, C1_5, C3_5}, 193 {0, C2_6, C1_6, C3_6}, 194 {0, C2_7, C1_7, C3_7}, 195 {0, C2_8, C1_8, C3_8}, 196 {0, C3_1, C2_1, C4_1}, 197 198 {0, C7_8, C6_8, C8_8}, 199 {0, C7_7, C6_7, C9_8}, 200 {0, C8_7, C6_6, C9_7}, 201 {0, C8_6, C7_6, C9_6}, 202 {0, C8_5, C7_5, C9_5}, 203 {0, C8_4, C7_4, C9_4}, 204 {0, C8_3, C7_3, C9_3}, 205 {0, C8_2, C7_2, C9_2}, 206 {0, C8_1, C7_1, C9_1}, 207 208 {0, C3_10, C1_9, C4_10}, 209 {0, C2_10, C1_10, C4_11}, 210 {0, C2_11, C1_11, C3_11}, 211 {0, C2_12, C1_12, C3_12}, 212 {0, C2_13, C1_13, C3_13}, 213 {0, C2_14, C1_14, C3_14}, 214 {0, C2_15, C1_15, C3_15}, 215 {0, C2_16, C1_16, C3_16}, 216 {0, C3_9, C2_9, C4_9}, 217 218 {0, C7_16, C6_16, C8_16}, 219 {0, C7_15, C6_15, C9_16}, 220 {0, C8_15, C6_14, C9_15}, 221 {0, C8_10, C7_10, C9_10}, 222 {0, C8_9, C7_9, C9_9}, 223 {0, C8_11, C7_11, C9_11}, 224 {0, C8_12, C7_12, C9_12}, 225 {0, C8_13, C7_13, C9_13}, 226 {0, C8_14, C7_14, C9_14}, 227 228 {1, C3_2, C1_1, C4_2}, 229 {1, C2_2, C1_2, C4_3}, 230 {1, C2_3, C1_3, C3_3}, 231 {1, C2_4, C1_4, C3_4}, 232 {1, C2_5, C1_5, C3_5}, 233 {1, C2_6, C1_6, C3_6}, 234 {1, C2_7, C1_7, C3_7}, 235 {1, C2_8, C1_8, C3_8}, 236 {1, C3_1, C2_1, C4_1}, 237 238 {1, C7_8, C6_8, C8_8}, 239 {1, C7_7, C6_7, C9_8}, 240 {1, C8_7, C6_6, C9_7}, 241 {1, C8_6, C7_6, C9_6}, 242 {1, C8_5, C7_5, C9_5}, 243 {1, C8_4, C7_4, C9_4}, 244 {1, C8_3, C7_3, C9_3}, 245 {1, C8_2, C7_2, C9_2}, 246 {1, C8_1, C7_1, C9_1}, 247 248 {1, C3_10, C1_9, C4_10}, 249 {1, C2_10, C1_10, C4_11}, 250 {1, C2_11, C1_11, C3_11}, 251 {1, C2_12, C1_12, C3_12}, 252 {1, C2_13, C1_13, C3_13}, 253 {1, C2_14, C1_14, C3_14}, 254 {1, C2_15, C1_15, C3_15}, 255 {1, C2_16, C1_16, C3_16}, 256 {1, C3_9, C2_9, C4_9}, 257 258 {1, C7_16, C6_16, C8_16}, 259 {1, C7_15, C6_15, C9_16}, 260 {1, C8_15, C6_14, C9_15}, 261 {1, C8_10, C7_10, C9_10}, 262 {1, C8_9, C7_9, C9_9}, 263 {1, C8_11, C7_11, C9_11}, 264 {1, C8_12, C7_12, C9_12}, 265 {1, C8_13, C7_13, C9_13}, 266 {1, C8_14, C7_14, C9_14}, 267 }; 268 // clang-format on 269 #endif 270 271 #ifdef AUDIO_ENABLE 272 bool music_mask_kb(uint16_t keycode) { 273 switch (keycode) { 274 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: 275 case QK_TO ... QK_TO_MAX: 276 case QK_MOMENTARY ... QK_MOMENTARY_MAX: 277 case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: 278 case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX: 279 case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: 280 case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: 281 case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: 282 case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: 283 case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: 284 case QK_MOD_TAP ... QK_MOD_TAP_MAX: 285 case AU_ON ... AU_PREV: 286 case QK_BOOT: 287 case QK_CLEAR_EEPROM: 288 return false; 289 default: 290 return music_mask_user(keycode); 291 } 292 } 293 #endif 294 295 #ifdef SWAP_HANDS_ENABLE 296 // swap-hands action needs a matrix to define the swap 297 // clang-format off 298 const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { 299 /* Left hand, matrix positions */ 300 {{6,6}, {5,6}, {4,6}, {3,6}, {2,6}, {1,6},{0,6}}, 301 {{6,7}, {5,7}, {4,7}, {3,7}, {2,7}, {1,7},{0,7}}, 302 {{6,8}, {5,8}, {4,8}, {3,8}, {2,8}, {1,8},{0,8}}, 303 {{6,9}, {5,9}, {4,9}, {3,9}, {2,9}, {1,9},{0,9}}, 304 {{6,10},{5,10},{4,10},{3,10},{2,10},{1,10},{0,10}}, 305 {{6,11},{5,11},{4,11},{3,11},{2,11},{1,11},{0,11}}, 306 /* Right hand, matrix positions */ 307 {{6,0}, {5,0}, {4,0}, {3,0}, {2,0}, {1,0},{0,0}}, 308 {{6,1}, {5,1}, {4,1}, {3,1}, {2,1}, {1,1},{0,1}}, 309 {{6,2}, {5,2}, {4,2}, {3,2}, {2,2}, {1,2},{0,2}}, 310 {{6,3}, {5,3}, {4,3}, {3,3}, {2,3}, {1,3},{0,3}}, 311 {{6,4}, {5,4}, {4,4}, {3,4}, {2,4}, {1,4},{0,4}}, 312 {{6,5}, {5,5}, {4,5}, {3,5}, {2,5}, {1,5},{0,5}}, 313 }; 314 // clang-format on 315 #endif 316 317 #if defined(AUDIO_ENABLE) && defined(MUSIC_MAP) 318 // clang-format off 319 __attribute__ ((weak)) 320 const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = { 321 {58, 59, 60, 61, 62, 63, 64}, 322 {44, 45, 46, 47, 48, 49, 50}, 323 {30, 31, 32, 33, 34, 35, 36}, 324 {18, 19, 20, 21, 22, 23, 0}, 325 { 8, 9, 10, 11, 12, 0, 0}, 326 { 0, 1, 2, 3, 0, 0, 0}, 327 {65, 66, 67, 68, 69, 70, 71}, 328 {51, 52, 53, 54, 55, 56, 57}, 329 {37, 38, 39, 40, 41, 42, 43}, 330 { 0, 24, 25, 26, 27, 28, 29}, 331 { 0, 0, 13, 14, 15, 16, 17}, 332 { 0, 0, 0, 4, 5, 6, 7} 333 }; 334 // clang-format on 335 #endif 336 337 #ifdef CAPS_LOCK_STATUS 338 void led_update_ports(led_t led_state) { 339 ML_LED_6(led_state.caps_lock); 340 } 341 #endif 342 343 bool process_record_kb(uint16_t keycode, keyrecord_t *record) { 344 if (!process_record_user(keycode, record)) { return false; } 345 switch (keycode) { 346 #if !defined(MOONLANDER_USER_LEDS) 347 case LED_LEVEL: 348 if (record->event.pressed) { 349 keyboard_config.led_level ^= 1; 350 eeconfig_update_kb(keyboard_config.raw); 351 if (keyboard_config.led_level) { 352 layer_state_set_kb(layer_state); 353 } else { 354 ML_LED_1(false); 355 ML_LED_2(false); 356 ML_LED_3(false); 357 ML_LED_4(false); 358 ML_LED_5(false); 359 ML_LED_6(false); 360 } 361 } 362 break; 363 #endif 364 #ifdef RGB_MATRIX_ENABLE 365 case TOGGLE_LAYER_COLOR: 366 if (record->event.pressed) { 367 keyboard_config.disable_layer_led ^= 1; 368 if (keyboard_config.disable_layer_led) rgb_matrix_set_color_all(0, 0, 0); 369 eeconfig_update_kb(keyboard_config.raw); 370 } 371 break; 372 case QK_RGB_MATRIX_TOGGLE: 373 if (record->event.pressed) { 374 switch (rgb_matrix_get_flags()) { 375 case LED_FLAG_ALL: { 376 rgb_matrix_set_flags(LED_FLAG_NONE); 377 keyboard_config.rgb_matrix_enable = false; 378 rgb_matrix_set_color_all(0, 0, 0); 379 } break; 380 default: { 381 rgb_matrix_set_flags(LED_FLAG_ALL); 382 keyboard_config.rgb_matrix_enable = true; 383 } break; 384 } 385 eeconfig_update_kb(keyboard_config.raw); 386 } 387 return false; 388 #endif 389 } 390 return true; 391 } 392 393 void keyboard_post_init_kb(void) { 394 keyboard_config.raw = eeconfig_read_kb(); 395 396 if (!keyboard_config.led_level && !keyboard_config.led_level_res) { 397 keyboard_config.led_level = true; 398 keyboard_config.led_level_res = 0b11; 399 eeconfig_update_kb(keyboard_config.raw); 400 } 401 #ifdef RGB_MATRIX_ENABLE 402 rgb_matrix_enable_noeeprom(); 403 #endif 404 #if defined(DEFERRED_EXEC_ENABLE) 405 is_launching = true; 406 defer_exec(500, startup_exec, NULL); 407 #endif 408 keyboard_post_init_user(); 409 } 410 411 void eeconfig_init_kb(void) { // EEPROM is getting reset! 412 keyboard_config.raw = 0; 413 keyboard_config.rgb_matrix_enable = true; 414 keyboard_config.led_level = true; 415 keyboard_config.led_level_res = 0b11; 416 eeconfig_update_kb(keyboard_config.raw); 417 eeconfig_init_user(); 418 }