qmk_firmware

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

oled.c (9436B)


      1 /*
      2 Copyright 2021 gregorio
      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 2 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 <http://www.gnu.org/licenses/>.
     16 */
     17 
     18 #include "oled.h"
     19 #include "rubi.h"
     20 
     21 bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) {
     22     return process_record_user(keycode, record);
     23 }
     24 
     25 void change_oled_mode(void) {
     26     oled_mode = (oled_mode + 1) % _NUM_OLED_MODES;
     27 }
     28 
     29 void render_layer_section(void) {
     30     // Layer indicators
     31     static const char PROGMEM layer_0[] = {0xc8, 0xc9, 0};
     32     static const char PROGMEM layer_1[] = {0xca, 0xcb, 0};
     33     static const char PROGMEM layer_2[] = {0xcc, 0xcd, 0};
     34     static const char PROGMEM layer_3[] = {0xce, 0xcf, 0};
     35 
     36     oled_set_cursor(oled_max_chars()-15, 0);
     37     oled_write_P(PSTR("LAYER"), false);
     38     switch (get_highest_layer(layer_state)) {
     39         case 0:
     40             oled_write_P(layer_0, false);
     41             break;
     42         case 1:
     43             oled_write_P(layer_1, false);
     44             break;
     45         case 2:
     46             oled_write_P(layer_2, false);
     47             break;
     48         case 3:
     49             oled_write_P(layer_3, false);
     50             break;
     51         default:
     52             oled_write_P(PSTR("? "), false);
     53             break;
     54     }
     55 }
     56 
     57 void render_encoder_section(void) {
     58     static const char PROGMEM enc_vol[] = {0x88, 0x89, 0x8a, 0x8b, 0};
     59     static const char PROGMEM enc_med[] = {0xa8, 0xa9, 0xaa, 0xab, 0};
     60     static const char PROGMEM enc_brt[] = {0x8c, 0x8d, 0x8e, 0x8f, 0};
     61 
     62     oled_set_cursor(oled_max_chars()-7, 0);
     63     oled_write_P(PSTR("ENC"), false);
     64     switch (encoder_mode) {
     65         default:
     66         case ENC_MODE_VOLUME:
     67             oled_write_P(enc_vol, false);
     68             break;
     69         case ENC_MODE_MEDIA:
     70             oled_write_P(enc_med, false);
     71             break;
     72         case ENC_MODE_BRIGHTNESS:
     73             oled_write_P(enc_brt, false);
     74             break;
     75     }
     76 }
     77 
     78 void render_numlock_section(void) {
     79     static const char PROGMEM num_on[] = {0x80, 0x81, 0x82, 0x83, 0};
     80     static const char PROGMEM num_off[] = {0xa0, 0xa1, 0xa2, 0xa3, 0};
     81     static const char PROGMEM cap_on[] = {0x84, 0x85, 0x86, 0x87, 0};
     82     static const char PROGMEM cap_off[] = {0xa4, 0xa5, 0xa6, 0xa7, 0};
     83     static const char PROGMEM scr_on[] = {0xba, 0xbb, 0xbc, 0xbd, 0};
     84     static const char PROGMEM scr_off[] = {0xda, 0xdb, 0xdc, 0xdd, 0};
     85 
     86     led_t led_state = host_keyboard_led_state();
     87 
     88     oled_set_cursor(oled_max_chars()-12, 3);
     89     // num lock
     90     oled_write_P(led_state.num_lock ? num_on : num_off, false);
     91     oled_write_P(led_state.caps_lock ? cap_on : cap_off, false);
     92     oled_write_P(led_state.scroll_lock ? scr_on : scr_off, false);
     93 }
     94 
     95 void render_mode_section(void) {
     96     static const char PROGMEM pad_on[] = {0xb0, 0xb1, 0xb2, 0xb3, 0};
     97     static const char PROGMEM pad_off[] = {0xc4, 0xc5, 0xc6, 0xc7, 0};
     98     static const char PROGMEM cal_on[] = {0x90, 0x91, 0x92, 0x93, 0};
     99     static const char PROGMEM cal_off[] = {0xc0, 0xc1, 0xc2, 0xc3, 0};
    100 
    101     if (oled_mode == OLED_MODE_CALC) {
    102         oled_set_cursor(0, 0);
    103         oled_write_P(pad_off, false);
    104         oled_set_cursor(0, 1);
    105         oled_write_P(cal_on, false);
    106     } else {
    107         oled_set_cursor(0, 0);
    108         oled_write_P(pad_on, false);
    109         oled_set_cursor(0, 1);
    110         oled_write_P(cal_off, false);
    111     }
    112 }
    113 
    114 void render_calc_section(void) {
    115     static const char PROGMEM add_on[] = {0xd4, 0xd5, 0};
    116     static const char PROGMEM add_off[] = {0x94, 0x95, 0};
    117     static const char PROGMEM sub_on[] = {0xd6, 0xd7, 0};
    118     static const char PROGMEM sub_off[] = {0x96, 0x97, 0};
    119     static const char PROGMEM mul_on[] = {0xd8, 0xd9, 0};
    120     static const char PROGMEM mul_off[] = {0x9c, 0x9d, 0};
    121     static const char PROGMEM div_on[] = {0xb8, 0xb9, 0};
    122     static const char PROGMEM div_off[] = {0x9e, 0x9f, 0};
    123     static const char PROGMEM sqr_on[] = {0x98, 0x99, 0};
    124     static const char PROGMEM sqr_off[] = {0xbe, 0xbf, 0};
    125     static const char PROGMEM rec_on[] = {0x9a, 0x9b, 0};
    126     static const char PROGMEM rec_off[] = {0xde, 0xdf, 0};
    127     static const char PROGMEM neg_on[] = {0xb4, 0xb5, 0};
    128     static const char PROGMEM neg_off[] = {0xb6, 0xb7, 0};
    129 
    130 
    131     if (oled_mode == OLED_MODE_CALC) {
    132         if (get_highest_layer(layer_state) == 1) {
    133             oled_set_cursor(oled_max_chars()-8, 0);
    134 
    135             switch (calc_operator_display) {
    136                 case '+':
    137                     oled_write_P(div_off, false);
    138                     oled_write_P(mul_off, false);
    139                     oled_write_P(sub_off, false);
    140                     oled_write_P(add_on, false);
    141                     break;
    142                 case '-':
    143                     oled_write_P(div_off, false);
    144                     oled_write_P(mul_off, false);
    145                     oled_write_P(sub_on, false);
    146                     oled_write_P(add_off, false);
    147                     break;
    148                 case '*':
    149                     oled_write_P(div_off, false);
    150                     oled_write_P(mul_on, false);
    151                     oled_write_P(sub_off, false);
    152                     oled_write_P(add_off, false);
    153                     break;
    154                 case '/':
    155                     oled_write_P(div_on, false);
    156                     oled_write_P(mul_off, false);
    157                     oled_write_P(sub_off, false);
    158                     oled_write_P(add_off, false);
    159                     break;
    160                 case 's':
    161                 case 'r':
    162                 case 'n':
    163                     layer_on(2);
    164                     break;
    165                 default:
    166                     oled_write_P(div_off, false);
    167                     oled_write_P(mul_off, false);
    168                     oled_write_P(sub_off, false);
    169                     oled_write_P(add_off, false);
    170                     break;
    171             }
    172         } else if (get_highest_layer(layer_state) == 2) {
    173             oled_set_cursor(oled_max_chars()-6, 0);
    174 
    175             switch (calc_operator_display) {
    176                 case '+':
    177                 case '-':
    178                 case '*':
    179                 case '/':
    180                     layer_off(2);
    181                     break;
    182                 case 's':
    183                     oled_write_P(neg_off, false);
    184                     oled_write_P(sqr_on, false);
    185                     oled_write_P(rec_off, false);
    186                     break;
    187                 case 'r':
    188                     oled_write_P(neg_off, false);
    189                     oled_write_P(sqr_off, false);
    190                     oled_write_P(rec_on, false);
    191                     break;
    192                 case 'n':
    193                     oled_write_P(neg_on, false);
    194                     oled_write_P(sqr_off, false);
    195                     oled_write_P(rec_off, false);
    196                     break;
    197                 default:
    198                     oled_write_P(neg_off, false);
    199                     oled_write_P(sqr_off, false);
    200                     oled_write_P(rec_off, false);
    201                     break;
    202             }
    203         }
    204 
    205         if (calc_display_lines == 1) {
    206             oled_set_cursor(oled_max_chars()-strlen(calc_result_display)-2, 3);
    207             oled_write_char(calc_operator_display, false);
    208         } else if (calc_display_lines == 2) {
    209             oled_set_cursor(oled_max_chars()-strlen(calc_status_display), 2);
    210             oled_write(calc_status_display, false);
    211         }
    212         oled_set_cursor(oled_max_chars()-strlen(calc_result_display), 3);
    213         oled_write(calc_result_display, false);
    214     }
    215 }
    216 
    217 static void render_logo(void) {
    218     oled_write_raw_P(raw_logo, sizeof(raw_logo));
    219 }
    220 
    221 void render_frame(void) {
    222     if (oled_logo_expired) {
    223         if (oled_mode == OLED_MODE_DEFAULT) {
    224             render_mode_section();
    225             render_layer_section();
    226             render_encoder_section();
    227             render_numlock_section();
    228         } else if (oled_mode == OLED_MODE_CALC) {
    229             render_mode_section();
    230             render_calc_section();
    231         } else if (oled_mode == OLED_MODE_OFF) {
    232             if (is_oled_on()) {
    233                 oled_off();
    234             }
    235         }
    236     } else {
    237         render_logo();
    238         oled_logo_expired = timer_elapsed(oled_logo_timer) > OLED_LOGO_TIMEOUT;
    239     }
    240 }
    241 
    242 bool oled_task_kb(void) {
    243     if (!oled_task_user()) { return false; }
    244     if (timer_elapsed(oled_frame_timer) > OLED_FRAME_TIMEOUT) {
    245         oled_clear();
    246         oled_frame_timer = timer_read();
    247         render_frame();
    248     }
    249 
    250     if (get_highest_layer(layer_state) == 1) {
    251         oled_mode = OLED_MODE_CALC;
    252     } else if (get_highest_layer(layer_state) == 2) {
    253         if (IS_LAYER_ON(1)) {
    254             oled_mode = OLED_MODE_CALC;
    255         } else {
    256             oled_mode = OLED_MODE_DEFAULT;
    257         }
    258     } else if (get_highest_layer(layer_state) == 3) {
    259         oled_mode = OLED_MODE_OFF;
    260     } else {
    261         oled_mode = OLED_MODE_DEFAULT;
    262     }
    263     return false;
    264 }
    265 
    266 oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
    267     oled_logo_timer = timer_read();
    268     oled_frame_timer = timer_read();
    269     return rotation;
    270 }