Prokas

Matrix

Mar 3rd, 2019
31
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Copyright 2019, Aleksadar Prokic <spinoses@gmail.com>
  3.  
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17.  
  18. /*
  19. * scan matrix
  20. */
  21. #include <stdint.h>
  22. #include <stdbool.h>
  23. #include <avr/io.h>
  24. #include <util/delay.h>
  25. #include "print.h"
  26. #include "debug.h"
  27. #include "util.h"
  28. #include "matrix.h"
  29.  
  30.  
  31. #ifndef DEBOUNCE
  32. # define DEBOUNCE 5
  33. #endif
  34. static uint8_t debouncing = DEBOUNCE;
  35.  
  36. /* matrix state(1:on, 0:off) */
  37. static matrix_row_t matrix[MATRIX_ROWS];
  38. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  39.  
  40. static matrix_row_t read_cols(void);
  41. static void init_cols(void);
  42. static void unselect_rows(void);
  43. static void select_row(uint8_t row);
  44.  
  45.  
  46. void matrix_init(void)
  47. {
  48. // initialize row and col
  49. unselect_rows();
  50. init_cols();
  51.  
  52. // initialize matrix state: all keys off
  53. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  54. matrix[i] = 0;
  55. matrix_debouncing[i] = 0;
  56. }
  57. }
  58.  
  59. uint8_t matrix_scan(void)
  60. {
  61. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  62. select_row(i);
  63. _delay_us(30); // without this wait read unstable value.
  64. matrix_row_t cols = read_cols();
  65. if (matrix_debouncing[i] != cols) {
  66. matrix_debouncing[i] = cols;
  67. if (debouncing) {
  68. debug("bounce!: "); debug_hex(debouncing); debug("\n");
  69. }
  70. debouncing = DEBOUNCE;
  71. }
  72. unselect_rows();
  73. }
  74.  
  75. if (debouncing) {
  76. if (--debouncing) {
  77. _delay_ms(1);
  78. } else {
  79. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  80. matrix[i] = matrix_debouncing[i];
  81. }
  82. }
  83. }
  84.  
  85. return 1;
  86. }
  87.  
  88. inline
  89. matrix_row_t matrix_get_row(uint8_t row)
  90. {
  91. return matrix[row];
  92. }
  93.  
  94. /* Column pin configuration
  95. * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
  96. * pin: F0 F1 E6 C7 C6 B6 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.A)
  97. * pin: B7 (Rev.B)
  98. */
  99. static void init_cols(void)
  100. {
  101. // Input with pull-up(DDR:0, PORT:1)
  102. DDRF &= ~(1<<7);
  103. PORTF |= (1<<7);
  104. DDRB &= ~(1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1);
  105. PORTB |= (1<<7 | 1<<6 | 1<<5 | 1<<4 | 1<<3 | 1<<2 | 1<<1);
  106. DDRD &= ~(1<<7 | 1<<3 | 1<<2 | 1<<1 | 1<<0 );
  107. PORTD |= (1<<7 | 1<<3 | 1<<2 | 1<<1 | 1<<0 );
  108. DDRC &= ~(1<<7 | 1<<6);
  109. PORTC |= (1<<7 | 1<<6);
  110. }
  111.  
  112. static matrix_row_t read_cols(void)
  113. {
  114. return (PINF&(1<<7) ? 0 : (1<<0)) |
  115. (PINB&(1<<6) ? 0 : (1<<1)) |
  116. (PINB&(1<<5) ? 0 : (1<<2)) |
  117. (PINB&(1<<4) ? 0 : (1<<3)) |
  118. (PIND&(1<<7) ? 0 : (1<<4)) |
  119. (PINC&(1<<7) ? 0 : (1<<5)) |
  120. (PINC&(1<<6) ? 0 : (1<<6)) |
  121. (PIND&(1<<3) ? 0 : (1<<7)) |
  122. (PIND&(1<<2) ? 0 : (1<<8)) |
  123. (PIND&(1<<1) ? 0 : (1<<9)) |
  124. (PIND&(1<<0) ? 0 : (1<<10)) |
  125. (PINB&(1<<7) ? 0 : (1<<11)) |
  126. (PINB&(1<<3) ? 0 : (1<<12)) |
  127. (PINB&(1<<2) ? 0 : (1<<13)) |
  128. (PINB&(1<<1) ? 0 : (1<<14));
  129. }
  130.  
  131. /* Row pin configuration
  132. * row: 0 1 2 3 4
  133. * pin: D0 D1 D2 D3 D5
  134. */
  135. static void unselect_rows(void)
  136. {
  137. // Hi-Z(DDR:0, PORT:0) to unselect
  138. DDRF &= ~0b01110011;
  139. PORTF &= ~0b01110011;
  140. }
  141.  
  142. static void select_row(uint8_t row)
  143. {
  144. // Output low(DDR:1, PORT:0) to select
  145. switch (row) {
  146. case 0:
  147. DDRF |= (1<<0);
  148. PORTF &= ~(1<<0);
  149. break;
  150. case 1:
  151. DDRF |= (1<<1);
  152. PORTF &= ~(1<<1);
  153. break;
  154. case 2:
  155. DDRF |= (1<<4);
  156. PORTF &= ~(1<<4);
  157. break;
  158. case 3:
  159. DDRF |= (1<<5);
  160. PORTF &= ~(1<<5);
  161. break;
  162. case 4:
  163. DDRF |= (1<<6);
  164. PORTF &= ~(1<<6);
  165. break;
  166. }
  167. }
RAW Paste Data