You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
5.6 KiB

  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 "quantum.h"
  17. static uint8_t debouncing = DEBOUNCE;
  18. static matrix_row_t matrix[MATRIX_ROWS];
  19. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  20. static uint8_t read_rows(void);
  21. static void init_rows(void);
  22. static void init_cols(void);
  23. static void unselect_cols(void);
  24. static void select_col(uint8_t col);
  25. __attribute__ ((weak))
  26. void matrix_init_kb(void)
  27. {
  28. matrix_init_user();
  29. }
  30. __attribute__ ((weak))
  31. void matrix_scan_kb(void)
  32. {
  33. matrix_scan_user();
  34. }
  35. __attribute__ ((weak))
  36. void matrix_init_user(void) {}
  37. __attribute__ ((weak))
  38. void matrix_scan_user(void) {}
  39. void matrix_init(void)
  40. {
  41. //setPinOutput(F0);
  42. //writePinHigh(F0);
  43. setPinOutput(B4);
  44. writePinLow(B4);
  45. init_cols();
  46. init_rows();
  47. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  48. matrix[i] = 0;
  49. matrix_debouncing[i] = 0;
  50. }
  51. matrix_init_quantum();
  52. }
  53. uint8_t matrix_scan(void)
  54. {
  55. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  56. select_col(col);
  57. _delay_us(3);
  58. uint8_t rows = read_rows();
  59. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  60. bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
  61. bool curr_bit = rows & (1<<row);
  62. if (prev_bit != curr_bit) {
  63. matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
  64. debouncing = DEBOUNCE;
  65. }
  66. }
  67. unselect_cols();
  68. }
  69. if (debouncing) {
  70. if (--debouncing) {
  71. _delay_ms(1);
  72. } else {
  73. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  74. matrix[i] = matrix_debouncing[i];
  75. }
  76. }
  77. }
  78. matrix_scan_quantum();
  79. return 1;
  80. }
  81. inline matrix_row_t matrix_get_row(uint8_t row)
  82. {
  83. return matrix[row];
  84. }
  85. void matrix_print(void)
  86. {
  87. print("\nr/c 0123456789ABCDEF\n");
  88. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  89. xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
  90. }
  91. }
  92. /*
  93. * Row pin configuration
  94. * row: 0 1 2 3 4
  95. * pin: PE6 PF6 PF7 PB7 PD4
  96. */
  97. static void init_rows(void)
  98. {
  99. setPinInputHigh(E6);
  100. setPinInputHigh(F6);
  101. setPinInputHigh(F7);
  102. setPinInputHigh(B7);
  103. setPinInputHigh(D4);
  104. }
  105. static uint8_t read_rows()
  106. {
  107. return ((readPin(E6) ? 0 : (1 << 0)) |
  108. (readPin(F6) ? 0 : (1 << 1)) |
  109. (readPin(F7) ? 0 : (1 << 2)) |
  110. (readPin(B7) ? 0 : (1 << 3)) |
  111. (readPin(D4) ? 0 : (1 << 4)));
  112. }
  113. /*
  114. * Columns 0 - 13
  115. * These columns uses two 74LVC138 3 to 8 bit demultiplexers.
  116. * EN Pin, PF5, PD6
  117. *
  118. * col / pin: PF0 PF1 PF4
  119. * 0: 0 0 0
  120. * 1: 1 0 0
  121. * 2: 0 1 0
  122. * 3: 1 1 0
  123. * 4: 0 0 1
  124. * 5: 1 0 1
  125. * 6: 0 1 1
  126. * PD2 PD3 PD5
  127. * 7: 0 0 0
  128. * 8: 1 0 0
  129. * 9: 0 1 0
  130. * 10: 1 1 0
  131. * 11: 0 0 1
  132. * 12: 1 0 1
  133. * 13: 0 1 1
  134. *
  135. */
  136. static void init_cols(void)
  137. {
  138. setPinOutput(F0);
  139. setPinOutput(F1);
  140. setPinOutput(F4);
  141. setPinOutput(F5);
  142. setPinOutput(D2);
  143. setPinOutput(D3);
  144. setPinOutput(D5);
  145. setPinOutput(D6);
  146. unselect_cols();
  147. }
  148. static void unselect_cols(void)
  149. {
  150. writePinHigh(F0);
  151. writePinHigh(F1);
  152. writePinHigh(F4);
  153. writePinHigh(F5);
  154. writePinHigh(D2);
  155. writePinHigh(D3);
  156. writePinHigh(D5);
  157. writePinHigh(D6);
  158. }
  159. static void select_col(uint8_t col) {
  160. switch (col) {
  161. case 0:
  162. writePinLow(F0);
  163. writePinLow(F1);
  164. writePinLow(F4);
  165. break;
  166. case 1:
  167. writePinHigh(F0);
  168. writePinLow(F1);
  169. writePinLow(F4);
  170. break;
  171. case 2:
  172. writePinLow(F0);
  173. writePinHigh(F1);
  174. writePinLow(F4);
  175. break;
  176. case 3:
  177. writePinHigh(F0);
  178. writePinHigh(F1);
  179. writePinLow(F4);
  180. break;
  181. case 4:
  182. writePinLow(F0);
  183. writePinLow(F1);
  184. writePinHigh(F4);
  185. break;
  186. case 5:
  187. writePinHigh(F0);
  188. writePinLow(F1);
  189. writePinHigh(F4);
  190. break;
  191. case 6:
  192. writePinLow(F0);
  193. writePinHigh(F1);
  194. writePinHigh(F4);
  195. break;
  196. case 7:
  197. writePinLow(D2);
  198. writePinLow(D3);
  199. writePinLow(D5);
  200. break;
  201. case 8:
  202. writePinHigh(D2);
  203. writePinLow(D3);
  204. writePinLow(D5);
  205. break;
  206. case 9:
  207. writePinLow(D2);
  208. writePinHigh(D3);
  209. writePinLow(D5);
  210. break;
  211. case 10:
  212. writePinHigh(D2);
  213. writePinHigh(D3);
  214. writePinLow(D5);
  215. break;
  216. case 11:
  217. writePinLow(D2);
  218. writePinLow(D3);
  219. writePinHigh(D5);
  220. break;
  221. case 12:
  222. writePinHigh(D2);
  223. writePinLow(D3);
  224. writePinHigh(D5);
  225. break;
  226. case 13:
  227. writePinLow(D2);
  228. writePinHigh(D3);
  229. writePinHigh(D5);
  230. break;
  231. }
  232. }