Keyboard firmwares for Atmel AVR and Cortex-M
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.

matrix.c 4.7KB

13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
13 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * scan matrix
  3. */
  4. #include <stdint.h>
  5. #include <stdbool.h>
  6. #include <avr/io.h>
  7. #include <util/delay.h>
  8. #include "matrix.h"
  9. #include "print.h"
  10. #include "util.h"
  11. // matrix is active low. (key on: 0/key off: 1)
  12. // row: Hi-Z(unselected)/low output(selected)
  13. // PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7
  14. // col: input w/pullup
  15. // PB0-PB7
  16. // matrix state buffer
  17. uint8_t *matrix;
  18. uint8_t *matrix_prev;
  19. static uint8_t _matrix0[MATRIX_ROWS];
  20. static uint8_t _matrix1[MATRIX_ROWS];
  21. static bool matrix_has_ghost_in_row(uint8_t row);
  22. static uint8_t read_col(void);
  23. static void unselect_rows(void);
  24. static void select_row(uint8_t row);
  25. inline
  26. int matrix_rows(void)
  27. {
  28. return MATRIX_ROWS;
  29. }
  30. inline
  31. int matrix_cols(void)
  32. {
  33. return MATRIX_COLS;
  34. }
  35. // this must be called once before matrix_scan.
  36. void matrix_init(void)
  37. {
  38. // initialize row and col
  39. unselect_rows();
  40. DDRB = 0x00;
  41. PORTB = 0xFF;
  42. // initialize matrix state: all keys off
  43. for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
  44. for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
  45. matrix = _matrix0;
  46. matrix_prev = _matrix1;
  47. }
  48. int matrix_scan(void)
  49. {
  50. uint8_t *tmp;
  51. tmp = matrix_prev;
  52. matrix_prev = matrix;
  53. matrix = tmp;
  54. for (int i = 0; i < MATRIX_ROWS; i++) {
  55. select_row(i);
  56. _delay_us(30); // without this wait read unstable value.
  57. matrix[i] = ~read_col();
  58. unselect_rows();
  59. }
  60. return 1;
  61. }
  62. bool matrix_is_modified(void)
  63. {
  64. for (int i = 0; i < MATRIX_ROWS; i++) {
  65. if (matrix[i] != matrix_prev[i])
  66. return true;
  67. }
  68. return false;
  69. }
  70. bool matrix_has_ghost(void)
  71. {
  72. for (int i = 0; i < MATRIX_ROWS; i++) {
  73. if (matrix_has_ghost_in_row(i))
  74. return true;
  75. }
  76. return false;
  77. }
  78. inline
  79. bool matrix_is_on(int row, int col)
  80. {
  81. return (matrix[row] & (1<<col));
  82. }
  83. inline
  84. uint16_t matrix_get_row(int row)
  85. {
  86. return matrix[row];
  87. }
  88. void matrix_print(void)
  89. {
  90. print("\nr/c 01234567\n");
  91. for (int row = 0; row < matrix_rows(); row++) {
  92. phex(row); print(": ");
  93. pbin_reverse(matrix_get_row(row));
  94. if (matrix_has_ghost_in_row(row)) {
  95. print(" <ghost");
  96. }
  97. print("\n");
  98. }
  99. }
  100. int matrix_key_count(void)
  101. {
  102. int count = 0;
  103. for (int i = 0; i < MATRIX_ROWS; i++) {
  104. count += bitpop(matrix[i]);
  105. }
  106. return count;
  107. }
  108. static bool matrix_has_ghost_in_row(uint8_t row)
  109. {
  110. // no ghost exists in case less than 2 keys on
  111. if (((matrix[row] - 1) & matrix[row]) == 0)
  112. return false;
  113. // ghost exists in case same state as other row
  114. for (int i=0; i < MATRIX_ROWS; i++) {
  115. if (i != row && (matrix[i] & matrix[row]) == matrix[row])
  116. return true;
  117. }
  118. return false;
  119. }
  120. static uint8_t read_col(void)
  121. {
  122. return PINB;
  123. }
  124. static void unselect_rows(void)
  125. {
  126. DDRD = 0x00;
  127. PORTD = 0x00;
  128. DDRC = 0x00;
  129. PORTC = 0x00;
  130. DDRF = 0x00;
  131. PORTF = 0x00;
  132. }
  133. static void select_row(uint8_t row)
  134. {
  135. switch (row) {
  136. case 0:
  137. DDRD = (1<<0);
  138. PORTD = 0x00;
  139. DDRC = 0x00;
  140. PORTC = 0x00;
  141. DDRF = 0x00;
  142. PORTF = 0x00;
  143. break;
  144. case 1:
  145. DDRD = 0x00;
  146. PORTD = 0x00;
  147. DDRC = (1<<7);
  148. PORTC = 0x00;
  149. DDRF = 0x00;
  150. PORTF = 0x00;
  151. break;
  152. case 2:
  153. DDRD = (1<<7);
  154. PORTD = 0x00;
  155. DDRC = 0x00;
  156. PORTC = 0x00;
  157. DDRF = 0x00;
  158. PORTF = 0x00;
  159. break;
  160. case 3:
  161. DDRD = 0x00;
  162. PORTD = 0x00;
  163. DDRC = 0x00;
  164. PORTC = 0x00;
  165. DDRF = (1<<6);
  166. PORTF = 0x00;
  167. break;
  168. case 4:
  169. DDRD = (1<<6);
  170. PORTD = 0x00;
  171. DDRC = 0x00;
  172. PORTC = 0x00;
  173. DDRF = 0x00;
  174. PORTF = 0x00;
  175. break;
  176. case 5:
  177. DDRD = (1<<1);
  178. PORTD = 0x00;
  179. DDRC = 0x00;
  180. PORTC = 0x00;
  181. DDRF = 0x00;
  182. PORTF = 0x00;
  183. break;
  184. case 6:
  185. DDRD = (1<<2);
  186. PORTD = 0x00;
  187. DDRC = 0x00;
  188. PORTC = 0x00;
  189. DDRF = 0x00;
  190. PORTF = 0x00;
  191. break;
  192. case 7:
  193. DDRD = 0x00;
  194. PORTD = 0x00;
  195. DDRC = (1<<6);
  196. PORTC = 0x00;
  197. DDRF = 0x00;
  198. PORTF = 0x00;
  199. break;
  200. case 8:
  201. DDRD = 0x00;
  202. PORTD = 0x00;
  203. DDRC = 0x00;
  204. PORTC = 0x00;
  205. DDRF = (1<<7);
  206. PORTF = 0x00;
  207. break;
  208. }
  209. }