logo

qmk_firmware

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

matrix.c (7381B)


  1. /*
  2. Copyright 2019 worthlessowl
  3. based on work by:
  4. Jun Wako <wakojun@gmail.com>
  5. Cole Markham <cole@ccmcomputing.net>
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /*
  18. * scan matrix
  19. */
  20. #include <stdint.h>
  21. #include <stdbool.h>
  22. #include "wait.h"
  23. #include "print.h"
  24. #include "debug.h"
  25. #include "util.h"
  26. #include "matrix.h"
  27. #include "timer.h"
  28. #if (MATRIX_COLS <= 8)
  29. # define print_matrix_header() print("\nr/c 01234567\n")
  30. # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
  31. # define ROW_SHIFTER ((uint8_t)1)
  32. #elif (MATRIX_COLS <= 16)
  33. # define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
  34. # define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
  35. # define ROW_SHIFTER ((uint16_t)1)
  36. #elif (MATRIX_COLS <= 32)
  37. # define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
  38. # define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
  39. # define ROW_SHIFTER ((uint32_t)1)
  40. #endif
  41. static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  42. static const uint8_t col_select_pins[3] = MATRIX_COL_SELECT_PINS;
  43. static const uint8_t dat_pin = MATRIX_COL_DATA_PIN;
  44. /* matrix state(1:on, 0:off) */
  45. static matrix_row_t raw_matrix[MATRIX_ROWS]; //raw values
  46. static matrix_row_t matrix[MATRIX_ROWS]; //raw values
  47. /* 2d array containing binary representation of its index */
  48. static const uint8_t num_in_binary[8][3] = {
  49. {0, 0, 0},
  50. {0, 0, 1},
  51. {0, 1, 0},
  52. {0, 1, 1},
  53. {1, 0, 0},
  54. {1, 0, 1},
  55. {1, 1, 0},
  56. {1, 1, 1},
  57. };
  58. static void select_col_analog(uint8_t col);
  59. static void mux_pin_control(const uint8_t binary[]);
  60. void debounce_init(uint8_t num_rows);
  61. void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed);
  62. __attribute__ ((weak))
  63. void matrix_init_user(void) {}
  64. __attribute__ ((weak))
  65. void matrix_scan_user(void) {}
  66. __attribute__ ((weak))
  67. void matrix_init_kb(void) {
  68. matrix_init_user();
  69. }
  70. __attribute__ ((weak))
  71. void matrix_scan_kb(void) {
  72. matrix_scan_user();
  73. }
  74. inline
  75. uint8_t matrix_rows(void)
  76. {
  77. return MATRIX_ROWS;
  78. }
  79. inline
  80. uint8_t matrix_cols(void)
  81. {
  82. return MATRIX_COLS;
  83. }
  84. inline
  85. bool matrix_is_on(uint8_t row, uint8_t col)
  86. {
  87. return (matrix[row] & ((matrix_row_t)1<<col));
  88. }
  89. inline
  90. matrix_row_t matrix_get_row(uint8_t row)
  91. {
  92. // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
  93. // switch blocker installed and the switch is always pressed.
  94. #ifdef MATRIX_MASKED
  95. return matrix[row] & matrix_mask[row];
  96. #else
  97. return matrix[row];
  98. #endif
  99. }
  100. void matrix_print(void)
  101. {
  102. print_matrix_header();
  103. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  104. print_hex8(row); print(": ");
  105. print_matrix_row(row);
  106. print("\n");
  107. }
  108. }
  109. // uses standard row code
  110. static void select_row(uint8_t row)
  111. {
  112. gpio_set_pin_output(row_pins[row]);
  113. gpio_write_pin_low(row_pins[row]);
  114. }
  115. static void unselect_row(uint8_t row)
  116. {
  117. gpio_set_pin_input_high(row_pins[row]);
  118. }
  119. static void unselect_rows(void)
  120. {
  121. for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
  122. gpio_set_pin_input_high(row_pins[x]);
  123. }
  124. }
  125. static void init_pins(void) { // still need some fixing, this might not work
  126. unselect_rows(); // with the loop
  127. /*
  128. for (uint8_t x = 0; x < MATRIX_COLS; x++) {
  129. gpio_set_pin_input_high(col_pins[x]);
  130. }
  131. */
  132. gpio_set_pin_input_high(dat_pin);
  133. }
  134. static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
  135. {
  136. // Store last value of row prior to reading
  137. matrix_row_t last_row_value = current_matrix[current_row];
  138. // Clear data in matrix row
  139. current_matrix[current_row] = 0;
  140. // Select row and wait for row selecton to stabilize
  141. select_row(current_row);
  142. wait_us(30);
  143. // For each col...
  144. for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
  145. // Select the col pin to read (active low)
  146. select_col_analog(col_index);
  147. wait_us(30);
  148. uint8_t pin_state = gpio_read_pin(dat_pin);
  149. // Populate the matrix row with the state of the col pin
  150. current_matrix[current_row] |= pin_state ? 0 : (ROW_SHIFTER << col_index);
  151. }
  152. // Unselect row
  153. unselect_row(current_row);
  154. return (last_row_value != current_matrix[current_row]);
  155. }
  156. void matrix_init(void) {
  157. // initialize key pins
  158. init_pins();
  159. // initialize matrix state: all keys off
  160. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  161. raw_matrix[i] = 0;
  162. matrix[i] = 0;
  163. }
  164. debounce_init(MATRIX_ROWS);
  165. matrix_init_kb();
  166. gpio_set_pin_input(D5);
  167. gpio_set_pin_input(B0);
  168. }
  169. // modified for per col read matrix scan
  170. uint8_t matrix_scan(void)
  171. {
  172. bool changed = false;
  173. for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
  174. changed |= read_cols_on_row(raw_matrix, current_row);
  175. }
  176. debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
  177. matrix_scan_kb();
  178. return (uint8_t)changed;
  179. }
  180. /*
  181. uint8_t matrix_scan(void)
  182. {
  183. bool changed = false;
  184. #if (DIODE_DIRECTION == COL2ROW)
  185. // Set row, read cols
  186. for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
  187. changed |= read_cols_on_row(raw_matrix, current_row);
  188. }
  189. #endif
  190. debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
  191. matrix_scan_kb();
  192. return (uint8_t)changed;
  193. }
  194. */
  195. static void select_col_analog(uint8_t col) {
  196. switch(col) {
  197. case 0:
  198. mux_pin_control(num_in_binary[0]);
  199. break;
  200. case 1:
  201. mux_pin_control(num_in_binary[1]);
  202. break;
  203. case 2:
  204. mux_pin_control(num_in_binary[2]);
  205. break;
  206. case 3:
  207. mux_pin_control(num_in_binary[3]);
  208. break;
  209. case 4:
  210. mux_pin_control(num_in_binary[4]);
  211. break;
  212. case 5:
  213. mux_pin_control(num_in_binary[5]);
  214. break;
  215. case 6:
  216. mux_pin_control(num_in_binary[6]);
  217. break;
  218. case 7:
  219. mux_pin_control(num_in_binary[7]);
  220. break;
  221. default:
  222. break;
  223. }
  224. }
  225. static void mux_pin_control(const uint8_t binary[]) {
  226. // set pin0
  227. gpio_set_pin_output(col_select_pins[0]);
  228. if(binary[2] == 0) {
  229. gpio_write_pin_low(col_select_pins[0]);
  230. }
  231. else {
  232. gpio_write_pin_high(col_select_pins[0]);
  233. }
  234. // set pin1
  235. gpio_set_pin_output(col_select_pins[1]);
  236. if(binary[1] == 0) {
  237. gpio_write_pin_low(col_select_pins[1]);
  238. }
  239. else {
  240. gpio_write_pin_high(col_select_pins[1]);
  241. }
  242. // set pin2
  243. gpio_set_pin_output(col_select_pins[2]);
  244. if(binary[0] == 0) {
  245. gpio_write_pin_low(col_select_pins[2]);
  246. }
  247. else {
  248. gpio_write_pin_high(col_select_pins[2]);
  249. }
  250. }