qmk_firmware

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

hotdox76v2.c (9596B)


      1 // Copyright 2021 JasonRen(biu)
      2 // Copyright 2022 Drashna Jael're (@Drashna Jael're)
      3 // SPDX-License-Identifier: GPL-2.0-or-later
      4 
      5 #include "hotdox76v2.h"
      6 #include <string.h>
      7 #include <transactions.h>
      8 #include "oled_font_lib/logo2.h"
      9 #include "oled_font_lib/ext_font.h"
     10 
     11 #ifdef OLED_ENABLE
     12 
     13 #    define UNC (' ')
     14 typedef struct _master_to_slave_t {
     15     int  cur_alp_index;
     16     char current_alp[7];
     17 } master_to_slave_t;
     18 master_to_slave_t m2s;
     19 
     20 typedef struct _slave_to_master_t {
     21     int  cur_alp_index;
     22     char current_alp[7];
     23 } slave_to_master_t;
     24 slave_to_master_t s2m;
     25 
     26 oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
     27     strcpy((char *)(m2s.current_alp), "[    ]");
     28     m2s.current_alp[1] = UNC;
     29     m2s.current_alp[2] = UNC;
     30     m2s.current_alp[3] = UNC;
     31     m2s.current_alp[4] = UNC;
     32 
     33     m2s.cur_alp_index = 1;
     34 
     35     strcpy((char *)(s2m.current_alp), "[    ]");
     36     s2m.current_alp[1] = UNC;
     37     s2m.current_alp[2] = UNC;
     38     s2m.current_alp[3] = UNC;
     39     s2m.current_alp[4] = UNC;
     40 
     41     s2m.cur_alp_index = 1;
     42 
     43     if (is_keyboard_left()) {
     44         return OLED_ROTATION_180;
     45     } else {
     46         return OLED_ROTATION_0;
     47     }
     48 }
     49 
     50 void render_logo(void) {
     51     uint8_t i = 0, j = 0;
     52     for (i = 0; i < 4; ++i) {
     53         for (j = 0; j < 32; ++j) {
     54             if (is_keyboard_left()) {
     55                 oled_write_raw_byte(pgm_read_byte(&logo_mouse[i * 32 + j]), i * 128 + j);
     56             } else {
     57                 oled_write_raw_byte(pgm_read_byte(&logo_mouse[i * 32 + j]), i * 128 + j + 96);
     58             }
     59         }
     60     }
     61 }
     62 
     63 void render_layer_helper_fun(uint8_t start_line, const char *data, uint8_t gap_w, uint8_t l) {
     64     uint8_t j = 0, k = 0;
     65     for (j = 0; j < l; ++j) {      // font index
     66         for (k = 0; k < 12; ++k) { // font byte index
     67             //                                        base + logo_w(32) + gap_w(12) +l*font_w(12)+current_byte_index
     68             oled_write_raw_byte(pgm_read_byte(&ext_big_font[pgm_read_byte(&data[j]) - 0x20][k]), start_line * 2 * 128 + 32 + gap_w + j * 12 + k);
     69             oled_write_raw_byte(pgm_read_byte(&ext_big_font[pgm_read_byte(&data[j]) - 0x20][k + 12]), start_line * 2 * 128 + 128 + 32 + gap_w + j * 12 + k);
     70         }
     71     }
     72     for (j = 0; j < gap_w; ++j) {
     73         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 32 + j);
     74         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 32 + gap_w + l * 12 + j);
     75 
     76         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + 32 + j);
     77         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + 32 + gap_w + l * 12 + j);
     78     }
     79 }
     80 void render_layer(uint8_t layer) {
     81     render_layer_helper_fun(0, PSTR("LAYER:"), 12, 6);
     82     switch (layer) {
     83         case 0:
     84             render_layer_helper_fun(1, PSTR("1:HOME"), 12, 6);
     85             break;
     86         case 1:
     87             render_layer_helper_fun(1, PSTR("2:CODE"), 12, 6);
     88             break;
     89         case 2:
     90             render_layer_helper_fun(1, PSTR("3:OFFICE"), 0, 8);
     91             break;
     92         case 3:
     93         default:
     94             render_layer_helper_fun(1, PSTR("4:OTHERS"), 0, 8);
     95             break;
     96     }
     97 }
     98 
     99 void render_cur_input_helper_fun(uint8_t start_line, const char *data, uint8_t gap_w, uint8_t l) {
    100     uint8_t j = 0, k = 0;
    101     for (j = 0; j < l; ++j) {      // font index
    102         for (k = 0; k < 12; ++k) { // font byte index
    103             //                                        base + logo_w(0) + gap_w(12) +l*font_w(12)+current_byte_index
    104             oled_write_raw_byte(pgm_read_byte(&ext_big_font[data[j] - 0x20][k]), start_line * 2 * 128 + gap_w + j * 12 + k);
    105             oled_write_raw_byte(pgm_read_byte(&ext_big_font[data[j] - 0x20][12 + k]), start_line * 2 * 128 + 128 + gap_w + j * 12 + k);
    106         }
    107     }
    108     for (j = 0; j < gap_w; ++j) {
    109         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + j);
    110         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + gap_w + l * 12 + j);
    111 
    112         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + j);
    113         oled_write_raw_byte(pgm_read_byte(&blank_block), start_line * 2 * 128 + 128 + gap_w + l * 12 + j);
    114     }
    115 }
    116 
    117 void render_cur_input(void) {
    118     render_cur_input_helper_fun(0, "INPUTS:", 6, 7);
    119     if (is_keyboard_master()) {
    120         render_cur_input_helper_fun(1, (const char *)(m2s.current_alp), 12, 6);
    121     } else {
    122         render_cur_input_helper_fun(1, (const char *)(s2m.current_alp), 12, 6);
    123     }
    124     return;
    125 }
    126 
    127 bool oled_task_kb(void) {
    128     if (!oled_task_user()) {
    129         return false;
    130     }
    131     render_logo();
    132     if (is_keyboard_left()) {
    133         render_layer(biton32(layer_state));
    134     } else {
    135         render_cur_input();
    136     }
    137     return false;
    138 }
    139 
    140 static const char PROGMEM code_to_name[0xFF] = {
    141     //   0    1    2    3    4    5    6    7    8    9    A    B    c    D    E    F
    142     UNC, UNC,  UNC, UNC, 'a',  'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x
    143     'm', 'n',  'o', 'p', 'q',  'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', // 1x
    144     '3', '4',  '5', '6', '7',  '8', '9', '0', UNC, UNC, UNC, UNC, UNC, '-', '=', '[', // 2x
    145     ']', '\\', '#', ';', '\'', '`', ',', '.', '/', UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 3x
    146     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 4x
    147     UNC, UNC,  UNC, UNC, '/',  '*', '-', '+', UNC, '1', '2', '3', '4', '5', '6', '7', // 5x
    148     '8', '9',  '0', '.', UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 6x
    149     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 7x
    150     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 8x
    151     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 9x
    152     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ax
    153     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Bx
    154     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Cx
    155     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Dx
    156     UNC, UNC,  'A', 'W', UNC,  'S', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ex
    157     UNC, UNC,  UNC, UNC, UNC,  UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC       // Fx
    158 };
    159 
    160 void get_cur_alp_hook(uint16_t keycode) {
    161     if (keycode >= 0xF0) {
    162         keycode = 0xF0;
    163     }
    164     if (m2s.cur_alp_index < 4) {
    165         m2s.current_alp[m2s.cur_alp_index] = pgm_read_byte(&code_to_name[keycode]);
    166         if (m2s.cur_alp_index == 1) {
    167             m2s.current_alp[2] = m2s.current_alp[3] = m2s.current_alp[4] = UNC;
    168         }
    169         m2s.cur_alp_index++;
    170     } else {
    171         for (uint8_t i = 2; i <= 4; ++i) {
    172             m2s.current_alp[i - 1] = m2s.current_alp[i];
    173         }
    174         m2s.current_alp[m2s.cur_alp_index] = pgm_read_byte(&code_to_name[keycode]);
    175     }
    176 }
    177 
    178 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
    179     if (record->event.pressed) {
    180         get_cur_alp_hook(keycode);
    181     }
    182     if (!process_record_user(keycode, record)) {
    183         return false;
    184     }
    185     switch (keycode) {
    186         case TOG_OLED:
    187             if (record->event.pressed) {
    188                 if (is_oled_on()) {
    189                     oled_off();
    190                 } else {
    191                     oled_on();
    192                 }
    193             }
    194             return false;
    195         default:
    196             return true;
    197     }
    198     return true;
    199 }
    200 
    201 void user_sync_alpa_slave_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) {
    202     const master_to_slave_t *m2s_p = (const master_to_slave_t *)in_data;
    203     s2m.cur_alp_index              = m2s_p->cur_alp_index;
    204     for (size_t i = 0; i < 7; i++) {
    205         s2m.current_alp[i] = m2s_p->current_alp[i];
    206     }
    207 }
    208 
    209 void keyboard_post_init_kb(void) {
    210     transaction_register_rpc(KEYBOARD_CURRENT_ALPA_SYNC, user_sync_alpa_slave_handler);
    211     keyboard_post_init_user();
    212 }
    213 
    214 void housekeeping_task_kb(void) {
    215     if (is_keyboard_master()) {
    216         if (!is_oled_on()) {
    217             m2s.cur_alp_index = 1;
    218         }
    219         // Interact with slave every 200ms
    220         static uint32_t last_sync = 0;
    221         if (timer_elapsed32(last_sync) > 200) {
    222             if (transaction_rpc_exec(KEYBOARD_CURRENT_ALPA_SYNC, sizeof(m2s), &m2s, sizeof(s2m), &s2m)) {
    223                 last_sync = timer_read32();
    224                 dprint("Slave sync successed!\n");
    225             } else {
    226                 dprint("Slave sync failed!\n");
    227             }
    228         }
    229     }
    230 }
    231 
    232 #endif
    233 
    234 #ifdef SWAP_HANDS_ENABLE
    235 __attribute__((weak))
    236 const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
    237     /* Left hand, matrix positions */
    238     {{0,  6}, {1,  6}, {2,  6}, {3,  6}, {4,  6}, {5,  6}, {6, 6}},
    239     {{0,  7}, {1,  7}, {2,  7}, {3,  7}, {4,  7}, {5,  7}, {6,  7}},
    240     {{0,  8}, {1,  8}, {2,  8}, {3,  8}, {4,  8}, {5,  8}, {6,  8}},
    241     {{0,  9}, {1,  9}, {2,  9}, {3,  9}, {4,  9}, {5,  9}, {6,  9}},
    242     {{0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10},  {6, 10}},
    243     {{0, 11}, {1, 11}, {2, 11}, {3, 11}, {4, 11}, {5, 11},  {6, 11}},
    244 
    245     /* Right hand, matrix positions */
    246     {{0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}},
    247     {{0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}},
    248     {{0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}},
    249     {{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}},
    250     {{0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}},
    251     {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}
    252 };
    253 #endif