matrix.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include <stdint.h>
  2. #include <stdbool.h>
  3. #include <avr/io.h>
  4. #include <util/delay.h>
  5. #include "print.h"
  6. #include "debug.h"
  7. #include "util.h"
  8. #include "matrix.h"
  9. #ifndef DEBOUNCING_DELAY
  10. # define DEBOUNCING_DELAY 5
  11. #endif
  12. static uint8_t debouncing = DEBOUNCING_DELAY;
  13. static matrix_row_t matrix[MATRIX_ROWS];
  14. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  15. static uint8_t read_rows(void);
  16. static void init_rows(void);
  17. static void unselect_cols(void);
  18. static void select_col(uint8_t col);
  19. inline uint8_t matrix_rows(void) {
  20. return MATRIX_ROWS;
  21. }
  22. inline uint8_t matrix_cols(void) {
  23. return MATRIX_COLS;
  24. }
  25. void matrix_init(void) {
  26. // initialize row and col
  27. unselect_cols();
  28. init_rows();
  29. // initialize matrix state: all keys off
  30. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  31. matrix[i] = 0;
  32. matrix_debouncing[i] = 0;
  33. }
  34. matrix_init_quantum();
  35. }
  36. uint8_t matrix_scan(void) {
  37. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  38. select_col(col);
  39. _delay_us(3);
  40. uint8_t rows = read_rows();
  41. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  42. bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
  43. bool curr_bit = rows & (1<<row);
  44. if (prev_bit != curr_bit) {
  45. matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
  46. debouncing = DEBOUNCING_DELAY;
  47. }
  48. }
  49. unselect_cols();
  50. }
  51. if (debouncing) {
  52. if (--debouncing) {
  53. _delay_ms(1);
  54. } else {
  55. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  56. matrix[i] = matrix_debouncing[i];
  57. }
  58. }
  59. }
  60. matrix_scan_quantum();
  61. return 1;
  62. }
  63. bool matrix_is_modified(void) {
  64. if (debouncing)
  65. return false;
  66. else
  67. return true;
  68. }
  69. inline bool matrix_is_on(uint8_t row, uint8_t col) {
  70. return (matrix[row] & ((matrix_row_t)1<<col));
  71. }
  72. inline matrix_row_t matrix_get_row(uint8_t row) {
  73. return matrix[row];
  74. }
  75. void matrix_print(void) {
  76. print("\nr/c 0123456789ABCDEF\n");
  77. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  78. xprintf("%02X: %032lb\n", row, bitrev32(matrix_get_row(row)));
  79. }
  80. }
  81. uint8_t matrix_key_count(void) {
  82. uint8_t count = 0;
  83. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  84. count += bitpop32(matrix[i]);
  85. }
  86. return count;
  87. }
  88. /* Row pin configuration
  89. *
  90. * row: 0 1 2 3 4 5
  91. * pin: C7 B1 B2 C6 B4 B5
  92. *
  93. */
  94. static void init_rows(void)
  95. {
  96. DDRC &= ~0b11000000;
  97. DDRB &= ~0b00110110;
  98. PORTC |= 0b11000000;
  99. PORTB |= 0b00110110;
  100. }
  101. static uint8_t read_rows(void) {
  102. return (PINC&(1<<PC7) ? 0 : (1<<0)) |
  103. (PINB&(1<<PB1) ? 0 : (1<<1)) |
  104. (PINB&(1<<PB2) ? 0 : (1<<2)) |
  105. (PINC&(1<<PC6) ? 0 : (1<<3)) |
  106. (PINB&(1<<PB4) ? 0 : (1<<4)) |
  107. (PINB&(1<<PB5) ? 0 : (1<<5));
  108. }
  109. /* Row pin configuration
  110. * pin: D3 D7 D6 D5 D4
  111. * row: off 0 x x x x
  112. * 0 1 0 0 0 0
  113. * 1 1 0 0 0 1
  114. * 2 1 0 0 1 0
  115. * 3 1 0 0 1 1
  116. * 4 1 0 1 0 0
  117. * 5 1 0 1 0 1
  118. * 6 1 0 1 1 0
  119. * 7 1 0 1 1 1
  120. * 8 1 1 0 0 0
  121. * 9 1 1 0 0 1
  122. * 10 1 1 0 1 0
  123. * 11 1 1 0 1 1
  124. * 12 1 1 1 0 0
  125. * 13 1 1 1 0 1
  126. * 14 1 1 1 1 0
  127. * 15 1 1 1 1 1
  128. */
  129. static void unselect_cols(void)
  130. {
  131. // output high(DDR:1, PORT:1) to unselect
  132. DDRB |= (1 << PD3);
  133. PORTB |= (1 << PD3);
  134. }
  135. static void select_col(uint8_t col) {
  136. DDRD |= (1<<PD3 | 1<<PD4 | 1<<PD5 | 1<<PD6 | 1<<PD7);
  137. PORTD &= ~(1<<PD3);
  138. if (col & (1<<0)) {
  139. PORTD |= (1<<PD4);
  140. }
  141. else {
  142. PORTD &= ~(1<<PD4);
  143. }
  144. if (col & (1<<1)) {
  145. PORTD |= (1<<PD5);
  146. }
  147. else {
  148. PORTD &= ~(1<<PD5);
  149. }
  150. if (col & (1<<2)) {
  151. PORTD |= (1<<PD6);
  152. }
  153. else {
  154. PORTD &= ~(1<<PD6);
  155. }
  156. if (col & (1<<3)) {
  157. PORTD |= (1<<PD7);
  158. }
  159. else {
  160. PORTD &= ~(1<<PD7);
  161. }
  162. }