matrix.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. Copyright 2012 Jun Wako
  3. Copyright 2014 Jack Humbert
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 2 of the License, or
  7. (at your option) any later version.
  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. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include <stdint.h>
  16. #include <stdbool.h>
  17. #if defined(__AVR__)
  18. #include <avr/io.h>
  19. #endif
  20. #include "wait.h"
  21. #include "print.h"
  22. #include "debug.h"
  23. #include "util.h"
  24. #include "matrix.h"
  25. #ifdef MATRIX_HAS_GHOST
  26. # error "The universal matrix.c file cannot be used for this keyboard."
  27. #endif
  28. #ifndef DEBOUNCING_DELAY
  29. # define DEBOUNCING_DELAY 5
  30. #endif
  31. static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  32. static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
  33. /* matrix state */
  34. #if DIODE_DIRECTION == COL2ROW
  35. static matrix_row_t matrix[MATRIX_ROWS];
  36. #else
  37. static matrix_col_t matrix[MATRIX_COLS];
  38. #endif
  39. static int8_t debouncing_delay = -1;
  40. #if DIODE_DIRECTION == COL2ROW
  41. static void toggle_row(uint8_t row);
  42. static matrix_row_t read_cols(void);
  43. #else
  44. static void toggle_col(uint8_t col);
  45. static matrix_col_t read_rows(void);
  46. #endif
  47. __attribute__ ((weak))
  48. void matrix_init_quantum(void) {
  49. matrix_init_kb();
  50. }
  51. __attribute__ ((weak))
  52. void matrix_scan_quantum(void) {
  53. matrix_scan_kb();
  54. }
  55. __attribute__ ((weak))
  56. void matrix_init_kb(void) {
  57. matrix_init_user();
  58. }
  59. __attribute__ ((weak))
  60. void matrix_scan_kb(void) {
  61. matrix_scan_user();
  62. }
  63. __attribute__ ((weak))
  64. void matrix_init_user(void) {
  65. }
  66. __attribute__ ((weak))
  67. void matrix_scan_user(void) {
  68. }
  69. uint8_t matrix_rows(void) {
  70. return MATRIX_ROWS;
  71. }
  72. uint8_t matrix_cols(void) {
  73. return MATRIX_COLS;
  74. }
  75. // void matrix_power_up(void) {
  76. // #if DIODE_DIRECTION == COL2ROW
  77. // for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  78. // /* DDRxn */
  79. // _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
  80. // toggle_row(r);
  81. // }
  82. // for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  83. // /* PORTxn */
  84. // _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF);
  85. // }
  86. // #else
  87. // for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  88. // /* DDRxn */
  89. // _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF);
  90. // toggle_col(c);
  91. // }
  92. // for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  93. // /* PORTxn */
  94. // _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF);
  95. // }
  96. // #endif
  97. // }
  98. void matrix_init(void) {
  99. /* frees PORTF by setting the JTD bit twice within four cycles */
  100. #ifdef __AVR_ATmega32U4__
  101. MCUCR |= _BV(JTD);
  102. MCUCR |= _BV(JTD);
  103. #endif
  104. /* initializes the I/O pins */
  105. #if DIODE_DIRECTION == COL2ROW
  106. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  107. /* DDRxn */
  108. _SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
  109. toggle_row(r);
  110. }
  111. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  112. /* PORTxn */
  113. _SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF);
  114. }
  115. #else
  116. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  117. /* DDRxn */
  118. _SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF);
  119. toggle_col(c);
  120. }
  121. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  122. /* PORTxn */
  123. _SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF);
  124. }
  125. #endif
  126. matrix_init_quantum();
  127. }
  128. #if DIODE_DIRECTION == COL2ROW
  129. uint8_t matrix_scan(void) {
  130. static matrix_row_t debouncing_matrix[MATRIX_ROWS];
  131. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  132. toggle_row(r);
  133. matrix_row_t state = read_cols();
  134. if (debouncing_matrix[r] != state) {
  135. debouncing_matrix[r] = state;
  136. debouncing_delay = DEBOUNCING_DELAY;
  137. }
  138. toggle_row(r);
  139. }
  140. if (debouncing_delay >= 0) {
  141. dprintf("Debouncing delay remaining: %X\n", debouncing_delay);
  142. --debouncing_delay;
  143. if (debouncing_delay >= 0) {
  144. wait_ms(1);
  145. }
  146. else {
  147. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  148. matrix[r] = debouncing_matrix[r];
  149. }
  150. }
  151. }
  152. matrix_scan_quantum();
  153. return 1;
  154. }
  155. static void toggle_row(uint8_t row) {
  156. /* PINxn */
  157. _SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF);
  158. }
  159. static matrix_row_t read_cols(void) {
  160. matrix_row_t state = 0;
  161. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  162. /* PINxn */
  163. if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) {
  164. state |= (matrix_row_t)1 << c;
  165. }
  166. }
  167. return state;
  168. }
  169. matrix_row_t matrix_get_row(uint8_t row) {
  170. return matrix[row];
  171. }
  172. #else
  173. uint8_t matrix_scan(void) {
  174. static matrix_col_t debouncing_matrix[MATRIX_COLS];
  175. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  176. toggle_col(c);
  177. matrix_col_t state = read_rows();
  178. if (debouncing_matrix[c] != state) {
  179. debouncing_matrix[c] = state;
  180. debouncing_delay = DEBOUNCING_DELAY;
  181. }
  182. toggle_col(c);
  183. }
  184. if (debouncing_delay >= 0) {
  185. dprintf("Debouncing delay remaining: %X\n", debouncing_delay);
  186. --debouncing_delay;
  187. if (debouncing_delay >= 0) {
  188. wait_ms(1);
  189. }
  190. else {
  191. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  192. matrix[c] = debouncing_matrix[c];
  193. }
  194. }
  195. }
  196. matrix_scan_quantum();
  197. return 1;
  198. }
  199. static void toggle_col(uint8_t col) {
  200. /* PINxn */
  201. _SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF);
  202. }
  203. static matrix_col_t read_rows(void) {
  204. matrix_col_t state = 0;
  205. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  206. /* PINxn */
  207. if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) {
  208. state |= (matrix_col_t)1 << r;
  209. }
  210. }
  211. return state;
  212. }
  213. matrix_row_t matrix_get_row(uint8_t row) {
  214. matrix_row_t state = 0;
  215. matrix_col_t mask = (matrix_col_t)1 << row;
  216. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  217. if (matrix[c] & mask) {
  218. state |= (matrix_row_t)1 << c;
  219. }
  220. }
  221. return state;
  222. }
  223. #endif
  224. bool matrix_is_modified(void) {
  225. if (debouncing_delay >= 0) return false;
  226. return true;
  227. }
  228. bool matrix_is_on(uint8_t row, uint8_t col) {
  229. return matrix_get_row(row) & (matrix_row_t)1 << col;
  230. }
  231. void matrix_print(void) {
  232. dprintln("Human-readable matrix state:");
  233. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  234. dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r)));
  235. }
  236. }
  237. uint8_t matrix_key_count(void) {
  238. uint8_t count = 0;
  239. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  240. count += bitpop16(matrix_get_row(r));
  241. }
  242. return count;
  243. }