qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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