matrix.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Copyright 2023 Cameron Varley (@RustedAperture)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "matrix.h"
  4. #include <string.h>
  5. #include "atomic_util.h"
  6. #include "wait.h"
  7. #include "print.h"
  8. #include "debug.h"
  9. static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  10. static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
  11. static inline void gpio_atomic_set_pin_output_low(pin_t pin) {
  12. ATOMIC_BLOCK_FORCEON {
  13. gpio_set_pin_output(pin);
  14. gpio_write_pin_low(pin);
  15. }
  16. }
  17. static inline void gpio_atomic_set_pin_output_high(pin_t pin) {
  18. ATOMIC_BLOCK_FORCEON {
  19. gpio_set_pin_output(pin);
  20. gpio_write_pin_high(pin);
  21. }
  22. }
  23. static inline void gpio_atomic_set_pin_input_high(pin_t pin) {
  24. ATOMIC_BLOCK_FORCEON {
  25. gpio_set_pin_input_high(pin);
  26. }
  27. }
  28. static inline uint8_t readMatrixPin(pin_t pin) {
  29. if (pin != NO_PIN) {
  30. return gpio_read_pin(pin);
  31. } else {
  32. return 1;
  33. }
  34. }
  35. static bool select_col(uint8_t col) {
  36. pin_t pin = col_pins[col];
  37. if (pin != NO_PIN) {
  38. gpio_atomic_set_pin_output_low(pin);
  39. return true;
  40. }
  41. return false;
  42. }
  43. static void unselect_col(uint8_t col) {
  44. pin_t pin = col_pins[col];
  45. if (pin != NO_PIN) {
  46. # ifdef MATRIX_UNSELECT_DRIVE_HIGH
  47. gpio_atomic_set_pin_output_high(pin);
  48. # else
  49. gpio_atomic_set_pin_input_high(pin);
  50. # endif
  51. }
  52. }
  53. static void unselect_cols(void) {
  54. for (uint8_t x = 0; x < MATRIX_COLS; x++) {
  55. unselect_col(x);
  56. }
  57. }
  58. __attribute__((weak)) void matrix_init_custom(void) {
  59. unselect_cols();
  60. for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
  61. if (row_pins[x] != NO_PIN) {
  62. gpio_atomic_set_pin_input_high(row_pins[x]);
  63. }
  64. }
  65. gpio_atomic_set_pin_input_high(B8);
  66. }
  67. __attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter) { // Start with a clear matrix row
  68. bool key_pressed = false;
  69. // Select col
  70. if (!select_col(current_col)) { // select col
  71. return; // skip NO_PIN col
  72. }
  73. matrix_output_select_delay();
  74. // For each row...
  75. for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
  76. // Check row pin state
  77. if (current_col == 3 && row_index == 2 && readMatrixPin(B8) == 1) {
  78. current_matrix[row_index] |= row_shifter;
  79. key_pressed = !readMatrixPin(B8);
  80. } else if (readMatrixPin(row_pins[row_index]) == 0) {
  81. // Pin LO, set col bit
  82. current_matrix[row_index] |= row_shifter;
  83. key_pressed = true;
  84. } else {
  85. // Pin HI, clear col bit
  86. current_matrix[row_index] &= ~row_shifter;
  87. }
  88. }
  89. // Unselect col
  90. unselect_col(current_col);
  91. matrix_output_unselect_delay(current_col, key_pressed); // wait for all Row signals to go HIGH
  92. }
  93. bool matrix_scan_custom(matrix_row_t current_matrix[]) {
  94. static matrix_row_t temp_matrix[MATRIX_ROWS] = {0};
  95. matrix_row_t row_shifter = MATRIX_ROW_SHIFTER;
  96. for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
  97. matrix_read_rows_on_col(temp_matrix, current_col, row_shifter);
  98. }
  99. bool changed = memcmp(current_matrix, temp_matrix, sizeof(temp_matrix)) != 0;
  100. if (changed) {
  101. memcpy(current_matrix, temp_matrix, sizeof(temp_matrix));
  102. }
  103. return changed;
  104. }