matrix.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* Copyright 2021 Jay Greco
  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. #include <stdint.h>
  17. #include <stdbool.h>
  18. #include <string.h>
  19. #include "util.h"
  20. #include "matrix.h"
  21. #include "split_util.h"
  22. #include "quantum.h"
  23. #define VIRT_COLS_PER_HAND 1
  24. #define PHYS_COLS_PER_HAND (MATRIX_COLS - VIRT_COLS_PER_HAND)
  25. #define ROWS_PER_HAND (MATRIX_ROWS / 2)
  26. #define COL_SHIFTER ((uint32_t)1)
  27. #define EXT_PIN_ROW 2
  28. #define EXT_PIN_COL 8
  29. // Row & column pins
  30. static uint8_t row_pins_left[MATRIX_ROWS] = MATRIX_ROW_PINS;
  31. static uint8_t col_pins_left[MATRIX_MUX_COLS] = MATRIX_COL_MUX_PINS;
  32. static uint8_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT;
  33. static uint8_t col_pins_right[MATRIX_MUX_COLS] = MATRIX_COL_MUX_PINS_RIGHT;
  34. static uint8_t* row_pins = row_pins_left;
  35. static uint8_t* col_pins = col_pins_left;
  36. // Internal functions
  37. static void init_pins(void) {
  38. // Set cols to outputs, low
  39. for (uint8_t pin = 0; pin < MATRIX_MUX_COLS; pin++) {
  40. setPinOutput(col_pins[pin]);
  41. }
  42. // Unselect cols
  43. for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) {
  44. writePinLow(col_pins[bit]);
  45. }
  46. // Set rows to input, pullup
  47. for (uint8_t pin = 0; pin < ROWS_PER_HAND; pin++) {
  48. setPinInputHigh(row_pins[pin]);
  49. }
  50. // Set extended pin (only on right side)
  51. if (!isLeftHand) {
  52. // Set extended pin to input, pullup
  53. setPinInputHigh(MATRIX_EXT_PIN_RIGHT);
  54. }
  55. }
  56. static void select_col(uint8_t col) {
  57. // Drive demux with correct column address
  58. for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) {
  59. uint8_t state = (col & (0b1 << bit)) >> bit;
  60. writePin(col_pins[bit], !state);
  61. }
  62. }
  63. static void read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
  64. select_col(current_col % PHYS_COLS_PER_HAND);
  65. wait_us(5);
  66. // Read each row sequentially
  67. for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
  68. if (readPin(row_pins[row_index]) == 0) {
  69. current_matrix[row_index] |= (COL_SHIFTER << current_col);
  70. } else {
  71. current_matrix[row_index] &= ~(COL_SHIFTER << current_col);
  72. }
  73. }
  74. }
  75. static void read_ext_pin(matrix_row_t current_matrix[]) {
  76. // Read the state of the extended matrix pin
  77. if (!isLeftHand) {
  78. if (readPin(MATRIX_EXT_PIN_RIGHT) == 0) {
  79. current_matrix[EXT_PIN_ROW] |= (COL_SHIFTER << EXT_PIN_COL);
  80. } else {
  81. current_matrix[EXT_PIN_ROW] &= ~(COL_SHIFTER << EXT_PIN_COL);
  82. }
  83. }
  84. }
  85. void matrix_init_custom(void) {
  86. if (!isLeftHand) {
  87. row_pins = row_pins_right;
  88. col_pins = col_pins_right;
  89. }
  90. init_pins();
  91. }
  92. bool matrix_scan_custom(matrix_row_t current_matrix[]) {
  93. matrix_row_t last_matrix[MATRIX_ROWS];
  94. memcpy(last_matrix, current_matrix, sizeof(last_matrix));
  95. #ifdef DEBUG_SLOW_MATRIX
  96. // Slow for debugging
  97. wait_ms(1000);
  98. #endif
  99. // Set col, read rows
  100. for (uint8_t current_col = 0; current_col < PHYS_COLS_PER_HAND; current_col++) {
  101. read_rows_on_col(current_matrix, current_col);
  102. }
  103. // Read extended pin and store in matrix
  104. read_ext_pin(current_matrix);
  105. // Check if the matrix changed
  106. bool changed = memcmp(last_matrix, current_matrix, sizeof(last_matrix)) != 0;
  107. return changed;
  108. }