launch_1.c (5524B)
1 /* 2 * Copyright (C) 2021 System76 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18 #include "quantum.h" 19 #include "eeprom.h" 20 21 #include "usb_mux.h" 22 23 // clang-format off 24 bool eeprom_is_valid(void) { 25 return ( 26 eeprom_read_word(((void *)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC && 27 eeprom_read_byte(((void *)EEPROM_VERSION_ADDR)) == EEPROM_VERSION 28 ); 29 } 30 // clang-format on 31 32 void eeprom_set_valid(bool valid) { 33 eeprom_update_word(((void *)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF); 34 eeprom_update_byte(((void *)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF); 35 } 36 37 void bootmagic_lite_reset_eeprom(void) { 38 // Set the keyboard-specific EEPROM state as invalid 39 eeprom_set_valid(false); 40 // Set the TMK/QMK EEPROM state as invalid 41 eeconfig_disable(); 42 } 43 44 // The lite version of TMK's bootmagic based on Wilba. 45 // 100% less potential for accidentally making the keyboard do stupid things. 46 void bootmagic_lite(void) { 47 // Perform multiple scans because debouncing can't be turned off. 48 matrix_scan(); 49 #if defined(DEBOUNCE) && DEBOUNCE > 0 50 wait_ms(DEBOUNCE * 2); 51 #else 52 wait_ms(30); 53 #endif 54 matrix_scan(); 55 56 // If the configured key (commonly Esc) is held down on power up, 57 // reset the EEPROM valid state and jump to bootloader. 58 uint8_t row = 0; // BOOTMAGIC_LITE_ROW; 59 uint8_t col = 0; // BOOTMAGIC_LITE_COLUMN; 60 61 if (matrix_get_row(row) & (1 << col)) { 62 bootmagic_lite_reset_eeprom(); 63 64 // Jump to bootloader. 65 bootloader_jump(); 66 } 67 } 68 69 void system76_ec_rgb_eeprom(bool write); 70 void system76_ec_rgb_layer(layer_state_t layer_state); 71 void system76_ec_unlock(void); 72 bool system76_ec_is_unlocked(void); 73 74 extern rgb_config_t layer_rgb[DYNAMIC_KEYMAP_LAYER_COUNT]; 75 76 void matrix_init_kb(void) { 77 usb_mux_init(); 78 79 bootmagic_lite(); 80 if (!eeprom_is_valid()) { 81 dynamic_keymap_reset(); 82 dynamic_keymap_macro_reset(); 83 system76_ec_rgb_eeprom(true); 84 eeprom_set_valid(true); 85 } else { 86 system76_ec_rgb_eeprom(false); 87 } 88 89 system76_ec_rgb_layer(layer_state); 90 91 matrix_init_user(); 92 } 93 94 void housekeeping_task_kb(void) { 95 usb_mux_event(); 96 } 97 98 #define LEVEL(value) (uint8_t)(((uint16_t)value) * ((uint16_t)RGB_MATRIX_MAXIMUM_BRIGHTNESS) / ((uint16_t)255)) 99 100 // clang-format off 101 static const uint8_t levels[] = { 102 LEVEL(48), 103 LEVEL(72), 104 LEVEL(96), 105 LEVEL(144), 106 LEVEL(192), 107 LEVEL(255) 108 }; 109 // clang-format on 110 111 static uint8_t toggle_level = RGB_MATRIX_MAXIMUM_BRIGHTNESS; 112 extern bool input_disabled; 113 114 static void set_value_all_layers(uint8_t value) { 115 if (!system76_ec_is_unlocked()) { 116 for (int8_t layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) { 117 layer_rgb[layer].hsv.v = value; 118 } 119 system76_ec_rgb_layer(layer_state); 120 } 121 } 122 123 bool process_record_kb(uint16_t keycode, keyrecord_t *record) { 124 if (input_disabled) { 125 return false; 126 } 127 128 if (!process_record_user(keycode, record)) { 129 return false; 130 } 131 132 switch (keycode) { 133 case QK_BOOT: 134 if (record->event.pressed) { 135 system76_ec_unlock(); 136 } 137 #ifdef SYSTEM76_EC 138 return false; 139 #else 140 return true; 141 #endif 142 case QK_RGB_MATRIX_VALUE_DOWN: 143 if (record->event.pressed) { 144 uint8_t level = rgb_matrix_config.hsv.v; 145 for (int i = sizeof(levels) - 1; i >= 0; i--) { 146 if (levels[i] < level) { 147 level = levels[i]; 148 break; 149 } 150 } 151 set_value_all_layers(level); 152 } 153 return false; 154 case QK_RGB_MATRIX_VALUE_UP: 155 if (record->event.pressed) { 156 uint8_t level = rgb_matrix_config.hsv.v; 157 for (int i = 0; i < sizeof(levels); i++) { 158 if (levels[i] > level) { 159 level = levels[i]; 160 break; 161 } 162 } 163 set_value_all_layers(level); 164 } 165 return false; 166 case QK_RGB_MATRIX_TOGGLE: 167 if (record->event.pressed) { 168 uint8_t level = 0; 169 if (rgb_matrix_config.hsv.v == 0) { 170 level = toggle_level; 171 } else { 172 toggle_level = rgb_matrix_config.hsv.v; 173 } 174 set_value_all_layers(level); 175 } 176 return false; 177 } 178 179 return true; 180 } 181 182 layer_state_t layer_state_set_kb(layer_state_t layer_state) { 183 system76_ec_rgb_layer(layer_state); 184 185 return layer_state_set_user(layer_state); 186 } 187 188 #ifdef CONSOLE_ENABLE 189 void keyboard_post_init_kb(void) { 190 debug_enable = true; 191 debug_matrix = false; 192 debug_keyboard = false; 193 194 keyboard_post_init_user(); 195 } 196 #endif // CONSOLE_ENABLE