]> git.gir.st - tmk_keyboard.git/blob - matrix.c
some fixes. LED flush for debug.
[tmk_keyboard.git] / matrix.c
1 /*
2 * scan matrix
3 */
4 #include <avr/io.h>
5 #include <util/delay.h>
6 #include "keymap.h"
7 #include "matrix.h"
8
9 // matrix is active low. (key on: 0/key off: 1)
10 // row: Hi-Z(unselected)/low output(selected)
11 // PD:0,1,2,3,6,7/PC:6,7/PF:7
12 // col: input w/pullup
13 // PB:0-8
14
15 // matrix state buffer
16 uint8_t *matrix;
17 uint8_t *matrix_prev;
18 static uint8_t _matrix0[MATRIX_ROWS];
19 static uint8_t _matrix1[MATRIX_ROWS];
20
21 static uint8_t read_col(void);
22 static void unselect_rows(void);
23 static void select_row(uint8_t row);
24
25
26 // this must be called once before matrix_scan.
27 void matrix_init(void)
28 {
29 // initialize row and col
30 unselect_rows();
31 DDRB = 0x00;
32 PORTB = 0xFF;
33
34 // initialize matrix state: all keys off
35 for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0xFF;
36 for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0xFF;
37 matrix = _matrix0;
38 matrix_prev = _matrix1;
39 }
40
41 uint8_t matrix_scan(void)
42 {
43 uint8_t row, state;
44 uint8_t *tmp;
45
46 tmp = matrix_prev;
47 matrix_prev = matrix;
48 matrix = tmp;
49
50 for (row = 0; row < MATRIX_ROWS; row++) {
51 select_row(row);
52 _delay_us(30); // without this wait read unstable value.
53 state = read_col();
54 unselect_rows();
55
56 matrix[row] = state;
57 }
58 return 1;
59 }
60
61 bool matrix_is_modified(void) {
62 for (int i=0; i <MATRIX_ROWS; i++) {
63 if (matrix[i] != matrix_prev[i])
64 return true;
65 }
66 return false;
67 }
68
69 bool matrix_has_ghost(void) {
70 for (int i=0; i <MATRIX_ROWS; i++) {
71 if (matrix_has_ghost_in_row(i))
72 return true;
73 }
74 return false;
75 }
76
77 bool matrix_has_ghost_in_row(uint8_t row) {
78 uint8_t state = ~matrix[row];
79 // no ghost exists in case less than 2 keys on
80 if (((state - 1) & state) == 0)
81 return false;
82
83 // ghost exists in case same state as other row
84 for (int i=0; i < MATRIX_ROWS; i++) {
85 if (i == row) continue;
86 if ((~matrix[i] & state) == state) return true;
87 }
88 return false;
89 }
90
91 static uint8_t read_col(void)
92 {
93 return PINB;
94 }
95
96 static void unselect_rows(void) {
97 DDRD = 0x00;
98 PORTD = 0x00;
99 DDRC = 0x00;
100 PORTC = 0x00;
101 DDRF = 0x00;
102 PORTF = 0x00;
103 }
104
105 static void select_row(uint8_t row)
106 {
107 switch (row) {
108 case 0:
109 DDRD = (1<<0);
110 PORTD = 0x00;
111 DDRC = 0x00;
112 PORTC = 0x00;
113 DDRF = 0x00;
114 PORTF = 0x00;
115 break;
116 case 1:
117 DDRD = (1<<1);
118 PORTD = 0x00;
119 DDRC = 0x00;
120 PORTC = 0x00;
121 DDRF = 0x00;
122 PORTF = 0x00;
123 break;
124 case 2:
125 DDRD = (1<<2);
126 PORTD = 0x00;
127 DDRC = 0x00;
128 PORTC = 0x00;
129 DDRF = 0x00;
130 PORTF = 0x00;
131 break;
132 case 3:
133 DDRD = (1<<3);
134 PORTD = 0x00;
135 DDRC = 0x00;
136 PORTC = 0x00;
137 DDRF = 0x00;
138 PORTF = 0x00;
139 break;
140 case 4:
141 DDRD = (1<<6);
142 PORTD = 0x00;
143 DDRC = 0x00;
144 PORTC = 0x00;
145 DDRF = 0x00;
146 PORTF = 0x00;
147 break;
148 case 5:
149 DDRD = (1<<7);
150 PORTD = 0x00;
151 DDRC = 0x00;
152 PORTC = 0x00;
153 DDRF = 0x00;
154 PORTF = 0x00;
155 break;
156 case 6:
157 DDRD = 0x00;
158 PORTD = 0x00;
159 DDRC = (1<<6);
160 PORTC = 0x00;
161 DDRF = 0x00;
162 PORTF = 0x00;
163 break;
164 case 7:
165 DDRD = 0x00;
166 PORTD = 0x00;
167 DDRC = (1<<7);
168 PORTC = 0x00;
169 DDRF = 0x00;
170 PORTF = 0x00;
171 break;
172 case 8:
173 DDRD = 0x00;
174 PORTD = 0x00;
175 DDRC = 0x00;
176 PORTC = 0x00;
177 DDRF = (1<<7);
178 PORTF = 0x00;
179 break;
180 }
181 }
Imprint / Impressum