logo

qmk_firmware

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

matrix.c (6308B)


  1. /**
  2. * matrix.c
  3. *
  4. Copyright 2020 astro <yuleiz@gmail.com>
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  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 "matrix.h"
  17. #include "print.h"
  18. #include "bitwise.h"
  19. #include "wait.h"
  20. #ifndef DEBOUNCE
  21. # define DEBOUNCE 5
  22. #endif
  23. static uint8_t debouncing = DEBOUNCE;
  24. static matrix_row_t matrix[MATRIX_ROWS];
  25. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  26. static uint8_t read_rows(void);
  27. static void init_rows(void);
  28. static void init_cols(void);
  29. static void unselect_cols(void);
  30. static void select_col(uint8_t col);
  31. __attribute__ ((weak))
  32. void matrix_init_kb(void)
  33. {
  34. matrix_init_user();
  35. }
  36. __attribute__ ((weak))
  37. void matrix_scan_kb(void)
  38. {
  39. matrix_scan_user();
  40. }
  41. __attribute__ ((weak))
  42. void matrix_init_user(void) {}
  43. __attribute__ ((weak))
  44. void matrix_scan_user(void) {}
  45. void matrix_init(void)
  46. {
  47. //gpio_set_pin_output(F0);
  48. //gpio_write_pin_high(F0);
  49. gpio_set_pin_output(B4);
  50. gpio_write_pin_low(B4);
  51. init_cols();
  52. init_rows();
  53. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  54. matrix[i] = 0;
  55. matrix_debouncing[i] = 0;
  56. }
  57. matrix_init_kb();
  58. }
  59. uint8_t matrix_scan(void)
  60. {
  61. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  62. select_col(col);
  63. _delay_us(3);
  64. uint8_t rows = read_rows();
  65. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  66. bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
  67. bool curr_bit = rows & (1<<row);
  68. if (prev_bit != curr_bit) {
  69. matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
  70. debouncing = DEBOUNCE;
  71. }
  72. }
  73. unselect_cols();
  74. }
  75. if (debouncing) {
  76. if (--debouncing) {
  77. _delay_ms(1);
  78. } else {
  79. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  80. matrix[i] = matrix_debouncing[i];
  81. }
  82. }
  83. }
  84. matrix_scan_kb();
  85. return 1;
  86. }
  87. inline matrix_row_t matrix_get_row(uint8_t row)
  88. {
  89. return matrix[row];
  90. }
  91. void matrix_print(void)
  92. {
  93. print("\nr/c 0123456789ABCDEF\n");
  94. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  95. xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
  96. }
  97. }
  98. /*
  99. * Row pin configuration
  100. * row: 0 1 2 3 4
  101. * pin: PE6 PF6 PF7 PB7 PD4
  102. */
  103. static void init_rows(void)
  104. {
  105. gpio_set_pin_input_high(E6);
  106. gpio_set_pin_input_high(F6);
  107. gpio_set_pin_input_high(F7);
  108. gpio_set_pin_input_high(B7);
  109. gpio_set_pin_input_high(D4);
  110. }
  111. static uint8_t read_rows(void)
  112. {
  113. return ((gpio_read_pin(E6) ? 0 : (1 << 0)) |
  114. (gpio_read_pin(F6) ? 0 : (1 << 1)) |
  115. (gpio_read_pin(F7) ? 0 : (1 << 2)) |
  116. (gpio_read_pin(B7) ? 0 : (1 << 3)) |
  117. (gpio_read_pin(D4) ? 0 : (1 << 4)));
  118. }
  119. /*
  120. * Columns 0 - 13
  121. * These columns uses two 74LVC138 3 to 8 bit demultiplexers.
  122. * EN Pin, PF5, PD6
  123. *
  124. * col / pin: PF0 PF1 PF4
  125. * 0: 0 0 0
  126. * 1: 1 0 0
  127. * 2: 0 1 0
  128. * 3: 1 1 0
  129. * 4: 0 0 1
  130. * 5: 1 0 1
  131. * 6: 0 1 1
  132. * PD2 PD3 PD5
  133. * 7: 0 0 0
  134. * 8: 1 0 0
  135. * 9: 0 1 0
  136. * 10: 1 1 0
  137. * 11: 0 0 1
  138. * 12: 1 0 1
  139. * 13: 0 1 1
  140. *
  141. */
  142. static void init_cols(void)
  143. {
  144. gpio_set_pin_output(F0);
  145. gpio_set_pin_output(F1);
  146. gpio_set_pin_output(F4);
  147. gpio_set_pin_output(F5);
  148. gpio_set_pin_output(D2);
  149. gpio_set_pin_output(D3);
  150. gpio_set_pin_output(D5);
  151. gpio_set_pin_output(D6);
  152. unselect_cols();
  153. }
  154. static void unselect_cols(void)
  155. {
  156. gpio_write_pin_high(F0);
  157. gpio_write_pin_high(F1);
  158. gpio_write_pin_high(F4);
  159. gpio_write_pin_high(F5);
  160. gpio_write_pin_high(D2);
  161. gpio_write_pin_high(D3);
  162. gpio_write_pin_high(D5);
  163. gpio_write_pin_high(D6);
  164. }
  165. static void select_col(uint8_t col) {
  166. switch (col) {
  167. case 0:
  168. gpio_write_pin_low(F0);
  169. gpio_write_pin_low(F1);
  170. gpio_write_pin_low(F4);
  171. break;
  172. case 1:
  173. gpio_write_pin_high(F0);
  174. gpio_write_pin_low(F1);
  175. gpio_write_pin_low(F4);
  176. break;
  177. case 2:
  178. gpio_write_pin_low(F0);
  179. gpio_write_pin_high(F1);
  180. gpio_write_pin_low(F4);
  181. break;
  182. case 3:
  183. gpio_write_pin_high(F0);
  184. gpio_write_pin_high(F1);
  185. gpio_write_pin_low(F4);
  186. break;
  187. case 4:
  188. gpio_write_pin_low(F0);
  189. gpio_write_pin_low(F1);
  190. gpio_write_pin_high(F4);
  191. break;
  192. case 5:
  193. gpio_write_pin_high(F0);
  194. gpio_write_pin_low(F1);
  195. gpio_write_pin_high(F4);
  196. break;
  197. case 6:
  198. gpio_write_pin_low(F0);
  199. gpio_write_pin_high(F1);
  200. gpio_write_pin_high(F4);
  201. break;
  202. case 7:
  203. gpio_write_pin_low(D2);
  204. gpio_write_pin_low(D3);
  205. gpio_write_pin_low(D5);
  206. break;
  207. case 8:
  208. gpio_write_pin_high(D2);
  209. gpio_write_pin_low(D3);
  210. gpio_write_pin_low(D5);
  211. break;
  212. case 9:
  213. gpio_write_pin_low(D2);
  214. gpio_write_pin_high(D3);
  215. gpio_write_pin_low(D5);
  216. break;
  217. case 10:
  218. gpio_write_pin_high(D2);
  219. gpio_write_pin_high(D3);
  220. gpio_write_pin_low(D5);
  221. break;
  222. case 11:
  223. gpio_write_pin_low(D2);
  224. gpio_write_pin_low(D3);
  225. gpio_write_pin_high(D5);
  226. break;
  227. case 12:
  228. gpio_write_pin_high(D2);
  229. gpio_write_pin_low(D3);
  230. gpio_write_pin_high(D5);
  231. break;
  232. case 13:
  233. gpio_write_pin_low(D2);
  234. gpio_write_pin_high(D3);
  235. gpio_write_pin_high(D5);
  236. break;
  237. }
  238. }