logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

rev1.c (8366B)


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