rev1.c (8366B)
1 // Copyright 2024 splitkb.com (support@splitkb.com) 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 4 #include "rev1.h" 5 #include "spi_master.h" 6 #include "myriad.h" 7 8 bool is_oled_enabled = true; 9 10 //// HW init 11 12 // Make sure all external hardware is 13 // in a known-good state on powerup 14 void keyboard_pre_init_kb(void) { 15 /// SPI Chip Select pins for various hardware 16 // Matrix CS 17 gpio_set_pin_output(GP13); 18 gpio_write_pin_high(GP13); 19 // Myriad Module CS 20 gpio_set_pin_output(GP9); 21 gpio_write_pin_high(GP9); 22 23 gpio_set_pin_output(ELORA_CC1_PIN); 24 gpio_write_pin_low(ELORA_CC1_PIN); 25 26 gpio_set_pin_output(ELORA_CC2_PIN); 27 gpio_write_pin_low(ELORA_CC2_PIN); 28 29 // We have to get the SPI interface working quite early, 30 // So make sure it is available well before we need it 31 spi_init(); 32 33 keyboard_pre_init_user(); 34 } 35 36 //// Encoder functionality 37 38 // The encoders are hooked in to the same shift registers as the switch matrix, so we can just piggyback on that. 39 40 // Clone of a variant in quantum/matrix_common.c, but matrix-agnostic 41 bool mat_is_on(matrix_row_t mat[], uint8_t row, uint8_t col) { 42 return (mat[row] & ((matrix_row_t)1 << col)); 43 } 44 45 uint8_t encoder_read_pads_from(uint8_t index, bool pad_b, matrix_row_t mat[]) { 46 // First two matrix rows: 47 // 48 // Pin A B C D E F G H 49 // Left: 50 // { __, __, __, __, __, __, A1, B1 }, 51 // { A3, B3, A2, B2, __, __, __, __ } 52 // Right: 53 // { A1, B1, __, __, __, __, __, __ }, 54 // { __, __, __, __, A2, B2, A3, B3 } 55 // 56 // See also rev1.h 57 58 bool pad_value = false; 59 60 if (is_keyboard_left()) { 61 if (index == 0) { 62 pad_value = pad_b ? mat_is_on(mat, 0, 7) : mat_is_on(mat, 0, 6); // B1, A1 63 } else if (index == 1) { 64 pad_value = pad_b ? mat_is_on(mat, 1, 3) : mat_is_on(mat, 1, 2); // B2, A2 65 } else if (index == 2) { 66 pad_value = pad_b ? mat_is_on(mat, 1, 1) : mat_is_on(mat, 1, 0); // B3, A3 67 } 68 } else { 69 if (index == 0) { 70 pad_value = pad_b ? mat_is_on(mat, 0, 1) : mat_is_on(mat, 0, 0); // B1, A1 71 } else if (index == 1) { 72 pad_value = pad_b ? mat_is_on(mat, 1, 5) : mat_is_on(mat, 1, 4); // B2, A2 73 } else if (index == 2) { 74 pad_value = pad_b ? mat_is_on(mat, 1, 7) : mat_is_on(mat, 1, 6); // B3, A3 75 } 76 } 77 78 return pad_value ? 1 : 0; 79 } 80 81 void encoder_quadrature_init_pin(uint8_t index, bool pad_b) { 82 // At this point the first matrix scan hasn't happened yet, 83 // so we can't use raw_matrix to initialize our encoder state 84 // as it contains all zeroes - so we have to do our own first scan 85 // The pins for myriad are initialized in myriad.c 86 87 matrix_row_t mat[MATRIX_ROWS]; 88 89 encoder_read_pads_from(index, pad_b, mat); 90 } 91 92 extern matrix_row_t raw_matrix[MATRIX_ROWS]; // From quantum/matrix_common.c 93 94 uint8_t encoder_quadrature_read_pin(uint8_t index, bool pad_b) { 95 // The matrix code already keeps the raw matrix up-to-date, 96 // so we only have to read the values from it 97 if(index <= 2) { 98 return encoder_read_pads_from(index, pad_b, raw_matrix); 99 } else { 100 #ifdef MYRIAD_ENABLE 101 return myriad_hook_encoder(index, pad_b); 102 #endif 103 return 0; 104 } 105 return 0; 106 } 107 108 //// Default functionality 109 110 #ifdef OLED_ENABLE 111 oled_rotation_t oled_init_kb(oled_rotation_t rotation) { 112 if (is_keyboard_left()) { 113 return OLED_ROTATION_270; 114 } else { 115 return OLED_ROTATION_90; 116 } 117 } 118 119 bool oled_task_kb(void) { 120 if (!oled_task_user()) { 121 return false; 122 } 123 124 if (!is_oled_enabled) { 125 oled_off(); 126 return false; 127 } else { 128 oled_on(); 129 } 130 131 if (is_keyboard_master()) { 132 oled_write_P(PSTR("Elora rev1\n\n"), false); 133 134 // Keyboard Layer Status 135 // Ideally we'd print the layer name, but no way to know that for sure 136 // Fallback option: just print the layer number 137 uint8_t layer = get_highest_layer(layer_state | default_layer_state); 138 oled_write_P(PSTR("Layer: "), false); 139 oled_write(get_u8_str(layer, ' '), false); 140 141 // Keyboard LED Status 142 led_t led_state = host_keyboard_led_state(); 143 oled_write_P(led_state.num_lock ? PSTR(" NUM") : PSTR(" "), false); 144 oled_write_P(led_state.caps_lock ? PSTR("CAP") : PSTR(" "), false); 145 oled_write_P(led_state.scroll_lock ? PSTR("SCR") : PSTR(" "), false); 146 147 // QMK Logo 148 // clang-format off 149 static const char PROGMEM qmk_logo[] = { 150 0x81,0x82,0x83,0x84,0x0a, 151 0xa1,0xa2,0xa3,0xa4,0x85,0x86,0x87,0x88,0x89,0x0a, 152 0xc1,0xc2,0xc3,0xc4,0xa5,0xa6,0xa7,0xa8,0xa9,0x0a, 153 0x8a,0x8b,0x8c,0x8d,0xc5,0xc6,0xc7,0xc8,0xc9,0x0a, 154 0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0x00 155 }; 156 // clang-format on 157 oled_set_cursor(0, oled_max_lines()-5); 158 oled_write_P(qmk_logo, false); 159 } else { 160 // Elora sigil 161 // clang-format off 162 static const char PROGMEM elora_logo[] = { 163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,192,224,224,240,248,120, 56, 60,188,158,158,222,206,207,207,207,239,239,239,239,239,239,207,207,207,206,222,158,158,188, 60, 56,120,248,240,224,224,192,128,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,224,248,252,126, 31,143,199,227,243,249,124, 60, 30, 31, 15, 7, 7, 3, 3, 3,131,193,225,241,249,253,255,255,255,255,127, 63, 31, 15, 7, 7, 7,143,223,254,252,252,249,243,227,199,143, 31,126,252,248,224,192, 0, 0, 0, 0, 0, 164 0,192,240,254,255, 63, 7,227,248,252,127, 31, 15, 3, 1, 0, 0, 0,128,192,224,240,248,252,254,255,255,255,127, 63, 31, 15, 7, 3, 1,128,192,224,240,248,252,254,255,255,255,255,127, 63, 31, 15, 7, 15, 31,255,252,248,227, 7, 63,255,254,240,192, 0,252,255,255,255, 1,224,255,255,255, 7, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 31, 31, 31, 15, 7, 3, 1, 0, 0, 0,240,248,252,254,255,255,255,255,127, 63, 31, 15, 7, 3, 1,128,192,224,240,248,252,254,255,255,255,255,255,255,224, 1,255,255,255,252, 165 63,255,255,255,128, 7,255,255,255,224, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,192,224,240,248,248,248,248,248,248, 0, 3, 3, 3, 3, 3, 3, 1,128,192,224,240,248,252,254,255,255,255,127, 63, 31, 15, 7, 3, 1,224,255,255,255, 7,128,255,255,255, 63, 0, 3, 15,127,255,252,224,199, 31, 63,254,248,240,192,128, 0, 0, 0, 0, 31, 31, 31, 31, 31, 31, 15, 7, 3, 1, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 63, 31, 15, 7, 3, 1, 0, 0, 0,128,192,240,248,254, 63, 31,199,224,252,255,127, 15, 3, 0, 166 0, 0, 0, 0, 0, 3, 7, 31, 63,126,248,241,227,199,207,159, 62, 60,120,248,240,224,224,192,192,192,192,128,128,128,128,128,128,128,128,128,128,192,192,192,192,224,224,240,248,120, 60, 62,159,207,199,227,241,248,126, 63, 31, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 7, 7, 15, 31, 30, 28, 60, 61,121,121,123,115,243,243,243,247,247,247,247,247,247,243,243,243,115,123,121,121, 61, 60, 28, 30, 31, 15, 7, 7, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167 }; 168 // clang-format on 169 oled_set_cursor(0, (oled_max_lines()/2)-4); // logo is 8 lines high, so center vertically 170 oled_write_raw_P(elora_logo, sizeof(elora_logo)); 171 } 172 173 return false; 174 } 175 176 void housekeeping_task_kb(void) { 177 is_oled_enabled = last_input_activity_elapsed() < 60000; 178 } 179 #endif 180 181 #ifdef ENCODER_ENABLE 182 bool encoder_update_kb(uint8_t index, bool clockwise) { 183 if (!encoder_update_user(index, clockwise)) { 184 return false; 185 } 186 187 if (index == 0 || index == 1 || index == 2) { 188 // Left side 189 // Arrow keys 190 if (clockwise) { 191 tap_code(KC_RIGHT); 192 } else { 193 tap_code(KC_LEFT); 194 } 195 } else if (index == 4 || index == 5 || index == 6) { 196 // Right side 197 // Page up/Page down 198 if (clockwise) { 199 tap_code(KC_PGDN); 200 } else { 201 tap_code(KC_PGUP); 202 } 203 } else if (index == 3 || index == 7) { 204 // Myriad 205 // Volume control 206 if (clockwise) { 207 tap_code(KC_VOLU); 208 } else { 209 tap_code(KC_VOLD); 210 } 211 } 212 return true; 213 } 214 #endif