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