upload
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. #include <avr/io.h>
  18. #include "wait.h"
  19. #include "print.h"
  20. #include "debug.h"
  21. #include "util.h"
  22. #include "matrix.h"
  23. #ifdef MATRIX_HAS_GHOST
  24. # error "The universal matrix.c file cannot be used for this keyboard."
  25. #endif
  26. #ifndef DEBOUNCING_DELAY
  27. # define DEBOUNCING_DELAY 5
  28. #endif
  29. static const io_pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
  30. static const io_pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
  31. /* matrix state */
  32. #if DIODE_DIRECTION == COL2ROW
  33. static matrix_row_t matrix[MATRIX_ROWS];
  34. #else
  35. static matrix_col_t matrix[MATRIX_COLS];
  36. #endif
  37. static int8_t debouncing_delay = -1;
  38. #if DIODE_DIRECTION == COL2ROW
  39. static void toggle_row(uint8_t row);
  40. static matrix_row_t read_cols(void);
  41. #else
  42. static void toggle_col(uint8_t col);
  43. static matrix_col_t read_rows(void);
  44. #endif
  45. __attribute__ ((weak))
  46. void matrix_init_quantum(void) {
  47. }
  48. __attribute__ ((weak))
  49. void matrix_scan_quantum(void) {
  50. }
  51. uint8_t matrix_rows(void) {
  52. return MATRIX_ROWS;
  53. }
  54. uint8_t matrix_cols(void) {
  55. return MATRIX_COLS;
  56. }
  57. void matrix_init(void) {
  58. /* frees PORTF by setting the JTD bit twice within four cycles */
  59. #ifdef __AVR_ATmega32U4__
  60. MCUCR |= _BV(JTD);
  61. MCUCR |= _BV(JTD);
  62. #endif
  63. /* initializes the I/O pins */
  64. #if DIODE_DIRECTION == COL2ROW
  65. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  66. /* DDRxn */
  67. _SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit);
  68. toggle_row(r);
  69. }
  70. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  71. /* PORTxn */
  72. _SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit);
  73. }
  74. #else
  75. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  76. /* DDRxn */
  77. _SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit);
  78. toggle_col(c);
  79. }
  80. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  81. /* PORTxn */
  82. _SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit);
  83. }
  84. #endif
  85. matrix_init_quantum();
  86. }
  87. #if DIODE_DIRECTION == COL2ROW
  88. uint8_t matrix_scan(void) {
  89. static matrix_row_t debouncing_matrix[MATRIX_ROWS];
  90. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  91. toggle_row(r);
  92. matrix_row_t state = read_cols();
  93. if (debouncing_matrix[r] != state) {
  94. debouncing_matrix[r] = state;
  95. debouncing_delay = DEBOUNCING_DELAY;
  96. }
  97. toggle_row(r);
  98. }
  99. if (debouncing_delay >= 0) {
  100. dprintf("Debouncing delay remaining: %X\n", debouncing_delay);
  101. --debouncing_delay;
  102. if (debouncing_delay >= 0) {
  103. wait_ms(1);
  104. }
  105. else {
  106. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  107. matrix[r] = debouncing_matrix[r];
  108. }
  109. }
  110. }
  111. matrix_scan_quantum();
  112. return 1;
  113. }
  114. static void toggle_row(uint8_t row) {
  115. /* PINxn */
  116. _SFR_IO8(row_pins[row].input_addr) = _BV(row_pins[row].bit);
  117. }
  118. static matrix_row_t read_cols(void) {
  119. matrix_row_t state = 0;
  120. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  121. /* PINxn */
  122. if (!(_SFR_IO8(col_pins[c].input_addr) & _BV(col_pins[c].bit))) {
  123. state |= (matrix_row_t)1 << c;
  124. }
  125. }
  126. return state;
  127. }
  128. matrix_row_t matrix_get_row(uint8_t row) {
  129. return matrix[row];
  130. }
  131. #else
  132. uint8_t matrix_scan(void) {
  133. static matrix_col_t debouncing_matrix[MATRIX_COLS];
  134. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  135. toggle_col(c);
  136. matrix_col_t state = read_rows();
  137. if (debouncing_matrix[c] != state) {
  138. debouncing_matrix[c] = state;
  139. debouncing_delay = DEBOUNCING_DELAY;
  140. }
  141. toggle_col(c);
  142. }
  143. if (debouncing_delay >= 0) {
  144. dprintf("Debouncing delay remaining: %X\n", debouncing_delay);
  145. --debouncing_delay;
  146. if (debouncing_delay >= 0) {
  147. wait_ms(1);
  148. }
  149. else {
  150. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  151. matrix[c] = debouncing_matrix[c];
  152. }
  153. }
  154. }
  155. matrix_scan_quantum();
  156. return 1;
  157. }
  158. static void toggle_col(uint8_t col) {
  159. /* PINxn */
  160. _SFR_IO8(col_pins[col].input_addr) = _BV(col_pins[col].bit);
  161. }
  162. static matrix_col_t read_rows(void) {
  163. matrix_col_t state = 0;
  164. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  165. /* PINxn */
  166. if (!(_SFR_IO8(row_pins[r].input_addr) & _BV(row_pins[r].bit))) {
  167. state |= (matrix_col_t)1 << r;
  168. }
  169. }
  170. return state;
  171. }
  172. matrix_row_t matrix_get_row(uint8_t row) {
  173. matrix_row_t state = 0;
  174. matrix_col_t mask = (matrix_col_t)1 << row;
  175. for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
  176. if (matrix[c] & mask) {
  177. state |= (matrix_row_t)1 << c;
  178. }
  179. }
  180. return state;
  181. }
  182. #endif
  183. bool matrix_is_modified(void) {
  184. if (debouncing_delay >= 0) return false;
  185. return true;
  186. }
  187. bool matrix_is_on(uint8_t row, uint8_t col) {
  188. return matrix_get_row(row) & (matrix_row_t)1 << col;
  189. }
  190. void matrix_print(void) {
  191. dprintln("Human-readable matrix state:");
  192. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  193. dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r)));
  194. }
  195. }
  196. uint8_t matrix_key_count(void) {
  197. uint8_t count = 0;
  198. for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
  199. count += bitpop16(matrix_get_row(r));
  200. }
  201. return count;
  202. }