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.

201 lines
4.0 KiB

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