matrix.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. Copyright 2018 Jack Humbert <jack.humb@gmail.com>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <avr/io.h>
  15. #include <util/delay.h>
  16. #include <string.h>
  17. #include "matrix.h"
  18. #ifndef DEBOUNCE
  19. # define DEBOUNCE 5
  20. #endif
  21. __attribute__ ((weak))
  22. void matrix_init_kb(void) {
  23. matrix_init_user();
  24. }
  25. __attribute__ ((weak))
  26. void matrix_scan_kb(void) {
  27. matrix_scan_user();
  28. }
  29. __attribute__ ((weak))
  30. void matrix_init_user(void) { }
  31. __attribute__ ((weak))
  32. void matrix_scan_user(void) { }
  33. // #define MATRIX_ROW_PINS { B3, B4, B5, B6, B7 }
  34. // #define MATRIX_COL_PINS { A0, A1, A2, A3, A4, A5, A6, A7, C7, C6, C5, C4, C3, C2, D7 }
  35. static uint8_t debouncing = DEBOUNCE;
  36. static matrix_row_t matrix[MATRIX_ROWS];
  37. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  38. void matrix_init(void) {
  39. // disables JTAG so we can use them as columns
  40. MCUCSR = (1<<JTD);
  41. MCUCSR = (1<<JTD);
  42. // rows (output)
  43. DDRB |= ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
  44. PORTB |= ((1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
  45. // cols (input)
  46. DDRA &= ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
  47. DDRC &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2));
  48. DDRD &= ~((1 << 7));
  49. // pull-up cols
  50. PORTA |= ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7));
  51. PORTC |= ((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2));
  52. PORTD |= ((1 << 7));
  53. // initialize matrix state: all keys off
  54. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  55. matrix[row] = 0x00;
  56. matrix_debouncing[row] = 0x00;
  57. }
  58. matrix_init_quantum();
  59. }
  60. uint8_t matrix_scan(void) {
  61. // actual matrix scan
  62. for (uint8_t c = 0; c < MATRIX_ROWS; c++) {
  63. switch (c) {
  64. case 0: PORTB &= ~(1 << 3); break;
  65. case 1: PORTB &= ~(1 << 4); break;
  66. case 2: PORTB &= ~(1 << 5); break;
  67. case 3: PORTB &= ~(1 << 6); break;
  68. case 4: PORTB &= ~(1 << 7); break;
  69. }
  70. _delay_us(5);
  71. matrix_row_t current_row = (
  72. (((PINA & (1 << 0)) ? 0 : 1 ) << 0) |
  73. (((PINA & (1 << 1)) ? 0 : 1 ) << 1) |
  74. (((PINA & (1 << 2)) ? 0 : 1 ) << 2) |
  75. (((PINA & (1 << 3)) ? 0 : 1 ) << 3) |
  76. (((PINA & (1 << 4)) ? 0 : 1 ) << 4) |
  77. (((PINA & (1 << 5)) ? 0 : 1 ) << 5) |
  78. (((PINA & (1 << 6)) ? 0 : 1 ) << 6) |
  79. (((PINA & (1 << 7)) ? 0 : 1 ) << 7) |
  80. (((PINC & (1 << 7)) ? 0 : 1 ) << 8) |
  81. (((PINC & (1 << 6)) ? 0 : 1 ) << 9) |
  82. (((PINC & (1 << 5)) ? 0 : 1 ) << 10) |
  83. (((PINC & (1 << 4)) ? 0 : 1 ) << 11) |
  84. (((PINC & (1 << 3)) ? 0 : 1 ) << 12) |
  85. (((PINC & (1 << 2)) ? 0 : 1 ) << 13) |
  86. (((PIND & (1 << 7)) ? 0 : 1 ) << 14)
  87. );
  88. switch (c) {
  89. case 0: PORTB |= (1 << 3); break;
  90. case 1: PORTB |= (1 << 4); break;
  91. case 2: PORTB |= (1 << 5); break;
  92. case 3: PORTB |= (1 << 6); break;
  93. case 4: PORTB |= (1 << 7); break;
  94. }
  95. if (matrix_debouncing[c] != current_row) {
  96. matrix_debouncing[c] = current_row;
  97. debouncing = DEBOUNCE;
  98. }
  99. }
  100. if (debouncing) {
  101. if (--debouncing) {
  102. _delay_ms(1);
  103. } else {
  104. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  105. matrix[i] = matrix_debouncing[i];
  106. }
  107. }
  108. }
  109. matrix_scan_quantum();
  110. return 1;
  111. }
  112. inline matrix_row_t matrix_get_row(uint8_t row) {
  113. return matrix[row];
  114. }
  115. void matrix_print(void) {
  116. }