qmk_firmware

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

sweep.c (13339B)


      1 /* Copyright 2022 splitkb.com <support@splitkb.com>
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 2 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15  */
     16 
     17 #include "quantum.h"
     18 
     19 // The first four layers gets a name for readability, which is then used in the OLED below.
     20 enum layers {
     21   _DEFAULT,
     22   _LOWER,
     23   _RAISE,
     24   _ADJUST
     25 };
     26 
     27 #ifdef OLED_ENABLE
     28 // NOTE: Most of the OLED code was originally written by Soundmonster for the Corne,
     29 // and has been copied directly from `crkbd/soundmonster/keymap.c`
     30 
     31 oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
     32     return OLED_ROTATION_270;
     33 }
     34 
     35 void render_space(void) {
     36     oled_write_P(PSTR("     "), false);
     37 }
     38 
     39 void render_mod_status_gui_alt(uint8_t modifiers) {
     40     static const char PROGMEM gui_off_1[] = {0x85, 0x86, 0};
     41     static const char PROGMEM gui_off_2[] = {0xa5, 0xa6, 0};
     42     static const char PROGMEM gui_on_1[] = {0x8d, 0x8e, 0};
     43     static const char PROGMEM gui_on_2[] = {0xad, 0xae, 0};
     44 
     45     static const char PROGMEM alt_off_1[] = {0x87, 0x88, 0};
     46     static const char PROGMEM alt_off_2[] = {0xa7, 0xa8, 0};
     47     static const char PROGMEM alt_on_1[] = {0x8f, 0x90, 0};
     48     static const char PROGMEM alt_on_2[] = {0xaf, 0xb0, 0};
     49 
     50     // fillers between the modifier icons bleed into the icon frames
     51     static const char PROGMEM off_off_1[] = {0xc5, 0};
     52     static const char PROGMEM off_off_2[] = {0xc6, 0};
     53     static const char PROGMEM on_off_1[] = {0xc7, 0};
     54     static const char PROGMEM on_off_2[] = {0xc8, 0};
     55     static const char PROGMEM off_on_1[] = {0xc9, 0};
     56     static const char PROGMEM off_on_2[] = {0xca, 0};
     57     static const char PROGMEM on_on_1[] = {0xcb, 0};
     58     static const char PROGMEM on_on_2[] = {0xcc, 0};
     59 
     60     if(modifiers & MOD_MASK_GUI) {
     61         oled_write_P(gui_on_1, false);
     62     } else {
     63         oled_write_P(gui_off_1, false);
     64     }
     65 
     66     if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) {
     67         oled_write_P(on_on_1, false);
     68     } else if(modifiers & MOD_MASK_GUI) {
     69         oled_write_P(on_off_1, false);
     70     } else if(modifiers & MOD_MASK_ALT) {
     71         oled_write_P(off_on_1, false);
     72     } else {
     73         oled_write_P(off_off_1, false);
     74     }
     75 
     76     if(modifiers & MOD_MASK_ALT) {
     77         oled_write_P(alt_on_1, false);
     78     } else {
     79         oled_write_P(alt_off_1, false);
     80     }
     81 
     82     if(modifiers & MOD_MASK_GUI) {
     83         oled_write_P(gui_on_2, false);
     84     } else {
     85         oled_write_P(gui_off_2, false);
     86     }
     87 
     88     if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) {
     89         oled_write_P(on_on_2, false);
     90     } else if(modifiers & MOD_MASK_GUI) {
     91         oled_write_P(on_off_2, false);
     92     } else if(modifiers & MOD_MASK_ALT) {
     93         oled_write_P(off_on_2, false);
     94     } else {
     95         oled_write_P(off_off_2, false);
     96     }
     97 
     98     if(modifiers & MOD_MASK_ALT) {
     99         oled_write_P(alt_on_2, false);
    100     } else {
    101         oled_write_P(alt_off_2, false);
    102     }
    103 }
    104 
    105 void render_mod_status_ctrl_shift(uint8_t modifiers) {
    106     static const char PROGMEM ctrl_off_1[] = {0x89, 0x8a, 0};
    107     static const char PROGMEM ctrl_off_2[] = {0xa9, 0xaa, 0};
    108     static const char PROGMEM ctrl_on_1[] = {0x91, 0x92, 0};
    109     static const char PROGMEM ctrl_on_2[] = {0xb1, 0xb2, 0};
    110 
    111     static const char PROGMEM shift_off_1[] = {0x8b, 0x8c, 0};
    112     static const char PROGMEM shift_off_2[] = {0xab, 0xac, 0};
    113     static const char PROGMEM shift_on_1[] = {0xcd, 0xce, 0};
    114     static const char PROGMEM shift_on_2[] = {0xcf, 0xd0, 0};
    115 
    116     // fillers between the modifier icons bleed into the icon frames
    117     static const char PROGMEM off_off_1[] = {0xc5, 0};
    118     static const char PROGMEM off_off_2[] = {0xc6, 0};
    119     static const char PROGMEM on_off_1[] = {0xc7, 0};
    120     static const char PROGMEM on_off_2[] = {0xc8, 0};
    121     static const char PROGMEM off_on_1[] = {0xc9, 0};
    122     static const char PROGMEM off_on_2[] = {0xca, 0};
    123     static const char PROGMEM on_on_1[] = {0xcb, 0};
    124     static const char PROGMEM on_on_2[] = {0xcc, 0};
    125 
    126     if(modifiers & MOD_MASK_CTRL) {
    127         oled_write_P(ctrl_on_1, false);
    128     } else {
    129         oled_write_P(ctrl_off_1, false);
    130     }
    131 
    132     if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) {
    133         oled_write_P(on_on_1, false);
    134     } else if(modifiers & MOD_MASK_CTRL) {
    135         oled_write_P(on_off_1, false);
    136     } else if(modifiers & MOD_MASK_SHIFT) {
    137         oled_write_P(off_on_1, false);
    138     } else {
    139         oled_write_P(off_off_1, false);
    140     }
    141 
    142     if(modifiers & MOD_MASK_SHIFT) {
    143         oled_write_P(shift_on_1, false);
    144     } else {
    145         oled_write_P(shift_off_1, false);
    146     }
    147 
    148     if(modifiers & MOD_MASK_CTRL) {
    149         oled_write_P(ctrl_on_2, false);
    150     } else {
    151         oled_write_P(ctrl_off_2, false);
    152     }
    153 
    154     if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) {
    155         oled_write_P(on_on_2, false);
    156     } else if(modifiers & MOD_MASK_CTRL) {
    157         oled_write_P(on_off_2, false);
    158     } else if(modifiers & MOD_MASK_SHIFT) {
    159         oled_write_P(off_on_2, false);
    160     } else {
    161         oled_write_P(off_off_2, false);
    162     }
    163 
    164     if(modifiers & MOD_MASK_SHIFT) {
    165         oled_write_P(shift_on_2, false);
    166     } else {
    167         oled_write_P(shift_off_2, false);
    168     }
    169 }
    170 
    171 void render_logo(void) {
    172     static const char PROGMEM aurora_logo[] = {
    173         0x00, 0x00, 0x00, 0xe0, 0x00, 0xf8, 0xc0, 0xf8, 0xe0, 0xc0, 0xfc, 0x00, 0x7e, 0x18, 0x00, 0x80,
    174         0x00, 0x02, 0x80, 0xf0, 0x00, 0xc0, 0x80, 0xf8, 0xc0, 0xe0, 0x70, 0x60, 0x3c, 0x38, 0x3c, 0x1c,
    175         0x00, 0x3f, 0x0c, 0x0f, 0x1f, 0x03, 0x07, 0x01, 0xc3, 0x00, 0xe0, 0x80, 0x00, 0xe0, 0x80, 0xf8,
    176         0x80, 0xc0, 0xf7, 0xc7, 0x6f, 0x7b, 0x39, 0x30, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xc0, 0xc2, 0xe0,
    177         0x00, 0x40, 0x38, 0x30, 0x38, 0x1e, 0x18, 0x1e, 0x0f, 0x0c, 0x07, 0x07, 0x07, 0x03, 0x03, 0x21,
    178         0x21, 0x31, 0x30, 0x18, 0x18, 0x1c, 0x08, 0x0c, 0x0e, 0x07, 0x06, 0x07, 0x03, 0xc3, 0x03, 0x01,
    179         0x4c, 0xcc, 0xc2, 0xc2, 0x41, 0x49, 0x09, 0x2b, 0x2a, 0x6a, 0x6e, 0x24, 0x24, 0x04, 0x92, 0x92,
    180         0xb1, 0xf1, 0xf1, 0xf2, 0xe6, 0xa4, 0xa4, 0x04, 0x04, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28
    181     };
    182     oled_write_raw_P(aurora_logo, sizeof(aurora_logo));
    183     oled_set_cursor(0, 4);
    184 }
    185 
    186 void render_logo_text(void) {
    187     oled_write_P(PSTR("sweep"), false);
    188 }
    189 
    190 void render_kb_LED_state(void) {
    191     // Host Keyboard LED Status
    192     led_t led_usb_state = host_keyboard_led_state();
    193     oled_write_P(led_usb_state.num_lock ? PSTR("N ") : PSTR("  "), false);
    194     oled_write_P(led_usb_state.caps_lock ? PSTR("C ") : PSTR("  "), false);
    195     oled_write_P(led_usb_state.scroll_lock ? PSTR("S ") : PSTR("  "), false);
    196 }
    197 
    198 void render_layer_state(void) {
    199     static const char PROGMEM default_layer[] = {
    200         0x20, 0x94, 0x95, 0x96, 0x20,
    201         0x20, 0xb4, 0xb5, 0xb6, 0x20,
    202         0x20, 0xd4, 0xd5, 0xd6, 0x20, 0};
    203     static const char PROGMEM raise_layer[] = {
    204         0x20, 0x97, 0x98, 0x99, 0x20,
    205         0x20, 0xb7, 0xb8, 0xb9, 0x20,
    206         0x20, 0xd7, 0xd8, 0xd9, 0x20, 0};
    207     static const char PROGMEM lower_layer[] = {
    208         0x20, 0x9a, 0x9b, 0x9c, 0x20,
    209         0x20, 0xba, 0xbb, 0xbc, 0x20,
    210         0x20, 0xda, 0xdb, 0xdc, 0x20, 0};
    211     static const char PROGMEM adjust_layer[] = {
    212         0x20, 0x9d, 0x9e, 0x9f, 0x20,
    213         0x20, 0xbd, 0xbe, 0xbf, 0x20,
    214         0x20, 0xdd, 0xde, 0xdf, 0x20, 0};
    215 
    216     switch (get_highest_layer(layer_state | default_layer_state)) {
    217         case _LOWER:
    218             oled_write_P(lower_layer, false);
    219             break;
    220         case _RAISE:
    221             oled_write_P(raise_layer, false);
    222             break;
    223         case _ADJUST:
    224             oled_write_P(adjust_layer, false);
    225             break;
    226         default:
    227             oled_write_P(default_layer, false);
    228     }
    229 }
    230 
    231 
    232 bool oled_task_kb(void) {
    233     if (!oled_task_user()) {
    234         return false;
    235     }
    236     if (is_keyboard_master()) {
    237         // Renders the current keyboard state (layers and mods)
    238         render_logo();
    239         render_logo_text();
    240         render_space();
    241         render_layer_state();
    242         render_space();
    243         render_mod_status_gui_alt(get_mods()|get_oneshot_mods());
    244         render_mod_status_ctrl_shift(get_mods()|get_oneshot_mods());
    245         render_kb_LED_state();
    246     } else {
    247         // clang-format off
    248         static const char PROGMEM aurora_art[] = {
    249             0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x08, 0x00, 0x00,
    250             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
    251             0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40,
    252             0xe0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x80,
    253             0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x80, 0x00, 0xf0, 0x00, 0x00, 0xc0,
    254             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
    255             0x81, 0x00, 0xc0, 0x00, 0xfe, 0x00, 0xfc, 0x00, 0xff, 0x20, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0xff,
    256             0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf8, 0x00, 0x00, 0xf8,
    257             0xff, 0x10, 0xff, 0x84, 0xff, 0x60, 0xff, 0x36, 0xff, 0x0f, 0xff, 0x3f, 0x00, 0x5f, 0x00, 0x05,
    258             0x80, 0x00, 0x80, 0x00, 0xc0, 0x38, 0x00, 0xec, 0xf0, 0x00, 0xfb, 0x80, 0xff, 0xf0, 0xff, 0xef,
    259             0xff, 0xe8, 0xff, 0x03, 0xff, 0x0c, 0xff, 0x00, 0xff, 0x00, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x80,
    260             0xff, 0x20, 0xff, 0xd0, 0xff, 0xe0, 0xfe, 0xf8, 0xff, 0xfc, 0xff, 0xff, 0x0f, 0xff, 0x01, 0x3f,
    261             0xff, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x03, 0x00, 0xfe, 0x80, 0xfe, 0x00, 0xc0, 0xff, 0xc4, 0xfb,
    262             0xff, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x07, 0xff, 0x03, 0x3f, 0x00, 0x0f, 0xc0, 0x00,
    263             0x00, 0x00, 0xb8, 0x00, 0xff, 0x40, 0xbe, 0xf0, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
    264             0x1f, 0xff, 0x67, 0x00, 0xef, 0x00, 0x1f, 0x00, 0x00, 0x07, 0x00, 0x00, 0xe0, 0x00, 0xff, 0xf0,
    265             0xff, 0x88, 0xff, 0xc4, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x7f, 0x0f, 0xff,
    266             0x00, 0x07, 0xfe, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xc0, 0x3f, 0xf8, 0xe7, 0xff,
    267             0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0x1f, 0x3f, 0x01, 0xff, 0x0b, 0x00, 0xff, 0x00, 0x00, 0x05,
    268             0x00, 0x00, 0x00, 0xe0, 0x00, 0xf8, 0x60, 0x80, 0xfe, 0xe3, 0xfc, 0xff, 0x1e, 0xff, 0xff, 0x23,
    269             0xff, 0x09, 0xff, 0x20, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x40, 0x00, 0xc0, 0x00, 0xfc,
    270             0xe0, 0xfc, 0xf0, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0x0f, 0xff, 0x07, 0x1f, 0x00, 0x01, 0x0f, 0x00,
    271             0x0f, 0x00, 0x81, 0x70, 0x0c, 0xf0, 0x80, 0x00, 0x00, 0xe4, 0xf8, 0xe6, 0x70, 0x3f, 0xcf, 0xff,
    272             0x1f, 0xff, 0x48, 0xff, 0x0f, 0x00, 0x07, 0x00, 0x00, 0x43, 0x60, 0xf8, 0xf0, 0xfe, 0x38, 0xfe,
    273             0x00, 0xfc, 0x03, 0x00, 0xc8, 0x72, 0xcf, 0xfc, 0x00, 0x03, 0x0f, 0x01, 0xe0, 0x1c, 0xe0, 0x03,
    274             0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x06, 0xf9, 0x00, 0x03, 0x00, 0x07,
    275             0xff, 0x00, 0x10, 0x12, 0xc9, 0xf0, 0xcf, 0xb4, 0x7f, 0x80, 0xe0, 0x1e, 0x01, 0x40, 0x65, 0x5e,
    276             0xe0, 0x00, 0x00, 0xf0, 0x0c, 0xf0, 0x00, 0x80, 0x7e, 0x01, 0x80, 0x93, 0xfc, 0xc0, 0x00, 0x00,
    277             0x00, 0x00, 0x00, 0x00, 0x89, 0x18, 0x2c, 0x46, 0x00, 0x07, 0x21, 0x10, 0x10, 0x80, 0x09, 0x13,
    278             0x31, 0xbf, 0xff, 0x00, 0x08, 0x1a, 0xf7, 0x0f, 0x00, 0x00, 0x44, 0x45, 0x34, 0xbf, 0xb8, 0x00,
    279             0x10, 0xf0, 0x08, 0xf4, 0x18, 0x11, 0xfc, 0x18, 0xfb, 0x0e, 0x10, 0xf8, 0x04, 0xf8, 0x10, 0x20,
    280             0x18, 0x09, 0xff, 0x0c, 0xea, 0x1f, 0x28, 0x60, 0x30, 0xf8, 0x20, 0xc0, 0x42, 0x33, 0x21, 0x00
    281         };
    282         // clang-format on
    283         oled_write_raw_P(aurora_art, sizeof(aurora_art));
    284     }
    285     return false;
    286 }
    287 #endif
    288 
    289 #ifdef ENCODER_ENABLE
    290 bool encoder_update_kb(uint8_t index, bool clockwise) {
    291     if (!encoder_update_user(index, clockwise)) {
    292         return false;
    293     }
    294     // 0 and 1 are left-half encoders,
    295     // 2 and 3 are right-half encoders
    296     if (index == 0) {
    297         // Volume control
    298         if (clockwise) {
    299             tap_code(KC_VOLU);
    300         } else {
    301             tap_code(KC_VOLD);
    302         }
    303     } else if (index == 1) {
    304         // Volume control
    305         if (clockwise) {
    306             tap_code(KC_VOLU);
    307         } else {
    308             tap_code(KC_VOLD);
    309         }
    310     } else if (index == 2) {
    311         // Page up/Page down
    312         if (clockwise) {
    313             tap_code(KC_PGDN);
    314         } else {
    315             tap_code(KC_PGUP);
    316         }
    317     } else if (index == 3) {
    318         // Page up/Page down
    319         if (clockwise) {
    320             tap_code(KC_PGDN);
    321         } else {
    322             tap_code(KC_PGUP);
    323         }
    324     }
    325     return true;
    326 }
    327 #endif